Erreur de segmentation en C

Fermé
Emad - Modifié par irongege le 18/10/2011 à 14:42
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 - 18 oct. 2011 à 14:37
Bonjour,


J'ai une erreur de segmentation sous linux seulement, windows ça marche . Lorsque je debugg sous avec gdb il me donne ça :

_IO_getc (fp=0x0) at getc.c:40
40 getc.c: Aucun fichier ou dossier de ce type.
in getc.c



Voici le code je sais que l'erreur commence dans les procédure dissimulation et extraction car lorsque j'enleve ces deux le reste marche nickel .


#include <stdio.h>
#include <stdlib.h>




/* ----------------------------------- */
/* Definition du type pixel */
/* ----------------------------------- */


struct sPixel
{
unsigned char red;
unsigned char green;
unsigned char blue;
};
typedef struct sPixel pixel;




/* -------------------------------------------------------------- */
/* Declarations des procedures que vous pouvez appeler */
/* (deja ecrites, code disponible pour information apres le main) */
/* -------------------------------------------------------------- */


/* Precondition : nomFichier est le nom d'un fichier au format Bitmap,
24-bit par pixel (donc pas de palette), non compresse.
Postconditions : largeur et hauteur contiennent la largeur (nombre de colonnes)
et la hauteur (nombre de lignes) de l'image, en nombre de pixels.
*/
void lireEntete(const char nomFichier[], unsigned int * largeur, unsigned int * hauteur);



/* Preconditions : tab est un tableau 1D de pixels, suffisamment grand pour contenir
tous les pixels de l'image. nomFichier est le nom d'un fichier au format Bitmap,
24-bit par pixel (donc pas de palette), non compresse. largeur et hauteur
sont les dimensions de l'image en nombre de pixels.
Postcondition : Chaque case de tab correspond a un pixel de l'image et contient
ainsi les valeurs RGB de ce pixel. Les premieres cases de tab contiennent la ligne
de pixels tout en bas de l'image. Les cases suivantes contiennent les pixels de la
ligne juste au-dessus (2e ligne en partant du bas), etc, jusqu'a la ligne du haut
de l'image.
*/
void remplirTableauPixelsDepuisFichier(const char nomFichier[], pixel tab[], \
unsigned int largeur, unsigned int hauteur);




/* Preconditions : tab est un tableau contenant largeur*hauteur pixels.
Postconditions : Un nouveau fichier est cree, nomme comme precise dans la chaine
de caracteres nomFic. Il est au format Bitmap, 24 bits par pixel, non compresse.
Si un fichier de ce nom existait deja, il est ecrase.
*/
void ecrireFichier(const char nomFic[], const pixel tab[], \
unsigned int largeur, unsigned int hauteur);



/* Precondition: 0 <= numbit <= 7, 0 correspond au bit de poids faible
Resultat: on recupere le bit numero 'numbit' de 'nombre', c'est-a-dire
0 ou 1 stocke dans un unsigned char.
*/
unsigned char getIemeBit(unsigned char nombre, unsigned char numbit);




/* Precondition: 0 <= numbit <= 7, 0 correspond au bit de poids faible
Postcondition: le bit numero 'numbit' de 'nombre' est mis a 0
*/
void setIemeBit0(unsigned char * nombre, unsigned char numbit);




/* Precondition: 0 <= numbit <= 7, 0 correspond au bit de poids faible
Postcondition: le bit numero 'numbit' de 'nombre' est mis a 1
*/
void setIemeBit1(unsigned char * nombre, unsigned char numbit);




/* -------------------------------------------------------------- */
/* Ecrivez ci-dessous les codes des procedures demandees */
/* -------------------------------------------------------------- */

void traitementSepia(const pixel tab[], pixel tabSep[], unsigned int intensite, \
unsigned int largeur, unsigned int hauteur)
{
unsigned int i;
unsigned int moyenne = 0;
int tmp = 0;
for(i = 0; i < hauteur*largeur; i ++)
{
moyenne = ((tab[i].red + tab[i].green + tab[i].blue) / 3);

tmp = moyenne - 2*intensite;
if(tmp > 255)
tmp = 255;
if(tmp < 0)
tmp = 0;
tabSep[i].red = tmp;

tmp = moyenne - intensite;
if(tmp > 255)
tmp = 255;
if(tmp < 0)
tmp = 0;
tabSep[i].green = tmp;

tmp = moyenne + 3*intensite;
if(tmp > 255)
tmp = 255;
if(tmp < 0)
tmp = 0;
tabSep[i].blue = tmp;
}

}

void dissimulation(const pixel tab1[], const pixel tab2[],pixel tabDis[], \
unsigned int largeur, unsigned int hauteur)
{
unsigned int i;
unsigned int tmp = 0;
for(i = 0; i < hauteur*largeur; i ++)
{
tabDis[i] = tab1[i];
tmp = getIemeBit((tab2[i].red),7);
if(tmp == 0)
setIemeBit0(&(tabDis[i].red),2);
else
setIemeBit1(&(tabDis[i].red),2);

tmp = getIemeBit((tab2[i].green),6);
if(tmp == 0)
setIemeBit0(&(tabDis[i].green),1);
else
setIemeBit1(&(tabDis[i].green),1);

tmp = getIemeBit((tab2[i].blue),5);
if(tmp == 0)
setIemeBit0(&(tabDis[i].blue),0);
else
setIemeBit1(&(tabDis[i].blue),0);
}

}

void extraction(const pixel tabDis[], pixel tabExt[], \
unsigned int largeur, unsigned int hauteur)
{
unsigned int i;
unsigned int tmp = 0;
for(i = 0; i < hauteur*largeur; i ++)
{
tabExt[i].red = 0;
tabExt[i].green = 0;
tabExt[i].blue = 0;
tmp = getIemeBit((tabDis[i].red),0);
if(tmp == 0)
setIemeBit0(&(tabExt[i].red),5);
else
setIemeBit1(&(tabExt[i].red),5);

tmp = getIemeBit((tabDis[i].green),1);
if(tmp == 0)
setIemeBit0(&(tabExt[i].green),6);
else
setIemeBit1(&(tabExt[i].green),6);

tmp = getIemeBit((tabDis[i].blue),2);
if(tmp == 0)
setIemeBit0(&(tabExt[i].blue),7);
else
setIemeBit1(&(tabExt[i].blue),7);
}

}

/* -------------------------- */
/* Completez le main */
/* -------------------------- */


int main()
{
char nomFicImage1[] = "gargouille.bmp";
char nomFicImage2[] = "F15.bmp";
unsigned int largeur, hauteur = 0;
lireEntete(nomFicImage1,&largeur,&hauteur);
printf("la largeur est %i la hauteur est %i \n",largeur , hauteur);

/* Remplissage des tableaux de pixel */
pixel* tab1;
tab1 = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
remplirTableauPixelsDepuisFichier(nomFicImage1, tab1, largeur, hauteur);

pixel* tab2;
tab2 = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
remplirTableauPixelsDepuisFichier(nomFicImage2, tab2, largeur, hauteur);


/* la lecture du pixel de la 7 eme ligne et la 10 eme colonne */
printf("le pixel de la 7 eme ligne et la 10 eme colonne est (R:%i,G:%i,B:%i)\n",tab1[6*largeur + 9].red, tab1[6*largeur + 9].green, tab1[6*largeur + 9].blue);


/* Effet sepia */
char nomFicImage3[] = "sepia.bmp";
unsigned int intensite = 0;
printf("Veuillez saisir l'intensite de l'effet sepia\n");
scanf("%i", &intensite);
pixel* tabSep;
tabSep = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
traitementSepia(tab1,tabSep,intensite,largeur,hauteur);
ecrireFichier(nomFicImage3,tabSep,largeur,hauteur);

/* Dissimulation d'image */
char nomFicImage4[] = "dissimulation.bmp";
pixel* tabDis;
tabDis = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
dissimulation(tab1,tab2,tabDis,largeur,hauteur);
ecrireFichier(nomFicImage4,tabDis,largeur,hauteur);

/* Extraction image dissimule */
char nomFicImage5[] = "extraction.bmp";
pixel* tabExt;
tabExt = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
extraction(tab2,tabExt,largeur,hauteur);
ecrireFichier(nomFicImage5,tabExt,largeur,hauteur);

system("pause");
return 0;
}


/* Procedure auxiliaire utile pour lire les fichiers */
void fskip(FILE *fp, int num_bytes)
{
int i;
for (i=0; i<num_bytes; i++)
{
fgetc(fp);
}
}


void lireEntete(const char nomFichier[], unsigned int * largeur, unsigned int * hauteur)
{

FILE * fic = fopen(nomFichier, "rb");
unsigned short bitsparpixel = 0;
unsigned int compression = 0, nbcolorsinpalette = 0, nbimportantcolors = 0;

if (fgetc(fic)!='B' || fgetc(fic)!='M')
{
fclose(fic);
fprintf(stderr, "%s n'est pas au format BMP.\n",nomFichier);
exit(EXIT_FAILURE);
}

fskip(fic,16);
fread(largeur, 4, 1, fic);
fread(hauteur, 4, 1, fic);

fskip(fic, 2); /* skipping the number of color planes (always 1) */
fread(&bitsparpixel, 2, 1, fic);

if(bitsparpixel != 24)
{
fclose(fic);
fprintf(stderr, "Erreur: le nombre de bits par pixel n'est pas 24, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}
fread(&compression, 4, 1, fic);
if(compression != 0)
{
fclose(fic);
fprintf(stderr, "Erreur: le mode de compression n'est pas 0, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}

fskip(fic,12);
fread(&nbcolorsinpalette, 4, 1, fic);
if(nbcolorsinpalette != 0)
{
fclose(fic);
fprintf(stderr, "Erreur: le nombre de couleurs dans la palette n'est pas 0, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}

fread(&nbimportantcolors, 4, 1, fic);
if(nbimportantcolors != 0)
{
fclose(fic);
fprintf(stderr, "Erreur: le nombre de couleurs importantes n'est pas 0, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}


fclose(fic);
}





void remplirTableauPixelsDepuisFichier(const char nomFichier[], pixel tab[], \
unsigned int largeur, unsigned int hauteur)
{
FILE * fic = fopen(nomFichier, "rb");
unsigned int ligne, colonne, padding;

fskip(fic, 54);
for(ligne = 0; ligne < hauteur; ligne ++)
{
for (colonne = 0; colonne < largeur; colonne ++)
{
/* Erreur dans l'ordre de lecture des composantes R,G,B */
tab[(ligne*largeur) + colonne].red = fgetc(fic);
tab[(ligne*largeur) + colonne].green = fgetc(fic);
tab[(ligne*largeur) + colonne].blue = fgetc(fic);
}

/* Padding for 4 byte alignment */
if( (3*largeur)%4 == 0) padding = 0;
else padding = 4 - ((3*largeur)%4);
fskip(fic, padding);
}

fclose(fic);
}



void ecrireFichier(const char nomFic[], const pixel tab[], \
unsigned int largeur, unsigned int hauteur)
{
FILE * fic = fopen(nomFic, "wb");
unsigned int monInt;
unsigned short monShort;
unsigned char monChar, i;
unsigned int padding, ligne, colonne, index;

char format[] = {'B', 'M'};
unsigned int tailleFic = 54 + largeur*hauteur*3;


fwrite(format, 1, 2, fic);

/* size of the file in bytes */
fwrite(&tailleFic, 4, 1, fic);

/* Unused, app specific */
monShort = 0;
fwrite(&monShort, 2, 1, fic);
fwrite(&monShort, 2, 1, fic);

/* Offset for pixel data */
monInt = 54;
fwrite(&monInt, 4, 1, fic);

/* Nb of bytes in the header from this point */
monInt = 40;
fwrite(&monInt, 4, 1, fic);

fwrite(&largeur, 4, 1, fic);
fwrite(&hauteur, 4, 1, fic);

/* Nb of color planes (always 1) */
monShort = 1;
fwrite(&monShort, 2, 1, fic);

/* Nb of bits per pixel */
monShort = 24;
fwrite(&monShort, 2, 1, fic);

/* Compression mode */
monInt = 0;
fwrite(&monInt, 4, 1, fic);


/* Size of the raw BMP data (after this header), including padding */
if( (3*largeur)%4 == 0) padding = 0;
else padding = 4 - ((3*largeur)%4);
monInt = (largeur*3 + padding)*hauteur;
fwrite(&monInt, 4, 1, fic);


/* Horiz and vertic resolutions (pixel per metre) */
monInt = 2835;
fwrite(&monInt, 4, 1, fic);
fwrite(&monInt, 4, 1, fic);


/* Numbers of colors in the palette & number of important colors */
monInt = 0;
fwrite(&monInt, 4, 1, fic);
fwrite(&monInt, 4, 1, fic);


/* Pixel data */

for(ligne = 0; ligne < hauteur; ligne ++)
{
for (colonne = 0; colonne < largeur; colonne ++)
{
index = largeur*ligne + colonne;
fwrite(&tab[index].red, 1, 1, fic);
fwrite(&tab[index].green, 1, 1, fic);
fwrite(&tab[index].blue, 1, 1, fic);
}

/* Padding for 4 byte alignment */
if( (3*largeur)%4 == 0) padding = 0;
else padding = 4 - ((3*largeur)%4);
monChar = 0;
for (i = 0; i < padding; i++) fwrite(&monChar, 1, 1, fic);
}

fclose(fic);
}




unsigned char getIemeBit(unsigned char nombre, unsigned char numbit)
{
return (nombre & (1 << numbit)) >> numbit;
}




void setIemeBit0(unsigned char * nombre, unsigned char numbit)
{
*nombre = (*nombre) & (~(1 << numbit));
}



void setIemeBit1(unsigned char * nombre, unsigned char numbit)
{
*nombre = (*nombre) | (1 << numbit);
}

Pourriez vous m'aider svp

4 réponses

Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
18 oct. 2011 à 14:36
alors ok,

ce que je comprends de ton message d'erreur, c'est que tu utilises des fonctions pour lire des fichiers, comme fgetc()

ces fonctions prennent un argument, fp, de type FILE *.

c'est donc un descripteur de fichier.

il faut que tu vérifies avant d'utiliser ton fichier, s'il n'y a pas eu d'erreur d'ouverture, etc... à l'aide de ferr() si je ne me trompe pas.

rajoute des tests avec cette fonction lorsque tu ouvres des fichiers.

voir la doc sur internet ou le man de linux si besoin
1
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
Modifié par Pacorabanix le 18/10/2011 à 14:37
car l'erreur :

_IO_getc (fp=0x0) at getc.c:40
40 getc.c: Aucun fichier ou dossier de ce type.
in getc.c


signifie, selon moi, que ton argument de fonction, fp, n'est pas correct. il vaut "0", zero, NULL, 0x0, que dale.
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
18 oct. 2011 à 13:24
euh d'accord mais ta ligne 40 de ton fichier, c'est quoi ?

et le code autour aussi...

sinon on ne peut pas trop t'aider
0
jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 934
18 oct. 2011 à 13:25
Si tu fournissais l'extrait du code concerné, on pourrait t'aider.
0
getc.c je pense c'est une librairie . Ce fichier ne fais pas parti de mon programme . Je ne le connais pas
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
Modifié par Pacorabanix le 18/10/2011 à 13:31
oui mais ton code, c'est quoi ?

tu dois surement utiliser des bibliothèques non-standard juste pour Windows...


mais si tu ne *donnes pas ton code* impossible d'en dire plus.
0
Voici tout le code :


#include <stdio.h>
#include <stdlib.h>




/* ----------------------------------- */
/* Definition du type pixel */
/* ----------------------------------- */


struct sPixel
{
unsigned char red;
unsigned char green;
unsigned char blue;
};
typedef struct sPixel pixel;




/* -------------------------------------------------------------- */
/* Declarations des procedures que vous pouvez appeler */
/* (deja ecrites, code disponible pour information apres le main) */
/* -------------------------------------------------------------- */


/* Precondition : nomFichier est le nom d'un fichier au format Bitmap,
24-bit par pixel (donc pas de palette), non compresse.
Postconditions : largeur et hauteur contiennent la largeur (nombre de colonnes)
et la hauteur (nombre de lignes) de l'image, en nombre de pixels.
*/
void lireEntete(const char nomFichier[], unsigned int * largeur, unsigned int * hauteur);



/* Preconditions : tab est un tableau 1D de pixels, suffisamment grand pour contenir
tous les pixels de l'image. nomFichier est le nom d'un fichier au format Bitmap,
24-bit par pixel (donc pas de palette), non compresse. largeur et hauteur
sont les dimensions de l'image en nombre de pixels.
Postcondition : Chaque case de tab correspond a un pixel de l'image et contient
ainsi les valeurs RGB de ce pixel. Les premieres cases de tab contiennent la ligne
de pixels tout en bas de l'image. Les cases suivantes contiennent les pixels de la
ligne juste au-dessus (2e ligne en partant du bas), etc, jusqu'a la ligne du haut
de l'image.
*/
void remplirTableauPixelsDepuisFichier(const char nomFichier[], pixel tab[], \
unsigned int largeur, unsigned int hauteur);




/* Preconditions : tab est un tableau contenant largeur*hauteur pixels.
Postconditions : Un nouveau fichier est cree, nomme comme precise dans la chaine
de caracteres nomFic. Il est au format Bitmap, 24 bits par pixel, non compresse.
Si un fichier de ce nom existait deja, il est ecrase.
*/
void ecrireFichier(const char nomFic[], const pixel tab[], \
unsigned int largeur, unsigned int hauteur);



/* Precondition: 0 <= numbit <= 7, 0 correspond au bit de poids faible
Resultat: on recupere le bit numero 'numbit' de 'nombre', c'est-a-dire
0 ou 1 stocke dans un unsigned char.
*/
unsigned char getIemeBit(unsigned char nombre, unsigned char numbit);




/* Precondition: 0 <= numbit <= 7, 0 correspond au bit de poids faible
Postcondition: le bit numero 'numbit' de 'nombre' est mis a 0
*/
void setIemeBit0(unsigned char * nombre, unsigned char numbit);




/* Precondition: 0 <= numbit <= 7, 0 correspond au bit de poids faible
Postcondition: le bit numero 'numbit' de 'nombre' est mis a 1
*/
void setIemeBit1(unsigned char * nombre, unsigned char numbit);




/* -------------------------------------------------------------- */
/* Ecrivez ci-dessous les codes des procedures demandees */
/* -------------------------------------------------------------- */

void traitementSepia(const pixel tab[], pixel tabSep[], unsigned int intensite, \
unsigned int largeur, unsigned int hauteur)
{
unsigned int i;
unsigned int moyenne = 0;
int tmp = 0;
for(i = 0; i < hauteur*largeur; i ++)
{
moyenne = ((tab[i].red + tab[i].green + tab[i].blue) / 3);

tmp = moyenne - 2*intensite;
if(tmp > 255)
tmp = 255;
if(tmp < 0)
tmp = 0;
tabSep[i].red = tmp;

tmp = moyenne - intensite;
if(tmp > 255)
tmp = 255;
if(tmp < 0)
tmp = 0;
tabSep[i].green = tmp;

tmp = moyenne + 3*intensite;
if(tmp > 255)
tmp = 255;
if(tmp < 0)
tmp = 0;
tabSep[i].blue = tmp;
}

}

void dissimulation(const pixel tab1[], const pixel tab2[],pixel tabDis[], \
unsigned int largeur, unsigned int hauteur)
{
unsigned int i;
unsigned int tmp = 0;
for(i = 0; i < hauteur*largeur; i ++)
{
tabDis[i] = tab1[i];
tmp = getIemeBit((tab2[i].red),7);
if(tmp == 0)
setIemeBit0(&(tabDis[i].red),2);
else
setIemeBit1(&(tabDis[i].red),2);

tmp = getIemeBit((tab2[i].green),6);
if(tmp == 0)
setIemeBit0(&(tabDis[i].green),1);
else
setIemeBit1(&(tabDis[i].green),1);

tmp = getIemeBit((tab2[i].blue),5);
if(tmp == 0)
setIemeBit0(&(tabDis[i].blue),0);
else
setIemeBit1(&(tabDis[i].blue),0);
}

}

void extraction(const pixel tabDis[], pixel tabExt[], \
unsigned int largeur, unsigned int hauteur)
{
unsigned int i;
unsigned int tmp = 0;
for(i = 0; i < hauteur*largeur; i ++)
{
tabExt[i].red = 0;
tabExt[i].green = 0;
tabExt[i].blue = 0;
tmp = getIemeBit((tabDis[i].red),0);
if(tmp == 0)
setIemeBit0(&(tabExt[i].red),5);
else
setIemeBit1(&(tabExt[i].red),5);

tmp = getIemeBit((tabDis[i].green),1);
if(tmp == 0)
setIemeBit0(&(tabExt[i].green),6);
else
setIemeBit1(&(tabExt[i].green),6);

tmp = getIemeBit((tabDis[i].blue),2);
if(tmp == 0)
setIemeBit0(&(tabExt[i].blue),7);
else
setIemeBit1(&(tabExt[i].blue),7);
}

}

/* -------------------------- */
/* Completez le main */
/* -------------------------- */


int main()
{
char nomFicImage1[] = "gargouille.bmp";
char nomFicImage2[] = "F15.bmp";
unsigned int largeur, hauteur = 0;
lireEntete(nomFicImage1,&largeur,&hauteur);
printf("la largeur est %i la hauteur est %i \n",largeur , hauteur);

/* Remplissage des tableaux de pixel */
pixel* tab1;
tab1 = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
remplirTableauPixelsDepuisFichier(nomFicImage1, tab1, largeur, hauteur);

pixel* tab2;
tab2 = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
remplirTableauPixelsDepuisFichier(nomFicImage2, tab2, largeur, hauteur);


/* la lecture du pixel de la 7 eme ligne et la 10 eme colonne */
printf("le pixel de la 7 eme ligne et la 10 eme colonne est (R:%i,G:%i,B:%i)\n",tab1[6*largeur + 9].red, tab1[6*largeur + 9].green, tab1[6*largeur + 9].blue);


/* Effet sepia */
char nomFicImage3[] = "sepia.bmp";
unsigned int intensite = 0;
printf("Veuillez saisir l'intensite de l'effet sepia\n");
scanf("%i", &intensite);
pixel* tabSep;
tabSep = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
traitementSepia(tab1,tabSep,intensite,largeur,hauteur);
ecrireFichier(nomFicImage3,tabSep,largeur,hauteur);

/* Dissimulation d'image */
char nomFicImage4[] = "dissimulation.bmp";
pixel* tabDis;
tabDis = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
dissimulation(tab1,tab2,tabDis,largeur,hauteur);
ecrireFichier(nomFicImage4,tabDis,largeur,hauteur);

/* Extraction image dissimule */
char nomFicImage5[] = "extraction.bmp";
pixel* tabExt;
tabExt = (pixel*) malloc(largeur*hauteur*sizeof(pixel));
extraction(tab2,tabExt,largeur,hauteur);
ecrireFichier(nomFicImage5,tabExt,largeur,hauteur);

system("pause");
return 0;
}


/* Procedure auxiliaire utile pour lire les fichiers */
void fskip(FILE *fp, int num_bytes)
{
int i;
for (i=0; i<num_bytes; i++)
{
fgetc(fp);
}
}


void lireEntete(const char nomFichier[], unsigned int * largeur, unsigned int * hauteur)
{

FILE * fic = fopen(nomFichier, "rb");
unsigned short bitsparpixel = 0;
unsigned int compression = 0, nbcolorsinpalette = 0, nbimportantcolors = 0;

if (fgetc(fic)!='B' || fgetc(fic)!='M')
{
fclose(fic);
fprintf(stderr, "%s n'est pas au format BMP.\n",nomFichier);
exit(EXIT_FAILURE);
}

fskip(fic,16);
fread(largeur, 4, 1, fic);
fread(hauteur, 4, 1, fic);

fskip(fic, 2); /* skipping the number of color planes (always 1) */
fread(&bitsparpixel, 2, 1, fic);

if(bitsparpixel != 24)
{
fclose(fic);
fprintf(stderr, "Erreur: le nombre de bits par pixel n'est pas 24, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}
fread(&compression, 4, 1, fic);
if(compression != 0)
{
fclose(fic);
fprintf(stderr, "Erreur: le mode de compression n'est pas 0, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}

fskip(fic,12);
fread(&nbcolorsinpalette, 4, 1, fic);
if(nbcolorsinpalette != 0)
{
fclose(fic);
fprintf(stderr, "Erreur: le nombre de couleurs dans la palette n'est pas 0, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}

fread(&nbimportantcolors, 4, 1, fic);
if(nbimportantcolors != 0)
{
fclose(fic);
fprintf(stderr, "Erreur: le nombre de couleurs importantes n'est pas 0, \n");
fprintf(stderr, "ce format d'image n'est pas supporte par ce programme. \n");
exit(EXIT_FAILURE);
}


fclose(fic);
}





void remplirTableauPixelsDepuisFichier(const char nomFichier[], pixel tab[], \
unsigned int largeur, unsigned int hauteur)
{
FILE * fic = fopen(nomFichier, "rb");
unsigned int ligne, colonne, padding;

fskip(fic, 54);
for(ligne = 0; ligne < hauteur; ligne ++)
{
for (colonne = 0; colonne < largeur; colonne ++)
{
/* Erreur dans l'ordre de lecture des composantes R,G,B */
tab[(ligne*largeur) + colonne].red = fgetc(fic);
tab[(ligne*largeur) + colonne].green = fgetc(fic);
tab[(ligne*largeur) + colonne].blue = fgetc(fic);
}

/* Padding for 4 byte alignment */
if( (3*largeur)%4 == 0) padding = 0;
else padding = 4 - ((3*largeur)%4);
fskip(fic, padding);
}

fclose(fic);
}



void ecrireFichier(const char nomFic[], const pixel tab[], \
unsigned int largeur, unsigned int hauteur)
{
FILE * fic = fopen(nomFic, "wb");
unsigned int monInt;
unsigned short monShort;
unsigned char monChar, i;
unsigned int padding, ligne, colonne, index;

char format[] = {'B', 'M'};
unsigned int tailleFic = 54 + largeur*hauteur*3;


fwrite(format, 1, 2, fic);

/* size of the file in bytes */
fwrite(&tailleFic, 4, 1, fic);

/* Unused, app specific */
monShort = 0;
fwrite(&monShort, 2, 1, fic);
fwrite(&monShort, 2, 1, fic);

/* Offset for pixel data */
monInt = 54;
fwrite(&monInt, 4, 1, fic);

/* Nb of bytes in the header from this point */
monInt = 40;
fwrite(&monInt, 4, 1, fic);

fwrite(&largeur, 4, 1, fic);
fwrite(&hauteur, 4, 1, fic);

/* Nb of color planes (always 1) */
monShort = 1;
fwrite(&monShort, 2, 1, fic);

/* Nb of bits per pixel */
monShort = 24;
fwrite(&monShort, 2, 1, fic);

/* Compression mode */
monInt = 0;
fwrite(&monInt, 4, 1, fic);


/* Size of the raw BMP data (after this header), including padding */
if( (3*largeur)%4 == 0) padding = 0;
else padding = 4 - ((3*largeur)%4);
monInt = (largeur*3 + padding)*hauteur;
fwrite(&monInt, 4, 1, fic);


/* Horiz and vertic resolutions (pixel per metre) */
monInt = 2835;
fwrite(&monInt, 4, 1, fic);
fwrite(&monInt, 4, 1, fic);


/* Numbers of colors in the palette & number of important colors */
monInt = 0;
fwrite(&monInt, 4, 1, fic);
fwrite(&monInt, 4, 1, fic);


/* Pixel data */

for(ligne = 0; ligne < hauteur; ligne ++)
{
for (colonne = 0; colonne < largeur; colonne ++)
{
index = largeur*ligne + colonne;
fwrite(&tab[index].red, 1, 1, fic);
fwrite(&tab[index].green, 1, 1, fic);
fwrite(&tab[index].blue, 1, 1, fic);
}

/* Padding for 4 byte alignment */
if( (3*largeur)%4 == 0) padding = 0;
else padding = 4 - ((3*largeur)%4);
monChar = 0;
for (i = 0; i < padding; i++) fwrite(&monChar, 1, 1, fic);
}

fclose(fic);
}




unsigned char getIemeBit(unsigned char nombre, unsigned char numbit)
{
return (nombre & (1 << numbit)) >> numbit;
}




void setIemeBit0(unsigned char * nombre, unsigned char numbit)
{
*nombre = (*nombre) & (~(1 << numbit));
}



void setIemeBit1(unsigned char * nombre, unsigned char numbit)
{
*nombre = (*nombre) | (1 << numbit);
}
0