begin process at 2012 05 29 22:58:36
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Linux

 > 

Multimédia

 > 

lecture BMP 32 ok mais pas 24bits


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

lecture BMP 32 ok mais pas 24bits

mercredi 4 février 2009 à 21:49:50 | lecture BMP 32 ok mais pas 24bits

snotocs

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<unistd.h>
#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<imageheader.biWidth;i++){
      bitmaparray24[i]=(PIXEL_24*)malloc(imageheader.biWidth*sizeof(PIXEL_24));
    }

    /* Remplissage */
    for (i=imageheader.biHeight-1;i>=0;i--){
      for(j=0;j<imageheader.biWidth;j++){
    bitmaparray24[i][j].b=*octets_courant;
    octets_courant+=1;
    bitmaparray24[i][j].g=*octets_courant;
    octets_courant+=1;
    bitmaparray24[i][j].r=*octets_courant;
    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);
      }
    }


    /* POUR TESTS */
    for (i=imageheader.biHeight-1;i>=0;i--){
      for(j=0;j<imageheader.biWidth;j++){
        /* CAUSE une erreur
    if(i==imageheader.biHeight-1)printf("B:%d G:%d R:%d \n",bitmaparray24[i][j].b,bitmaparray24[i][j].g,bitmaparray24[i][j].r); /*
       
        */
        if(i==0)printf("B:%d G:%d R:%d \n",bitmaparray24[i][j].b,bitmaparray24[i][j].g,bitmaparray24[i][j].r); 
      }
    }

    break;
  case 32:
   
    /* Création des pointeurs formant la matrice */
    bitmaparray32=(PIXEL_32**)malloc(imageheader.biHeight*sizeof(PIXEL_32));
    for(i=0;i<imageheader.biWidth;i++){
      bitmaparray32[i]=(PIXEL_32*)malloc(imageheader.biWidth*sizeof(PIXEL_32));
    }

    /* Remplissage */
    for (i=imageheader.biHeight-1;i>=0;i--){
      for(j=0;j<imageheader.biWidth;j++){
    bitmaparray32[i][j].b=*octets_courant;
    octets_courant+=1;
    bitmaparray32[i][j].g=*octets_courant;
    octets_courant+=1;
    bitmaparray32[i][j].r=*octets_courant;
    octets_courant+=1;
    bitmaparray32[i][j].t=*octets_courant;
    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);
      }
    }
    /* POUR TESTS */
    for (i=imageheader.biHeight-1;i>=0;i--){
      for(j=0;j<imageheader.biWidth;j++){
        
    if(i==imageheader.biHeight-1)printf("B:%d G:%d R:%d \n",bitmaparray32[i][j].b,bitmaparray32[i][j].g,bitmaparray32[i][j].r);
       
       
        //if(i==0)printf("B:%d G:%d R:%d \n",bitmaparray32[i][j].b,bitmaparray32[i][j].g,bitmaparray32[i][j].r); 
      }
    }
    break;
  }






  /* Libération de l'espace alloué */
  free(octets);

   
  printf("Magic Number For File : %d\n",fileheader.bfType);
  printf("Size of File : %d bytes\n",fileheader.bfSize);
  printf("Reserved 1 : %d \n",fileheader.bfReserved1);
  printf("Reserved 2 : %d \n",fileheader.bfReserved2);
  printf("Offset to bitmap data : %d\n",fileheader.bfOffBits);
  printf("Size of info header : %d\n",imageheader.biSize);
  printf("Largeur de l'image en pixel : %d\n",imageheader.biWidth);
  printf("Hauteur de l'image en pixel : %d\n",imageheader.biHeight);
  printf("Nombre de \"plan\" dans cet image: %d\n",imageheader.biPlanes);
  printf("Nombre de bits par pixel : %d\n",imageheader.biBitCount);
  printf("Type de compression utilisée : %d\n",imageheader.biCompression);
  printf("Taille des données image : %d\n",imageheader.biSizeImage);
  printf("X pixels par metre : %d\n",imageheader.biXPelsPerMeter);
  printf("Y pixels par metre : %d\n",imageheader.biYPelsPerMeter);
  printf("Nbr de couleurs utilisées : %d\n",imageheader.biClrUsed);
  printf("Nbr d'importantes couleurs : %d\n",imageheader.biClrImportant);



  /*     TRAITEMENT SUR BITMAPARRAY       */




  /* SAUVEGARDE DANS UN AUTRE FICHIER */

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

  /* On recopie les données du header récupéré précédemment */
  if (fwrite(&fileheader, sizeof(BITMAPFILEHEADER), 1, fp) < 1){
    /* Couldn't read the file header - return NULL... */
    fprintf(stderr,"Ecriture sur le fichier impossible\n");
    fclose(fp);
    return (0);
  }

  /* On écrit le nombre de données correspondant à l'en tête du fichier */
  if (fwrite(&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 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;

  printf("bip\n");

  switch (imageheader.biBitCount) {
  case 1:
    break;
  case 4:
    break;
  case 8:/*
       if (fread(&grey,sizeof(unsigned char),1,fptr) != 1) {
       fprintf(stderr,"Image read failed\n");
       exit(-1);
       }
       if (gotindex) {
       putchar(colourindex[grey].r);
       putchar(colourindex[grey].g);
       putchar(colourindex[grey].b);
       } else {
       putchar(grey);
       }*/
    break;
  case 24:
    printf("bap\n");

    for (i=imageheader.biHeight-1;i>=0;i--){
      for(j=0;j<imageheader.biWidth;j++){
    *octets_courant=bitmaparray24[i][j].b;
    octets_courant+=1;
    *octets_courant=bitmaparray24[i][j].g;       
    octets_courant+=1;
    *octets_courant=bitmaparray24[i][j].r;
    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);
  }      
    break;
  case 32:

    for (i=imageheader.biHeight-1;i>=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)
jeudi 5 février 2009 à 14:30:33 | Re : lecture BMP 32 ok mais pas 24bits

rt15

Membre Club Administrateur CodeS-SourceS
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...
jeudi 5 février 2009 à 14:31:05 | Re : lecture BMP 32 ok mais pas 24bits

rt15

Membre Club Administrateur CodeS-SourceS
Et libère la mémoire...
jeudi 5 février 2009 à 18:09:57 | Re : lecture BMP 32 ok mais pas 24bits

snotocs

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 .
jeudi 5 février 2009 à 20:05:14 | Re : lecture BMP 32 ok mais pas 24bits

rt15

Membre Club Administrateur CodeS-SourceS
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).




vendredi 6 février 2009 à 09:44:08 | Re : lecture BMP 32 ok mais pas 24bits

snotocs

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


Cette discussion est classée dans : printf, octets, unsigned, courant, imageheader


Répondre à ce message

Sujets en rapport avec ce message

Unsigned __int64 et PRINTF [ par BeLZeL ] Ce message n'attend pas de réponse. Il est là à titre indicatif. Il aidera les gens qui tomberont dessus via un moteur de recherche.En effet, j'ai un Appel d'une fonction langage c [ par BenoitGironde ] Excusez-moi j'ai oublié de poster mon travail. <font liste chaine [ par b2_mk2 ] Bonjour je doit dire que c'est bien la premiere fois que je ne trouve pas de solution a mon probleme avec vos archive.Donc vu que ca fait maintenant q HELP HELP EN C !!! [ par cali1983 ] Voilà j'ai un problème pour crypter un texte j'ai fais un programme il n'a aucune erreur si ce n'est qu'il veut pas faire ce que je dis.Il ne veut pas class matrice [ par flaky ] Slt à tousJ'utilise une classe "matrice" (celle de nicolas aunai, téléchargée sur le site) qui fonctionne très bien. Mais j'ai du mal à manipuler l'ob petite question pr une meilleur visibilité [ par anek971 ] Bonjour a tousEnfaite je voudrais savoir en mode console comment on fait pr que par exemple le prog :#include int main(void){ int choix; do { printf [c] plantage du program,base 2 donné, surmen un pb de struct [ par Diony ] jvous explique mon probleme . ce programme est une base de données de recettes . et il plante a la fonction inserer_recette_fin_liste (vers le milieu envoyer une commande à l'intérieure du programme sous forme de string [ par oudkaramla ] bonjour tout le monde j'ai un programme qui demande à l'utilisateur d'entrer une commande sur la fenêtre consolesauf que moi je veux le faire à l'inté Printf bizarre [ par x0s ] Bonjour Amis codeurs,J'ai un probleme avec cette petite fonction, je débute en c, merci de m'aider, voici le problème:#include /* Autor lire 12 octets sur le port série [ par jeromelef ] Bonjourje développe une application avec borland c++ et j'ai besoin de lire le port série. le probléme c'est que je n'arrive pas à lire les 12 octets


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,390 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales