/*************************************************************************************************/
/*************************       Niveau de gris       ********************************************/
/*************************************************************************************************/

#include <stdafx.h>
#include <stdio.h>
#include <conio.h>

int NiveauDeGris(char *, char *);
int entete(char *, char *, int *);

void main()
{
	char nomFicL[80], nomFicE[80];
   int ret;

   printf("\nNom de l'image a traiter : ");
   scanf("%s",nomFicL);
   printf("\nNom de l'image transformee : ");
   scanf("%s",nomFicE);

   ret=NiveauDeGris(nomFicL, nomFicE);
   switch(ret)
   {
   	case 0 : printf("\nTraitement termine"); break;
   	case 1 : printf("\nFichier inexistant"); break;
   	case 2 : printf("\nL'image n'est pas au format BMP 24 bits");
   }
   getch();
}

int entete(char *nomFicE, char *nomFicS, int dim[2])
{
   FILE *ptrE, *ptrS;			// Pointeurs de fichiers
   unsigned char bm[2];			// Buffer pour les lettres BM
   short couleur;					// Nombre de couleurs

   // Ouverture du fichier d'entrée en lecture
   ptrE=fopen(nomFicE,"rb");

   // Le fichier d'entrée existe-t-il ?
   if (ptrE==NULL)
   	return 1;

   // Ouverture du fichier de sortie écriture
   ptrS=fopen(nomFicS,"wb");

   // Lire et stocker les 2 premiers octets (car. B et M)
   fread(bm,sizeof(unsigned char),2,ptrE);

   // Avancer de 16 octets
   fseek(ptrE,16,SEEK_CUR);

   // Lire et recopier les dimensions
   fread(dim,sizeof(int),2,ptrE);

   // Avancer de 2 octets
   fseek(ptrE,2,SEEK_CUR);

   // Lire et stocker le nb de couleurs
   fread(&couleur,sizeof(short),1,ptrE);

   // Vérification du format de l'image
   if((bm[0]!='B') || (bm[1]!='M') || (couleur!=24))
   {
      // Si format incorrect, fermer et effacer fichier de sortie
      fclose(ptrE); fclose(ptrS);
      unlink(nomFicS);
   	return 2;
   }
	// Fermeture des fichiers
   fclose(ptrE); fclose(ptrS);

   // Traitement entête OK
   return 0;
}

int NiveauDeGris( char *nomFicE, char *nomFicS)
{
   FILE *ptrE, *ptrS;			// Pointeurs de fichiers
	int ret; 						// Retour de la fonction
   unsigned char enTete[54];	// Buffer de recopie de l'entête
   unsigned char b, ob; 		// Nombre d'octets de bourrage, octet de bourrage
   int dim[2];						// Dimensions de l'image (largeur, hauteur)
   int i, j;						// Index courants
   unsigned char moyenne;		// Moyenne des 3 couleurs
   struct pixel					// Contenu d'un pixel
   {
   	unsigned char bleu;
      unsigned char vert;
      unsigned char rouge;
   } point;

   // Traitement de l'entete
   ret=entete(nomFicE, nomFicS, dim);

   if(ret!=0)
   	return ret;

   // Ouverture des fichiers
   ptrE=fopen(nomFicE,"rb");
   ptrS=fopen(nomFicS,"wb");

   // Lire et recopier 54 octets
   fread(enTete,sizeof(unsigned char),54,ptrE);
   fwrite(enTete,sizeof(unsigned char),54,ptrS);

   // Calculer le nb d'octets à 0 de bourrage
   b=4-(3*dim[0]%4)&3;

   for(i=0;i<dim[1];i++)
   {
   	for(j=0;j<dim[0];j++)
      {
         // Lire pixel dans E
         fread(&point,sizeof(point),1,ptrE);
         // Moyenne des 3 composantes
         moyenne=(point.bleu+point.vert+point.rouge)/3;
         // Composantes = moyenne
         point.bleu=moyenne;
         point.vert=moyenne;
         point.rouge=moyenne;
         // Ecrire pixel dans S
         fwrite(&point,sizeof(point),1,ptrS);
      }

      // Lire-écrire les octets de bourrage
      for(j=0;j<b;j++)
      {
      	fread(&ob,sizeof(ob),1,ptrE);
      	fwrite(&ob,sizeof(ob),1,ptrS);
      }
   }

	// Fermeture des fichiers
   fclose(ptrE); fclose(ptrS);

   // Traitement OK
   return 0;
}

