/* --------------------------------------------------*/
/*   Filtrage Moyen				     */
/*   Fichier: LibMoyen.c			     */
/*   Auteur: Patrick Bonnin			     */
/*   Date de Creation:                               */
/*   Livree : Le TI a l'IUT                          */
/* --------------------------------------------------*/
#include "Structures.h"
/* ---- Code de l'operateur Moyen ---- */

void CouleurKirsh(IMAGE *image, IMAGE *imnorm, IMAGE *imarg, IMAGE *imres)
{
  POINT	*point = NULL, *pointv1 = NULL, *pointv2 = NULL, *pointv=NULL; /* point courant et point voisin */
  int	i,j; /* variables indices ligne et colonne du voisinage */
  int	moy; /* variable temporaire de type short */

  if(crea_POINT(point) == NULL) {
     fprintf(stderr,"Erreur d'Allocation Memoire du Point : Moyen \n");
     exit (0);
  }

  if(crea_POINT(pointv) == NULL) {
     fprintf(stderr,"Erreur d'Allocation Memoire du Point Voisin : Moyen \n");
     exit (0);
  }

  if(crea_POINT(pointv1) == NULL) {
     fprintf(stderr,"Erreur d'Allocation Memoire du Point Voisin : Moyen \n");
     exit (0);
  }

  if(crea_POINT(pointv2) == NULL) {
     fprintf(stderr,"Erreur d'Allocation Memoire du Point Voisin : Moyen \n");
     exit (0);
  }

  int tabVoisinR[9];
  int tabVoisinV[9];
  int tabVoisinB[9];

  int GxR, GyR, GdR, GiR, GxV, GyV, GdV, GiV, GxB, GyB, GdB, GiB, Gmax = 0, GmaxR = 0, GmaxV = 0, GmaxB = 0, ArgR, ArgV, ArgB, Arg;

    for(POINT_Y(point) = 1; POINT_Y(point) < NLIG(image) - 1; POINT_Y(point)++)
        for(POINT_X(point) = 1; POINT_X(point) < NCOL(image) - 1; POINT_X(point)++)
        {
             /*--Recuperation des valeurs du pixel courant dans une tableaux--*/
             int K = 0; //compteur dans tabVoisin
             /* --- Balayage Video du voisinage 3x3 --- */
             for(j = 0; j < 3; j++)
             for(i = 0; i < 3; i++)
             {
                 /* calcul des coordonnees absolues du point voisin */
                 POINT_X(pointv) = POINT_X(point) + i - 1;
                 POINT_Y(pointv) = POINT_Y(point) + j - 1;

                 tabVoisinR[K] = (int) PIXEL_R(image, pointv);
                 tabVoisinV[K] = (int) PIXEL_V(image, pointv);
                 tabVoisinB[K] = (int) PIXEL_B(image, pointv);

                 K++;
             } /* --- fin du balayage du voisinage --- */

             GxR, GyR, GdR, GiR, GxV, GyV, GdV, GiV, GxB, GyB, GdB, GiB = 0; /* initialisation des variables temporaires */

             //Calcul des normes//
             GxR = (-tabVoisinR[0] + tabVoisinR[2] - tabVoisinR[3] + tabVoisinR[5] - tabVoisinR[6] + tabVoisinR[8])/3;
             GyR = (-tabVoisinR[0] - tabVoisinR[1] - tabVoisinR[2] + tabVoisinR[6] + tabVoisinR[7] + tabVoisinR[8])/3;
             GdR = (-tabVoisinR[0] - tabVoisinR[1] - tabVoisinR[3] + tabVoisinR[5] + tabVoisinR[7] + tabVoisinR[8])/3;
             GiR = (+tabVoisinR[1] + tabVoisinR[2] - tabVoisinR[3] + tabVoisinR[5] - tabVoisinR[6] - tabVoisinR[7])/3;

             GxV = (-tabVoisinV[0] + tabVoisinV[2] - tabVoisinV[3] + tabVoisinV[5] - tabVoisinV[6] + tabVoisinV[8])/3;
             GyV = (-tabVoisinV[0] - tabVoisinV[1] - tabVoisinV[2] + tabVoisinV[6] + tabVoisinV[7] + tabVoisinV[8])/3;
             GdV = (-tabVoisinV[0] - tabVoisinV[1] - tabVoisinV[3] + tabVoisinV[5] + tabVoisinV[7] + tabVoisinV[8])/3;
             GiV = (+tabVoisinV[1] + tabVoisinV[2] - tabVoisinV[3] + tabVoisinV[5] - tabVoisinV[6] - tabVoisinV[7])/3;

             GxB = (-tabVoisinB[0] + tabVoisinB[2] - tabVoisinB[3] + tabVoisinB[5] - tabVoisinB[6] + tabVoisinB[8])/3;
             GyB = (-tabVoisinB[0] - tabVoisinB[1] - tabVoisinB[2] + tabVoisinB[6] + tabVoisinB[7] + tabVoisinB[8])/3;
             GdB = (-tabVoisinB[0] - tabVoisinB[1] - tabVoisinB[3] + tabVoisinB[5] + tabVoisinB[7] + tabVoisinB[8])/3;
             GiB = (+tabVoisinB[1] + tabVoisinB[2] - tabVoisinB[3] + tabVoisinB[5] - tabVoisinB[6] - tabVoisinB[7])/3;

             //Recuperation de la valeur absolue
             GxR = (GxR >= 0) ? GxR : -GxR;
             GyR = (GyR >= 0) ? GyR : -GyR;
             GdR = (GdR >= 0) ? GdR : -GdR;
             GiR = (GiR >= 0) ? GiR : -GiR;

             GxV = (GxV >= 0) ? GxV : -GxV;
             GyV = (GyV >= 0) ? GyV : -GyV;
             GdV = (GdV >= 0) ? GdV : -GdV;
             GiV = (GiV >= 0) ? GiV : -GiV;

             GxB = (GxB >= 0) ? GxB : -GxB;
             GyB = (GyB >= 0) ? GyB : -GyB;
             GdB = (GdB >= 0) ? GdB : -GdB;
             GiB = (GiB >= 0) ? GiB : -GiB;

             //Estimation de la norme correspondante (plus grande valeur)
             GmaxR = GxR;
             GmaxR = (GmaxR > GyR) ? GmaxR : GyR;
             GmaxR = (GmaxR > GdR) ? GmaxR : GdR;
             GmaxR = (GmaxR > GiR) ? GmaxR : GiR;

             GmaxV = GxV;
             GmaxV = (GmaxV > GyV) ? GmaxV : GyV;
             GmaxV = (GmaxV > GdV) ? GmaxV : GdV;
             GmaxV = (GmaxV > GiV) ? GmaxV : GiV;

             GmaxB = GxB;
             GmaxB = (GmaxB > GyB) ? GmaxB : GyB;
             GmaxB = (GmaxB > GdB) ? GmaxB : GdB;
             GmaxB = (GmaxB > GiB) ? GmaxB : GiB;

             if(GmaxR > GmaxV && GmaxR > GmaxB)
                Gmax = GmaxR;
             if(GmaxV > GmaxR && GmaxV > GmaxB)
                Gmax = GmaxV;
             if(GmaxB > GmaxR && GmaxB > GmaxV)
                Gmax = GmaxB;

            if(Gmax > 255)
                Gmax = 255;
            if(Gmax < 0)
                Gmax = 0;

             //affectation de la valeur du gradient max au pixel courant dans l'image norme
             PIXEL(imnorm, point) = (unsigned char)Gmax;

            if(Gmax == GmaxR) {
                 Arg = 0; //reinitiallisation de l'argument

                 if(Gmax == GxR) {
                    Arg = 0;
                 }
                 else if(Gmax == GyR) {
                    Arg = 6;
                 }
                 else if(Gmax == GdR) {
                    Arg = 1;
                 }
                 else  {
                    Arg = 7;
                 }
            }
            else if(Gmax == GmaxV) {
                 Arg = 0; //reinitiallisation de l'argument

                 if(Gmax == GxV) {
                    Arg = 0;
                 }
                 else if(Gmax == GyV) {
                    Arg = 6;
                 }
                 else if(Gmax == GdV) {
                    Arg = 1;
                 }
                 else  {
                    Arg = 7;
                 }
            }
            else {
                Arg = 0; //reinitiallisation de l'argument

                 if(Gmax == GxB) {
                    Arg = 0;
                 }
                 else if(Gmax == GyB) {
                    Arg = 6;
                 }
                 else if(Gmax == GdB) {
                    Arg = 1;
                 }
                 else  {
                    Arg = 7;
                 }
            }

            PIXEL(imarg, point) = (unsigned char) Arg;


         }/* --- fin du balayage de l'image --- */

        for(POINT_Y(point) = 1; POINT_Y(point) < NLIG(imnorm) - 1; POINT_Y(point)++)
            for(POINT_X(point) = 1; POINT_X(point) < NCOL(imnorm) - 1; POINT_X(point)++)
            {
                if(PIXEL(imnorm, point) > 70) //Valeur du pixel sur l'image seuillée
                {
                    /* Recherche des points voisins */
                    switch(PIXEL(imarg, point)) //Valeur du de l'image argument
                    {
                        case 0:
                            POINT_X(pointv1) = POINT_X(point) - 1; // Point voisin 1
                            POINT_Y(pointv1) = POINT_Y(point);
                            POINT_X(pointv2) = POINT_X(point) + 1; // Point voisin 2
                            POINT_Y(pointv2) = POINT_Y(point);
                        break;
                        case 6:
                            POINT_X(pointv1) = POINT_X(point);
                            POINT_Y(pointv1) = POINT_Y(point) - 1;
                            POINT_X(pointv2) = POINT_X(point);
                            POINT_Y(pointv2) = POINT_Y(point) + 1;
                        break;
                        case 1:
                            POINT_X(pointv1) = POINT_X(point) + 1;
                            POINT_Y(pointv1) = POINT_Y(point) - 1;
                            POINT_X(pointv2) = POINT_X(point) - 1;
                            POINT_Y(pointv2) = POINT_Y(point) + 1;
                        break;
                        case 7:
                            POINT_X(pointv1) = POINT_X(point) - 1;
                            POINT_Y(pointv1) = POINT_Y(point) - 1;
                            POINT_X(pointv2) = POINT_X(point) + 1;
                            POINT_Y(pointv2) = POINT_Y(point) + 1;
                        break;
                        default:
                            fprintf(stderr,"Erreur de code Argument\n");
                    }
                    /* fin de la recherche du point voisin */
                    /*Comparaison de la valeur des normes du gradient*/
                    if(PIXEL(imnorm,pointv1) > PIXEL(imnorm,point) || PIXEL(imnorm,pointv2) > PIXEL(imnorm,point))
                    {
                        PIXEL(imres,point)=0;
                    }
                    else
                    {
                        PIXEL(imres,point)=255;
                    }
                }
            }
  free((void *)pointv);/* --- liberation des zones memoire */
  free((void *)point);
} /* --- fin de l'operateur --- */
