/*
//
//  calcul des extrema locaux sur une image .pgm, en 8c
//  arguments :
//      le nom de l'image a traiter (format pgm)
//      eventuellement, le nom de l'image sauvegardee
//      (sinon on l'ecrit sur toto.pgm)
//      les minima locaux sont a 0
//      les maxima locaux sont a 255
//      le reste de l'image est a 128
*/

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

#define _pixel_non_extremum 128
#define _pixel_minimum 0
#define _pixel_maximum 255

void main(int argc, char *argv[]) 
{
  char *pImageEntree, *pImageSortie;
  short erreur;
  int i,j;
  int nbLignes;
  int nbColonnes;
  char pToto[9]="toto.pgm";
  
  if (argc<=1)
    printf("Il faut donner le nom de l'image en argument\n");
  else if (argc >= 2) {
    printf("lecture de l'image d'entree...\n");
    pImageEntree=loadpgm_alloc(argv[1],&erreur,&nbColonnes,&nbLignes);
    if (erreur) {
      switch(erreur){
      case 1: 
	printf("data transmission problem\n");
	break;
      case 2: 
	printf("memory alloocation error\n");
	break;
      case 3:
	printf("format error\n");
	break;
      case 4:
	printf("file problem\n");
	break;
      }
      exit;
    }
    else printf("lecture correcte de l'image en entree\n");

    /* traitements */
    
    pImageSortie=(char*)malloc((1+nbColonnes*nbLignes)*sizeof(char));

    /* calcul des extrema */
    /* cas des quatre pixels des coins */

    /* coin superieur gauche (0) */
    if ((pImageEntree[1]>pImageEntree[0]) && (pImageEntree[nbColonnes]>pImageEntree[0]))
      pImageSortie[0]= _pixel_minimum;
    else if ((pImageEntree[1]<pImageEntree[0]) && (pImageEntree[nbColonnes]<pImageEntree[0])) 
      pImageSortie[0]= _pixel_maximum;
    else pImageSortie[0]= _pixel_non_extremum;

    /* coin superieur droit (nbColonnes-1) */
    if ((pImageEntree[nbColonnes-2]>pImageEntree[nbColonnes-1]) && (pImageEntree[2*nbColonnes-1]>pImageEntree[nbColonnes-1]))
      pImageSortie[nbColonnes-1]= _pixel_minimum;
    else if ((pImageEntree[nbColonnes-2]<pImageEntree[nbColonnes-1]) && (pImageEntree[2*nbColonnes-1]<pImageEntree[nbColonnes-1])) 
      pImageSortie[nbColonnes-1]= _pixel_maximum;
    else pImageSortie[nbColonnes-1]= _pixel_non_extremum;

    /* coin inferieur gauche ((nbLignes-1)*nbColonnes) */
    if ((pImageEntree[1+(nbLignes-1)*nbColonnes]>pImageEntree[(nbLignes-1)*nbColonnes]) && (pImageEntree[(nbLignes-2)*nbColonnes]>pImageEntree[(nbLignes-1)*nbColonnes]))
      pImageSortie[(nbLignes-1)*nbColonnes]= _pixel_minimum;
    else if ((pImageEntree[1+(nbLignes-1)*nbColonnes]<pImageEntree[(nbLignes-1)*nbColonnes]) && (pImageEntree[(nbLignes-2)*nbColonnes]<pImageEntree[(nbLignes-1)*nbColonnes])) 
      pImageSortie[(nbLignes-1)*nbColonnes]= _pixel_maximum;
    else pImageSortie[(nbLignes-1)*nbColonnes]= _pixel_non_extremum;

    /* coin inferieur droit (nbLignes*nbColonnes-1) */
    if ((pImageEntree[nbLignes*nbColonnes-2]>pImageEntree[nbLignes*nbColonnes-1]) && (pImageEntree[(nbLignes-1)*nbColonnes-1]>pImageEntree[nbLignes*nbColonnes-1]))
      pImageSortie[nbLignes*nbColonnes-1]= _pixel_minimum;
    else if ((pImageEntree[nbLignes*nbColonnes-2]<pImageEntree[nbLignes*nbColonnes-1]) && (pImageEntree[(nbLignes-1)*nbColonnes-1]<pImageEntree[nbLignes*nbColonnes-1])) 
      pImageSortie[nbLignes*nbColonnes-1]= _pixel_maximum;
    else pImageSortie[nbLignes*nbColonnes-1]= _pixel_non_extremum;
    
    /* cas des premieres et dernieres lignes */
    /* la premiere ligne */
    for (i=1;i<nbColonnes-1;i++) {
      if ((pImageEntree[i-1]>pImageEntree[i]) && (pImageEntree[i+1]>pImageEntree[i]) && (pImageEntree[i+nbColonnes]>pImageEntree[i]))
	pImageSortie[i]=_pixel_minimum;
      else if ((pImageEntree[i-1]<pImageEntree[i]) && (pImageEntree[i+1]<pImageEntree[i]) && (pImageEntree[i+nbColonnes]<pImageEntree[i]))
	pImageSortie[i]=_pixel_maximum;
      else pImageSortie[i]=_pixel_non_extremum;
    }

    /* la derniere ligne */
    for (i=1+(nbLignes-1)*nbColonnes;i<nbLignes*nbColonnes-2;i++) {
      if ((pImageEntree[i-1]>pImageEntree[i]) && (pImageEntree[i+1]>pImageEntree[i]) && (pImageEntree[i-nbColonnes]>pImageEntree[i]))
	pImageSortie[i]=_pixel_minimum;
      else if ((pImageEntree[i-1]<pImageEntree[i]) && (pImageEntree[i+1]<pImageEntree[i]) && (pImageEntree[i-nbColonnes]<pImageEntree[i]))
	pImageSortie[i]=_pixel_maximum;
      else pImageSortie[i]=_pixel_non_extremum;
    }
    
    /* cas general */

    for (i=nbColonnes;i<(nbLignes-1)*nbColonnes;i+=nbColonnes) {
      /* cas du premier point de la ligne */
      if ((pImageEntree[i-nbColonnes]>pImageEntree[i]) && (pImageEntree[i+1]>pImageEntree[i]) && (pImageEntree[i+nbColonnes]>pImageEntree[i]))
	pImageSortie[i]=_pixel_minimum;
      else if ((pImageEntree[i-nbColonnes]<pImageEntree[i]) && (pImageEntree[i+1]<pImageEntree[i]) && (pImageEntree[i+nbColonnes]<pImageEntree[i]))
	pImageSortie[i]=_pixel_maximum;
      else pImageSortie[i]=_pixel_non_extremum;
      
      /* cas du dernier point de la ligne */
      if ((pImageEntree[i-1]>pImageEntree[i+nbColonnes-1]) && (pImageEntree[i-1+2*nbColonnes]>pImageEntree[i+nbColonnes-1]) && (pImageEntree[i+nbColonnes-2]>pImageEntree[i+nbColonnes-1]))
	pImageSortie[i+nbColonnes-1]=_pixel_minimum;
      else if ((pImageEntree[i-1]<pImageEntree[i+nbColonnes-1]) && (pImageEntree[i-1+2*nbColonnes]<pImageEntree[i+nbColonnes-1]) && (pImageEntree[i+nbColonnes-2]<pImageEntree[i+nbColonnes-1]))
	pImageSortie[i+nbColonnes-1]=_pixel_maximum;
      else pImageSortie[i+nbColonnes-1]=_pixel_non_extremum;
      
      /* cas des points centraux */
      for (j=1;j<nbColonnes-1;j++){
	if ((pImageEntree[i+j-1]>pImageEntree[i+j]) && (pImageEntree[i+j+1]>pImageEntree[i+j]) && (pImageEntree[i+j+nbColonnes]>pImageEntree[i+j]) && (pImageEntree[i+j-nbColonnes]>pImageEntree[i+j]) && (pImageEntree[i+j-1-nbColonnes]>pImageEntree[i+j]) && (pImageEntree[i+j-1+nbColonnes]>pImageEntree[i+j]) && (pImageEntree[i+j+1+nbColonnes]>pImageEntree[i+j]) && (pImageEntree[i+j+1-nbColonnes]>pImageEntree[i+j]))
	  pImageSortie[i+j]=_pixel_minimum;
	else { 
	  if ((pImageEntree[i+j-1]<pImageEntree[i+j]) && (pImageEntree[i+j+1]<pImageEntree[i+j]) && (pImageEntree[i+j+nbColonnes]<pImageEntree[i+j]) && (pImageEntree[i+j-nbColonnes]<pImageEntree[i+j]) && (pImageEntree[i+j-1-nbColonnes]<pImageEntree[i+j]) && (pImageEntree[i+j-1+nbColonnes]<pImageEntree[i+j]) && (pImageEntree[i+j+1+nbColonnes]<pImageEntree[i+j]) && (pImageEntree[i+j+1-nbColonnes]<pImageEntree[i+j]))
	    pImageSortie[i+j]=_pixel_maximum;
	  else pImageSortie[i+j]=_pixel_non_extremum;
	}
      }
    }
    
    /* fin des traitements */
    
    printf("ecriture de l'image en sortie...\n");
    if (argc>2)
      savepgm(pImageSortie,argv[2],&erreur,nbColonnes,nbLignes);
    else 
      savepgm(pImageSortie,pToto,&erreur,nbColonnes,nbLignes);
    if (erreur) {
      switch(erreur){
      case 1: 
	printf("data transmission problem\n");
	break;
      case 2: 
	printf("memory alloocation error\n");
	break;
      case 3:
	printf("format error\n");
	break;
      case 4:
	printf("file problem\n");
	break;
      }
      exit;
    }
    else printf("ecriture correcte de l'image en sortie\n");
  }
}

