[C++] Lecture d'un fichier bitmap

Résolu/Fermé
Signaler
-
 beta testeur -
Bonjour,

Je dois réaliser un programme en c++ qui récupère les info dans un fichier bitmap.
Pour cela, j'utilise "fopen" pour ouvrir le fichier bitmap en binaire.
J'utilise "fseek" pour me placer au bon endroit dans le fichier
Et enfin "fgetc" pour récupérer les octets.

Pour le moment pas de problème apparent.... sauf que fgetc récupère des valeurs négatives (0xFFFFFFC0 par exemple) or il n'y en a pas dans un fichier bitmap.

Pourquoi ?? Et comment fait-il pour caser ce nombre dans UNE case d'un tableau de caractère sans générer d'erreur ??!!!

J'aimerai beaucoup résoudre ce problème.
J'ai essayé de faire des tests de signe sur les valeurs récupérer mais il ne voit rien...

Je vous serais reconnaissant de vous pencher sur mon problème, svp

Merci d'avance.

12 réponses


Je ne peux pas mettre de unsigned char à cause de la fonction strcpy (c'est ma faute, j'ai oublié de le préciser dans le post), la fonction strcpy n'accepte que des const char.

Il y a t-il une alternative à strcpy ?
1
Comment écrire et lire un fichier bipmap en C++? voir www.gravitomagnetism.com en fin de page d'accueil
1

ton programme est en C, hors sur le sujet c'est précisé qu'il cherche à le faire en C++.
0
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 331
tu peux faire du cast de porc...
unsigned char* a,b;
...//du code
strcpy((char*)a,(char*)b);
vu que c'est codé sur le même nombre de bit, ça devrai passer.
à tester.
0

Ok, j'essai ça
0

Bonjour

J'ai effectué ce que tu m'as donné, j'ai de nouvelles erreurs encore du aux types et aux pointeurs.

J'ai fait

(unsigned char*) temp;
....
strcpy((char*)signature,(char*)temp);


maintenant cette partie du code fonctionne mais j'ai des lignes:

if(temp[0]=='B' and temp[1]=='M')
.....


je les ai remplacé par:

if((char*)temp[0]=='B' and (char*)temp[1]=='M')
....


Il m'a mis une erreur (qui m'a semblé logique) comme quoi il ne pouvait pas comparer un pointeur avec un entier.
De là, j'ai retiré l'étoile dans la comparaison et l'erreur reste (ce qui ne me semble pas logique)...
Je dois mettre quoi pour que l'erreur disparaisse ?

Merci d'avance
0
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 331
Bon déjà, tu n'as pas allou de meoire à temp, il est donc logicque que le programme fasse une erreur. Ensuite :
if(int i=0;i<bit;i++) remplace le if par un for pour avoir les autres valeurs.
Pour finir (mais ça c'est du détail), je ne pense pas que la taille soit en bit, mais plutôt en octet et un octet vaut 8 bits.
Il me semble qu'un char est codé sur 8bits, soit un octet, donc à chaque fois que tu fait fgetc tu lit au moins 8 bits.
pour coder 256 valeurs, il faut donc au moins un octet. Les int sont codé (en général) sur 4 octets.
0

J'avais bien mis for(int i=0;i<bit;i++), j'ai fais une faute de frappe dans le message. Il ne li quand même pas les autres infos (il le faisait toutefois avant que je ne transforme char temp[4] en unsigned char* temp)
Je me suis bien trompé dans les commentaire, c'est bien en octets, pas en bits... je vais corriger ça
0

Le problème vient apparemment du pointeur (unsigned char* temp) mais je le fais pointer sur quoi ?
Je me demande pourquoi, il arrive à stocker les 2 premiers octets, puis ignore les autres sans faire de message d'erreur.
0
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 331
Sit u ne veu pas t'enmerder, fait :
unsigned char temp[8];
sinon, unsigned char*temp = new (unsigned char)[8];//ou un truc dans le genre
0

Merci, apparemment ça fonctionne bien maintenant avec unsigned char temp[8];

0
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 331
0xFFFFFFC0 est négatif seulement si tu décide qu'il est négatif. En utilisant une rerésentation "unsigned" tu aura une autre valeur.
regarde là :
http://www.linux-kheops.com/doc/man/manfr/man-ascii-0.9/man3/fgetc.3.txt.html
le proto de fgetc () donne comme valeur de retour un int, à partir d'un unsigned char.
Donc, au final, attention aux types et à leur taille.
Donne la manip que tu fais. si tu met fgetc dans un tableau de char*, ça peut causer des soucis. Par contre, en unsigned char*, ça devrais passer.
-1

Après quelques modifications de types. L'erreur ne s'affiche plus, il compile le programme mais à l'exécution. Il me met une erreur de segmentation donc je manipule mal mes pointeurs, je suppose que l'erreur se situe dans l'utilisation du pointeur temp mais je ne vois pas où. Je vais retaper le code de la fonction dans le message:

int Image::set_param(FILE* file, int pos)
{
     unsigned char* temp;     //variable temporaire qui contient les octets du fichier bitmap
     int bit;                             //nombre de bit de l'info (2 ou 4)
     int test;                          

//en fonction de la postion dans le fichier, l'info sera sur 2 ou 4 bits     
     if(pos==0 or pos==26 or pos==28)            
          bit=2;
     else
          bit=4;                                                       

    //se place à la postion pos dans le fichier à partir du début
     if((test=fseek(file,pos,SEEK_SET))!=0)
          return 0;                                                  

    //récupère l'info à cette position 
    //(j'ai déjà une incohérence ici, il ne récupère que la première info)
      if(int i=0;i<bit;i++)
     {
           temp[i]=fgetc(file);
           printf("%d: %d\n",pos,(int)temp[i]);    //pour voir s'il récupère bien les infos.
      }

     if(pos==0)
     {
            if((char)temp[0]=='B' and (char)temp[1]=='M')
                   strcpy(signature,"Bitmap Windows");
            ..... //Autres tests de caractères du même genre
      }

      if(pos==2)
             taille_fichier=(int)temp[0]+(int)temp[1]*256+(int)temp[2]*65536
                                   +(int)temp[3]*16777216;

      if(pos==6)
             strcpy((char*)champ_reserve,(char*)temp);

      ...  
//Il y a une dizaine de positions à traiter dans le fichier, 
//c'est soit des caractères, soit des traitement de valeurs entières.



Le problème semble toutefois venir du début car il ne récupère pas toutes les valeurs...
-1