IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

calcul de CRC pour une image png


Sujet :

C

  1. #1
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut calcul de CRC pour une image png
    bonjour,

    j'essaye de modifier des images png en travaillant directement par lecture binaire du fichier image.
    comme je modifie mon image, je dois recalculer des CRC avec les valeurs des pixels de mon image.
    J'ai donc utilisé le calcul CRC donné dans les spec png.
    Lorsque j'ouvre mon image modifiée avec the Gimp, il me dit qu'il y a une erreur de lecture.

    je n'arrive pas à trouver mon erreur..... est-ce-que quelqu'un aurait une idée ???


    voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    struct pixel {
      unsigned int red;
      unsigned int green;
      unsigned int blue;
      unsigned int alpha;
      unsigned char crc[4];
      unsigned int len;
      int flag;
    };
     
    /* pour les listes chainées */
    struct l_pix {
      struct pixel * pix;
      struct l_pix * prev;
      struct l_pix * next;
    };
     
    struct accesPix {
      struct l_pix * first;
      struct l_pix * last;  
    };
    .....
     
    /* Make the table for a fast CRC. */
    void 
    make_crc_table(void) {
      unsigned long c;
      int n, k;
     
      for (n = 0; n < 256; n++) {
        c = (unsigned long) n;
        for (k = 0; k < 8; k++) {
          if (c & 1) {
    	c = 0xedb88320L ^ (c >> 1);
          } else {
    	c = c >> 1;
          }
        }
        crc_table[n] = c;
      }
      crc_table_computed = 1;
    }
     
    /* Update a running CRC with the bytes buf[0..len-1]--the CRC
       should be initialized to all 1's, and the transmitted value
       is the 1's complement of the final running CRC (see the
       mkCrc() routine below)). */
     
    unsigned long 
    update_crc(unsigned long crc, unsigned char *buf,int len) {
      unsigned long c = crc;
      int n;
     
      if (!crc_table_computed) {
        make_crc_table();
      }
      for (n = 0; n < len; n++) {
        c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
      }
      return c;
    }
     
    /* Return the CRC of the bytes buf[0..len-1]. */
    unsigned long 
    mkCrc(unsigned char *buf, int len) {
      return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
    }
     
    /************************************************************************
     * calcCRC : calcul des crc a partir des chunks IDAT modifiés 
     *
     ***********************************************************************/
    int
    calcCRC(struct accesPix *lpix) {
      struct l_pix * tmp;
      unsigned char buf[256];
      unsigned long crc;
      int i, len=0;
     
      tmp = lpix->first;
      /* 1er pixel d'un chunk est avec len!=0, dernier pixel est avec
       * flag=1
       */
      while(tmp != NULL) {
        if(tmp->pix->len != 0) {
          len = tmp->pix->len;
          fprintf(stderr,"pix->len=<%d>\n",tmp->pix->len);
          bzero(buf,256);
        }
        for(i=0; i<(len/4); i++) {
          memcpy(&buf[i],(&(tmp->pix->red)), 1); 
          memcpy(&buf[i],(&(tmp->pix->green)), 1); 
          memcpy(&buf[i],(&(tmp->pix->blue)), 1); 
          memcpy(&buf[i],(&(tmp->pix->alpha)), 1); 
     
          if(tmp->pix->flag == 1) {
    	crc = mkCrc(buf, len);
    	fprintf(stderr,"calcCRC : crc =<%ld> <%8x>\n",crc, crc);
    	memcpy(&(tmp->pix->crc),&crc,4);
          }
     
          tmp = tmp->next;
        }
      }
     
      return 0;
    }
    merci

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Es tu sûr que l'erreur de lecture de GIMP est du à une erreur crc. Ca peut etre une autre erreur dans les entêtes ou autre.

    Pour ça tu pourrais par exemple comparer le CRC que tu cree avec un CRC original, sans modifier ton image ?

  3. #3
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Es tu sûr que l'erreur de lecture de GIMP est du à une erreur crc. Ca peut etre une autre erreur dans les entêtes ou autre.

    Pour ça tu pourrais par exemple comparer le CRC que tu cree avec un CRC original, sans modifier ton image ?
    j ai deja fait ca, le probleme vient bien de la valeur crc que je calcule.

  4. #4
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    heu... le calcul du CRC se fait sur un chunk entier (type+data) et pas sur chaque pixel.

    http://www.w3.org/TR/PNG/#5Chunk-layout

  5. #5
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    heu... le calcul du CRC se fait sur un chunk entier (type+data) et pas sur chaque pixel.

    http://www.w3.org/TR/PNG/#5Chunk-layout
    je fais bien le calcul sur un chunk entier.
    l'appel à la fonction mkCrc n'est fait que pour le dernier pixel de la liste chainée, lorsque tous les pixels ont été recopiés dans le buffer "buf".

    par contre je ne calcule pas le crc avec le type, je vais essayer ça.

    merci

  6. #6
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par floopi51 Voir le message
    je fais bien le calcul sur un chunk entier.
    l'appel à la fonction mkCrc n'est fait que pour le dernier pixel de la liste chainée, lorsque tous les pixels ont été recopiés dans le buffer "buf".

    par contre je ne calcule pas le crc avec le type, je vais essayer ça.

    merci
    pour faire ça j'ajoute le type de chunk (IDAT) au début de mon buffer, et je me retrouve avec une erreur de segmentation.....

    voici mon code modifié : NB les structures sont identiques au post precedent

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    int
    calcCRC(struct accesPix *lpix) {
      struct l_pix * tmp;
      unsigned char buf[260];
      unsigned long crc;
      int i, len=0;
     
      tmp = lpix->first;
      /* 1er pixel d'un chunk est avec len!=0, dernier pixel est avec
       * flag=1
       */
      while(tmp != NULL) {
        if(tmp->pix->len != 0) {
          len = tmp->pix->len;
          len += 4; /* ajout de la longeur du type */
          bzero(buf,260);
        }
     
        /* copie du type du chunk dans buf */
        memcpy(&buf[0],idat, 4);
     
        for(i=4; i<((len-4)/4); i++) {
          memcpy(&buf[i],(&(tmp->pix->red)), 1); 
          memcpy(&buf[i],(&(tmp->pix->green)), 1); 
          memcpy(&buf[i],(&(tmp->pix->blue)), 1); 
          memcpy(&buf[i],(&(tmp->pix->alpha)), 1); 
     
          if(tmp->pix->flag == 1) {
    	/* crc32 est une fonction fournie par la lib zlib incluse
    	 * dans la libpng
    	 */ 
    	crc = crc32(tmp->pix->crc,buf, len);
    	fprintf(stderr,"calcCRC : len =<%d> <%8x>\n",len,crc);
          }
          tmp = tmp->next;
        }
      }
     
      return 0;
    }
    une idée ? une remarque ?

    floopi51

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      while(tmp != NULL) {
    ....
        for(i=4; i<((len-4)/4); i++) {
          memcpy(&buf[i],(&(tmp->pix->red)), 1); 
          memcpy(&buf[i],(&(tmp->pix->green)), 1); 
          memcpy(&buf[i],(&(tmp->pix->blue)), 1); 
          memcpy(&buf[i],(&(tmp->pix->alpha)), 1); 
    ....
          tmp = tmp->next;
        }
      }
    - Les 4 memcpy écrivent tous au même endroit. Ne serait-ce pas plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        for(i=4; i<len; i+=4) {
          memcpy(&buf[i],(&(tmp->pix->red)), 1); 
          memcpy(&buf[i+1],(&(tmp->pix->green)), 1); 
          memcpy(&buf[i+2],(&(tmp->pix->blue)), 1); 
          memcpy(&buf[i+3],(&(tmp->pix->alpha)), 1);
    - Le contrôle de la boucle for n'est pas sécurisé. Si on arrive avec le temp = temp->next à NULL dans le for, on va planter. C'est à vérifier

  8. #8
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    merci Diogène et Pseudocode, ça marche beaucoup mieux avec vos corrections

    floopi51

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. calcul de PSNR pour une image stéganographiée
    Par hajerboug dans le forum Traitement d'images
    Réponses: 0
    Dernier message: 02/06/2012, 20h08
  2. calcul de CRC pour une image png
    Par floopi51 dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 15/01/2009, 08h35
  3. calcul de l'erreur quadratique pour une image
    Par HALAILI dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 10/10/2008, 10h05
  4. Réponses: 4
    Dernier message: 09/02/2006, 17h44
  5. Définir un angle de rotation pour une image
    Par mateo.14 dans le forum C++
    Réponses: 5
    Dernier message: 25/03/2005, 14h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo