Lecture BMP 32 ok mais pas 24bits

snotocs Messages postés 6 Date d'inscription lundi 13 septembre 2004 Statut Membre Dernière intervention 20 août 2009 - 4 févr. 2009 à 21:49
snotocs Messages postés 6 Date d'inscription lundi 13 septembre 2004 Statut Membre Dernière intervention 20 août 2009 - 6 févr. 2009 à 09:44
Bonjour, je me suis codé un petit programme permettant de récupérer la valeur des pixels contenus dans l'image seulement ce que j'ai fait fonctionne pour des images 32 bits mais pas pour des 24 bits.

Pourtant je fais bien un case selon le nb de bits et fait un traitement différent. J'ai beau cherché avec ddd et des print mais j'arrive pas a trouver ou cela coince. Au niveau des 24 bits lorsque je rempli ma matrice tout a l'air de bien se passer mais lorsque je veu afficher les valeurs j'ai une erreur de segmentation ... Quelqu'un pourrait-il m'aider svp

Je vous remercie d'avance je vous donne mon source ci dessous

#include<stdio.h>
#include<string.h>
#include
#include<stdlib.h>
#define BF_TYPE 0x4D42
#pragma pack(push, 1)
#define BYTE unsigned char

///Header de fichier du BITMAP
typedef struct                       /**** BMP file header structure ****/
{
  unsigned short bfType;           /* Magic number for file 2 bytes */
  unsigned int   bfSize;           /* Size of file 4 bytes */
  unsigned short bfReserved1;      /* Reserved 2 bytes */
  unsigned short bfReserved2;      /* ... 2 bytes */
  unsigned int   bfOffBits;        /* Offset to bitmap data 4 bytes */
} BITMAPFILEHEADER;

///Header d'information du BITMAP
typedef struct                       /**** BMP file info structure ****/
{
  unsigned int   biSize;           /* Size of info header 4 bytes */
  unsigned int   biWidth;          /* Width of image 4 bytes */
  unsigned int   biHeight;         /* Height of image 4 bytes*/
  unsigned short biPlanes;         /* Number of color planes */
  unsigned short biBitCount;       /* Number of bits per pixel */
  unsigned int   biCompression;    /* Type of compression to use */
  unsigned int   biSizeImage;      /* Size of image data */
  unsigned int   biXPelsPerMeter;  /* X pixels per meter */
  unsigned int   biYPelsPerMeter;  /* Y pixels per meter */
  unsigned int   biClrUsed;        /* Number of colors used */
  unsigned int   biClrImportant;   /* Number of important colors */
} BITMAPINFOHEADER;

//Couleur de palette colorimétrique
typedef struct
{
  unsigned char rgbBlue;
  unsigned char rgbGreen;
  unsigned char rgbRed;
  unsigned char rgbReserved;
} RGBQUAD;

///Pixels de BITMAP selon format
typedef struct
{
  BYTE b;
  BYTE g;
  BYTE r;
} PIXEL_24;

typedef struct
{
  BYTE b;
  BYTE g;
  BYTE r;
  BYTE t;
} PIXEL_32;

typedef struct {

  /*!
   * Fichier image d'entree du textureur.
   */
  const char* fichierImage;

  
} DescripteurTache ;

int main(int argc, char** argv)
{
  BITMAPFILEHEADER fileheader;                   /* En-tete du fichier                    */
  BITMAPINFOHEADER imageheader;                  /* En-tete de l'image                    */
  FILE * fp;                                     /* Pointeur de fichier                   */
  BYTE * octets ;
  BYTE * octets_courant;                           /* Pointeur parcourant les données image */
  PIXEL_32 ** bitmaparray32;
  PIXEL_24 ** bitmaparray24;
  int i,j;

  DescripteurTache tache;
  /* Initialisation des valeurs par défauts */
  tache.fichierImage = "bmp32.bmp";
  char * filename = "test.bmp";      

   
  // traitement (simpliste) des arguments Unix

  if (argc>=2) tache.fichierImage = argv[1];

  /* On essaie d'ouvrir le fichier. On utilise le mode rb pour lire ce fichier binaire */  if ((fp fopen(tache.fichierImage, "rb")) NULL){
    fprintf(stderr,"Impossible d'ouvrir le fichier demandé\n");   
    return (0);
  }

  /* On lit le nombre de données correspondant à l'en tête du fichier */
  if (fread(&fileheader, sizeof(BITMAPFILEHEADER), 1, fp) < 1){
    /* Couldn't read the file header - return NULL... */
    fprintf(stderr,"Le fichier ne contient pas assez de données pour lire le header du fichier BMP\n");
    fclose(fp);
    return (0);
  }

  /* On s'assure que le fichier est bien du type BMP */
  if (fileheader.bfType != BF_TYPE)    /* Check for BM reversed... */
    {
      /* Not a bitmap file - return NULL... */
      fprintf(stderr,"Le fichier spécifié n'est pas du type BMP\n");
      fclose(fp);
      return (0);
    }

  /* On lit le nombre de données correspondant à l'en tête du fichier */
  if (fread(&imageheader, sizeof(BITMAPINFOHEADER), 1, fp) < 1){
    /* Couldn't read the file header - return NULL... */
    fprintf(stderr,"Le fichier ne contient pas assez de données pour lire le header de l'image BMP\n");
    fclose(fp);
    return (0);
  }

  /* On va se positionner au début des données propre à l'image */
  fseek(fp, fileheader.bfOffBits, SEEK_SET );

  /* On alloue de la mémoire de la taille des données images */
  /* Le pointeur d'octets Octets pointe sur le premier
     octet de l'espace attribué   */  if ((octets malloc(imageheader.biSizeImage*sizeof(BYTE))) NULL){
    /* Ne peut allouer de la mémoire - return NULL! */
    fclose(fp);
    return (0);
  }
 
  octets_courant = octets;

    /* On lit les données images et les stocke dans l'espace alloué précédemment */
    if(fread(octets,sizeof(BYTE),imageheader.biSizeImage,fp) < imageheader.biSizeImage){
      /* Ne peut lire les données images */
      free(octets);
      fclose(fp);
      return(0);
    }

  /* bitmaparray[i][j] */
  /*  i lignes         */
  /*  j colonnes       */

  switch (imageheader.biBitCount) {
  case 1:
    break;
  case 4:
    break;
  case 8:/*
      
    break;
  case 24:

    /* Création des pointeurs formant la matrice */
    bitmaparray24=(PIXEL_24**)malloc(imageheader.biHeight*sizeof(PIXEL_24));
    for(i=0;i=0;i--){
      for(j=0;j=0;i--){
      for(j=0;j=0;i--){
      for(j=0;j=0;i--){
      for(j=0;j=0;i--){
      for(j=0;j=0;i--){
      for(j=0;j<imageheader.biWidth;j++){
    *octets_courant=bitmaparray32[i][j].b;
    octets_courant+=1;
    *octets_courant=bitmaparray32[i][j].g;       
    octets_courant+=1;
    *octets_courant=bitmaparray32[i][j].r;
    octets_courant+=1;
    *octets_courant=bitmaparray32[i][j].t;
    octets_courant+=1;
    //printf("B:%d G:%d R:%d T:%d\n",bitmaparray[i][j].b,bitmaparray[i][j].g,bitmaparray[i][j].r,bitmaparray[i][j].t);
      }
    }
    /* On lit les données images et les stocke dans l'espace alloué précédemment */
    if(fwrite(octets,sizeof(BYTE),imageheader.biSizeImage,fp) < imageheader.biSizeImage){
    /* Ne peut lire les données images */
    free(octets);
    fclose(fp);
    return(0);
  }
  }

  /* On libère l'espace alloué */
  free(octets);

  return(0);
}
#pragma pack (pop)

5 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
5 févr. 2009 à 14:30
Salut,

  bitmaparray24=(PIXEL_24**)malloc(imageheader.biHeight*sizeof(PIXEL_24));

Tu alloue biHeight * sizeof(PIXEL_24) dans un tableau de PIXEL_24*.

Ca plante car PIXEL_24 fait 3 octets, alors que PIXEL_24* en fait 4 (C'est à dire 32 bits, comme dans le cas ton chargement de la bitmap 32 bits qui ne plante pas).

Tu peux cependant allouer la matrice en un malloc...
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
5 févr. 2009 à 14:31
Et libère la mémoire...
0
snotocs Messages postés 6 Date d'inscription lundi 13 septembre 2004 Statut Membre Dernière intervention 20 août 2009
5 févr. 2009 à 18:09
Salut, je ne suis pas tout à fait sûr d'avoir compris ...

la structure PIXEL_24 fait 3 bytes je suis d'accord et un pointeur de PIXEL_24 fait une taille de 4 bytes ? Cela vient du pointeur qui prend un byte ?

Mais alors je ne comprend pas pourquoi cela marche avec mes PIXEL_32 ... Pourrais-je avoir quelques détails supplémentaires ou de la littérature relatif à ce détails.

Merci d'avance .
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
5 févr. 2009 à 20:05
Bordel de Dieu ! (Et chui poli).

Va falloir me réviser les pointeurs, monsieur snotocs !

Un pointeur fait toujours 4 octets (Sur les OS 32 bits).
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
snotocs Messages postés 6 Date d'inscription lundi 13 septembre 2004 Statut Membre Dernière intervention 20 août 2009
6 févr. 2009 à 09:44
Ah en effet je comprend mieux le problème, je suis désolé j'ai eu un cours sur les pointeurs assez bref il y a quelques années et j'ai voulu bosser en C pour approfondir un peu mes connaissances sur ce langage.

C'est une notion sur les pointeurs que je n'avais pas vraiment retenu bien que maintenant cela me semble logique qu'il faille 32 bits pour un pointeur vu que celui-ci doit pouvoir adresser toute la plage d'addresse.

Bref je te remercie énormément, je pense réutiliser mon PXEL_32 mais je n'utiliserais pas le dernier byte dans le cas des 24 bytes .

Merci, bye
0