#include <stdlib.h>
#include <math.h>
#include <values.h>
#include <time.h>
#include "image.h"
#include "canal.h"
#include "grille.h"
#include "visu.h"
//#include "e.h"
#include "r.h"
#include "c.h"
#include "fourier.h"
//#include "img.h"

#define pi   3.1415926535897931160E0



/*-------------------------------------------------------------------------*/


typedef struct p
	{
	int			xcoord;
	int			ycoord;
	struct p  * pt;
	} poin ;
static poin   *	tete, *queue, *poi;
static void		Empiler ( int x, int y );
static poin   * Depiler ( void );


 static void Empiler ( int x, int y )
/***********************************/

{
 poin	*	ptemp;

 ptemp            = calloc(1,sizeof(poin));
 ptemp -> xcoord  = x;
 ptemp -> ycoord  = y;
 ptemp -> pt      = NULL;
 if (tete == NULL)
      tete = ptemp;
 else
	  queue -> pt = ptemp;
 queue       = ptemp;
}


 static poin  * Depiler ( void )
/******************************/

{
 poin  *ptdep, *pt1, *pt2;

 ptdep = NULL;
 if (tete != NULL)
      {
      pt1 = tete;
      pt2 = pt1 -> pt;
      if (pt2 == NULL)
	   {
           ptdep = tete;
           tete  = NULL;
	   queue = NULL;
           }
      else
           {
           while (pt2 != queue)
		{
		pt1 = pt2;
                pt2 = pt2 -> pt;
                }
           queue    = pt1;
           ptdep     = pt2;
           pt1 -> pt = NULL;
           }
      }
 return(ptdep);
}



static Image MoyenneMasqueR (Image imaS,Image masque,float seuil,float *mu)
/*************************************************************************/
{
int		x,y,i,j;
long int	n=0;
Reel		*valS,*valM;
Canal		canS,canM;

if ((masque=CreeImageDest(imaS,masque,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imaS,&x, &y);
if ((valS=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((valM=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canS=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canM=CreeCanal(masque,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

*mu=0;
for (i=0;i<y;i++)
	{
	LitCanal(canS,valS);
	LitCanal(canM,valM);
	for (j=0;j<x;j++)
		if (valM[j]>=seuil)
			{
			(*mu)+=valS[j];
			n++;
                        }
	}
if (n==0) return(NULL);
(*mu)/=n;
LibereCanal(canS);
LibereCanal(canM);
free(valS);
free(valM);
return(masque);
}

/*-------------------------------------------------------------------------*/


Image SeuilleInfR(Image imS,Image imD,Reel vinf,Reel val)
/******************************************************/
{
int x,y,i,j;
Canal canL;
Reel *valeur;
Reel **grille;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imD,&x,&y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

for(i=0;i<y;i++)
	{
	LitCanal(canL,valeur);
	for (j=0;j<x;j++)
		{
		if (valeur[j]<=vinf) grille[i][j]=val;
		else grille[i][j]=valeur[j];
		}
	 }
LibereGrille(grille);
LibereCanal(canL);
free(valeur);
return(imD);
}

Image SeuilleSupR(Image imS,Image imD,Reel vsup,Reel val)
/******************************************************/
{
int x,y,i,j;
Canal canL;
Reel *valeur;
Reel **grille;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imD,&x,&y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

for(i=0;i<y;i++)
	{
	LitCanal(canL,valeur);
	for (j=0;j<x;j++)
		{
		if (vsup<valeur[j]) grille[i][j]=val;
		else grille[i][j]=valeur[j];
		}
	 }
LibereGrille(grille);
LibereCanal(canL);
free(valeur);
return(imD);
}

Image SeuilleInterR(Image imS,Image imD,Reel v1,Reel v2,Reel val)
/**************************************************************/

{
int x,y,i,j;
Canal canL;
Reel *valeur,v;
Reel **grille;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imD,&x,&y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

for(i=0;i<y;i++)
	{
	LitCanal(canL,valeur);
	for (j=0;j<x;j++)
		{
		  v=valeur[j];
		if ((v1<v)&&(v<=v2)) grille[i][j]=val;
		else grille[i][j]=valeur[j];
		}
	 }
LibereGrille(grille);
LibereCanal(canL);
free(valeur);
return(imD);
}

Image TransfereR(Image imS, Image imD)
/************************************/

{
Canal canL,canE;
Reel *valeur;
int x,y,i;

if ( (imD=CreeImageDest(imS, imD, T_REEL))==NULL) return(NULL);

if (imD==imS) return(imD);

LitTailleFenetre(imD,&x, &y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
   {
   LitCanal(canL, valeur);
   EcritCanal(canE, valeur);
   }

LibereCanal(canE);
LibereCanal(canL);
free(valeur);
return (imD) ;
}


Image NiveauR(Image imS, Image imD, Reel valeur)
/**********************************************/

{
Canal canE;
Reel *tampon;
int x,y,i;

if ( (imD=CreeImageDest(imS, imD, T_REEL))==NULL) return(NULL);

LitTailleFenetre(imD,&x, &y);
if ((tampon=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canE=CreeCanal(imD, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

for (i=0;i<x;i++) tampon[i]=valeur;
for (i=0;i<y;i++) EcritCanal(canE,tampon);

LibereCanal(canE);
free(tampon);
return(imD);
}


int MoyenneR(Image imS, Reel *moy)
/********************************/

{
Canal canL;
Reel *tampon;
ReelL aux;
int x,y,i,j;

if (imS==NULL) return(1);

LitTailleFenetre(imS,&x, &y);
if ((tampon=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

aux=0;
for (i=0;i<y;i++)
    {
    LitCanal(canL,tampon);
    for (j=0;j<x;j++) aux+=tampon[j];
    }
*moy=(float)(aux/((long)x*y));

LibereCanal(canL);
free(tampon);
return(0);
}


int MinMaxR(Image imS, Reel *min, Reel *max)
/******************************************/

{
Canal canL;
Reel *valeur;
int x,y,i,j;

if (imS==NULL) return(1);

LitTailleFenetre(imS,&x, &y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(1);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(1);

LitCanal(canL, valeur);
*min=*max=*valeur;
for (i=0;i<y-1;i++)
    {
    for (j=0;j<x;j++)
        {
        if (valeur[j]>*max) *max=valeur[j];
        if (valeur[j]<*min) *min=valeur[j];
        }
    LitCanal(canL, valeur);
    }
for (j=0;j<x;j++)
        {
        if (valeur[j]>*max) *max=valeur[j];
        if (valeur[j]<*min) *min=valeur[j];
        }

LibereCanal(canL);
free(valeur);
return (0);
}


Image EtaleR(Image imS, Image imD, Reel min, Reel max)
/****************************************************/

{
Canal canL,canE;
Reel *valeur,mini,maxi,a,b;
int x,y,i,j;

if ( (imD=CreeImageDest(imS, imD, T_REEL))==NULL) return(NULL);

LitTailleFenetre(imD,&x, &y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

MinMaxR(imS, &mini, &maxi);
if (mini==maxi)
	{
   a=0;
   b=min;
   }
else
	{
   a=(max-min)/(maxi-mini);
	b=min-a*mini;
   }

for (i=0;i<y;i++)
   {
   LitCanal(canL, valeur);
   for (j=0;j<x;j++) valeur[j]=valeur[j]*a+b;
   EcritCanal(canE, valeur);
   }

LibereCanal(canE);
LibereCanal(canL);
free(valeur);
return (imD) ;
}


Image EcreteR(Image imaS,Image imaD,int sup,Reel crete)
/*****************************************************/
{
int	  	  i,j,x,y;
Reel   *  valeur,** grilleD;
Canal     canL;

if ((imaD=CreeImageDest(imaS, imaD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imaS,&x,&y);
if ((valeur=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return(NULL);

if (sup)
	for(i=0;i<y;i++)
		{
		LitCanal(canL,valeur);
		for(j=0;j<x;j++)
			if (valeur[j]>crete) grilleD[i][j]=crete;
			 else                grilleD[i][j]=valeur[j];
		}
 else
	for(i=0;i<y;i++)
		{
		LitCanal(canL,valeur);
		for(j=0;j<x;j++)
			if (valeur[j]<crete) grilleD[i][j]=crete;
			 else                grilleD[i][j]=valeur[j];
		}

LibereGrille(grilleD);
free(valeur);
LibereCanal(canL);

return(imaD);
}



Image DecaleR(Image imS, Image imD, int dx, int dy)
/*************************************************/

{
int i,j,x,y;
Canal canL, canE;
Reel *valL, *valE;
Reel ** grille;

if ( (imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);

if ( (valL=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ( (valE=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ( (canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ( (canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ( (grille=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

dx=(x+dx%x)%x;
dy=(y+dy%y)%y;

if (dx>=0)
    for (i=0;i<y;i++)
        {
        LitCanal(canL,valL);
        for (j=0;j<dx;j++) valE[j]=valL[x+j-dx];
        for (j=dx;j<x;j++) valE[j]=valL[j-dx];
        EcritCanal(canE,valE);
		  }
if (y>x)
    if ( (valL=(Reel*)realloc(valL,y*sizeof(Reel)))==NULL) return(NULL);

if (dy>=0)
    for (j=0;j<x;j++)
        {
        for (i=0;i<y;i++) valL[i]=grille[i][j];
        for (i=0;i<dy;i++) grille[i][j]=valL[y+i-dy];
        for (i=dx;i<x;i++) grille[i][j]=valL[i-dy];
        }

LibereGrille(grille);
LibereCanal(canE);
LibereCanal(canL);
free(valE);
free(valL);

return(imD);
}



Image ExtraitFenetreR(Image imS, Image imD)
/*****************************************/

{
int i,x,y;
Canal canL,canE;
Reel *val;

if (imS==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);

if ((imD=CreeImageSimple(imD,T_REEL,imS->visu,x,y))==NULL) return(NULL);
if (imS->lut!=NULL) if (EcritLut(imD,imS->lut->taille,imS->lut->table)) return(NULL);

if ((val=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL,val);
    EcritCanal(canE,val);
    }


LibereCanal(canE);
LibereCanal(canL);
free(val);
return(imD);
}

Image PlaceFenetreR(Image imS1,Image imS2,Image imD,int taille,Reel seuil)
/************************************************************************/
{
Image imT=NULL;
Reel max,smax,min;
Point pMin,pMax;
int x,y,ox,oy,tx,ty,ts2,ox0,oy0,tx0,ty0;
FenetreL fen;

if (imD==NULL) imD=TransfereR(imS1,NULL);
LitFenetre(imS1,&ox,&oy,&tx,&ty);
LitFenetre(imS2,&ox0,&oy0,&tx0,&ty0);
EcritFenetre(imS2,ox,oy,tx,ty);
imT=ExtraitFenetreR(imS2,imT);
EcritFenetre(imS2,ox0,oy0,tx0,ty0);
PosMinMaxR(imT,&pMin,&pMax,&min,&max);
smax=seuil;
ts2=taille/2;

while(max>smax)
	{
	x=pMax.x+ox-ts2;
	y=pMax.y+oy-ts2;
	if (x<ox) x=ox;
	if (y<oy) y=oy;
	if (x+taille>ox+tx) x=ox+tx-taille;
	if (y+taille>oy+ty) y=oy+ty-taille;
	fen=(FenetreL)calloc(1,sizeof(Fenetre));
	fen->origine.x=x;
	fen->origine.y=y;
	fen->taille.x=taille;
	fen->taille.y=taille;
	InsereFenetreL(&imD->fenetreL,fen,0);
	EcritFenetre(imT,x-ox,y-oy,taille,taille);
	NiveauR(imT,imT,smax);
	EcritFenetre(imT,0,0,tx,ty);
	PosMinMaxR(imT,&pMin,&pMax,&min,&max);
	}
LibereImage(imT);
return(imD);
}

Image IntersecteR(Image imS1,Image imS2,Image imD)
/************************************************/
{
int i,j,x,y;
Canal canL1, canL2, canE;
Reel *val1,*val2;

if (TesteFenetre(imS1,imS2)) return(NULL);
if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS1,&x,&y);
if ((val1=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((val2=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
	 {
	 LitCanal(canL1,val1);
	 LitCanal(canL2,val2);
	for (j=0;j<x;j++) val1[j]=val1[j]*(Reel)(val1[j]==val2[j]);
	 EcritCanal(canE,val1);
	}

LibereCanal(canE);
LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(imD);
}


Image AbsR(Image imS, Image imD)
/******************************/

{
int i,j,x,y;
Canal canL,canE;
Reel *valeur;

if ( (imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);

if ( (valeur=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
   {
   LitCanal(canL, valeur);
   for (j=0;j<x;j++) valeur[j]=fabs(valeur[j]);
   EcritCanal(canE, valeur);
   }

LibereCanal(canE);
LibereCanal(canL);
free(valeur);
return (imD) ;
}



Image AddR(Image imS1, Image imS2, Image imD)
/*******************************************/

{
int i,j,x,y;
Canal canL1, canL2, canE;
Reel *val1,*val2;

if (TesteFenetre(imS1,imS2)) return(NULL);
if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS1,&x,&y);
if ((val1=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((val2=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL1,val1);
    LitCanal(canL2,val2);
    for (j=0;j<x;j++) val1[j]+=val2[j];
    EcritCanal(canE,val1);
     }

LibereCanal(canE);
LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(imD);
}


Image MaxR(Image imS1, Image imS2, Image imD)
/*******************************************/

{
int i,j,x,y;
Canal canL1, canL2, canE;
Reel *val1,*val2, v1,v2;

if (TesteFenetre(imS1,imS2)) return(NULL);
if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS1,&x,&y);
if ((val1=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((val2=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL1,val1);
    LitCanal(canL2,val2);
    for (j=0;j<x;j++)
        {
        v1=val1[j];
        v2=val2[j];
        if (v1>v2) val1[j]=v1;
        else val1[j]=v2;
        }
     EcritCanal(canE,val1);
     }

LibereCanal(canE);
LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(imD);
}


Image ExtraitDroiteR(Image imS, Image imD, int x1, int y1, int x2, int y2)
/************************************************************************/

{
int x, y, dx, d2x, dy, d2y, s1, s2, aux, e, interchange = 0;
int xs,ys,n;
Reel **grille, *ptr;
Canal canL;

if (imS==NULL) return(NULL);
LitTailleImage(imS,&xs,&ys);
if ( (x1<0) || (x1>xs) || (y1<0) || (y1>ys) ) return(NULL);
if ( (x2<0) || (x2>xs) || (y2<0) || (y2>ys) ) return(NULL);

dx = abs (x2-x1);
dy = abs (y2-y1);
s1 = (x2>x1) ? 1 : ((x2<x1) ? -1 : 0);
s2 = (y2>y1) ? 1 : ((y2<y1) ? -1 : 0);
x = x1;
y = y1;


 if (dy > dx)
  {
   aux = dx;
   dx = dy;
   dy = aux;
   interchange = 1;
  }

 d2x = 2*dx;
 d2y = 2*dy;
 e = d2y-dx;

 n=dx+1;

 if ((imD=CreeImageSimple(imD,T_REEL,V_COURBE,n,1))==NULL) return(NULL);

 if ((grille=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
 if ((canL=CreeCanal(imS,T_REEL,B_POINT,Z_IMAGE))==NULL) return(NULL);
 ptr=*grille;

 if (interchange)
  {

   if (s2 >0)
    {
      for (y=y1; y<=y2; y++)
        {

    PoseCanal(canL,x,y);
    LitCanal(canL,ptr++);
    if (e >= 0)
     {
      x += s1;
      e -= d2x;
     }
   e += d2y;

       }
    }
   else  for (y=y1; y>=y2; y--)
        {

    PoseCanal(canL,x,y);
    LitCanal(canL,ptr++);
    if (e >= 0)
     {
      x += s1;
      e -= d2x;
     }
   e += d2y;

        }
 }
 else {

       if (s1>0)  for (x=x1; x<=x2; x++)
                       {

      PoseCanal(canL,x,y);
      LitCanal(canL,ptr++);
      if (e >= 0)
       {
        y += s2;
        e -= d2x;
       }
      e += d2y;

                       }
       else for (x=x1; x>=x2; x--)
                        {

             PoseCanal(canL,x,y);
             LitCanal(canL,ptr++);
      if (e >= 0)
       {
        y += s2;
        e -= d2x;
       }
      e += d2y;

                        }
      }

LibereCanal(canL);
LibereGrille(grille);

return(imD);
}



Image ModuleR(Image imS, Image imD)
/*********************************/

{
Canal canL,canE;
Complexe *valeur,*pval;
Reel *val;
int x,y,i,j;

if ( (imD=CreeImageDest(imS, imD, T_REEL))==NULL) return(NULL);
if ( (imS->type==T_COMPLEXEL) || (imS->type==T_COMPLEXE) ||
     (imS->type==T_COULEUR) )
    {
    LitTailleFenetre(imD,&x, &y);
    if ((valeur=(Complexe *)calloc(x,sizeof(Complexe)))==NULL) return(NULL);
    if ((val=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
    if ((canL=CreeCanal(imS, T_COMPLEXE, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
    if ((canE=CreeCanal(imD, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

    for (i=0;i<y;i++)
       {
       LitCanal(canL, valeur);
       pval = valeur;
       for (j=0;j<x;j++)
           {
           val[j]=(float)(sqrt(pval->x*pval->x + pval->y*pval->y));
           pval++;
           }
       EcritCanal(canE, val);
       }

   LibereCanal(canE);
   LibereCanal(canL);
   free(val);
   free(valeur);
   }
else imD=AbsR(imS,imD);

return(imD);
}


Image PhaseR(Image imS, Image imD)
/********************************/

{
Canal canL,canE;
Complexe *valeur;
Reel *val, aux;
int x,y,i,j;

if ((imD = CreeImageDest(imS, imD, T_REEL)) == NULL) return(NULL);

LitTailleFenetre(imD,&x, &y);
if ((valeur=(Complexe *)calloc(x,sizeof(Complexe)))==NULL) return(NULL);
if ((val=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_COMPLEXE, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
     {
     LitCanal(canL, valeur);
     for (j=0;j<x;j++)
          {
          aux = valeur[j].x;
          if (aux!=0)
               if (aux > 0)
                    val[j] = atan (valeur[j].y / aux);
               else
                    if (valeur[j].y >= 0)
                         val[j] = atan (valeur[j].y / aux) + pi;
                    else
                         val[j] = atan (valeur[j].y / aux) - pi;
          else
               if (valeur[j].y > 0)
                    val[j] = pi/2.;
               else
                    if (valeur[j].y < 0)
                         val[j] = -pi/2;
                    else val[j] = 0;
          }
     EcritCanal(canE, val);
     }

LibereCanal(canE);
LibereCanal(canL);
free(val);
free(valeur);

return (imD) ;
}




Image ImagR(Image imS, Image imD)
/*******************************/

{
Canal canL;
Complexe *valeur,*pval;
Reel **grille;
int x,y,i,j;

if ( (imD=CreeImageDest(imS, imD, T_REEL))==NULL) return(NULL);

LitTailleFenetre(imD,&x, &y);
if ((valeur=(Complexe *)calloc(x,sizeof(Complexe)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_COMPLEXE, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((grille=(Reel**)CreeGrille(imD, Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
	{
    LitCanal(canL, valeur);
    pval = valeur;
    for (j=0;j<x;j++) grille[i][j]=(pval++)->y;
    }

LibereGrille(grille);
LibereCanal(canL);
free(valeur);
return(imD);
}



Image ConstAddR(Image imS, Image imD, Reel cte)
/*********************************************/

{
int i,j,x,y;
Canal canL,canE;
Reel *val;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS,&x,&y);
if ((val=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL,val);
    for (j=0;j<x;j++) val[j]+=cte;
    EcritCanal(canE,val);
     }

LibereCanal(canE);
LibereCanal(canL);
free(val);
return(imD);
}



Image ConstMultR(Image imS, Image imD, Reel cte)
/**********************************************/

{
int i,j,x,y;
Canal canL,canE;
Reel *val;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS,&x,&y);
if ((val=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL,val);
    for (j=0;j<x;j++) val[j]*=cte;
    EcritCanal(canE,val);
     }

LibereCanal(canE);
LibereCanal(canL);
free(val);
return(imD);
}



Image SoustrR(Image imS1, Image imS2, Image imD)
/**********************************************/

{
int i,j,x,y;
Canal canL1, canL2, canE;
Reel *val1,*val2;

if (TesteFenetre(imS1,imS2)) return(NULL);
if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS1,&x,&y);
if ((val1=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((val2=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL1,val1);
    LitCanal(canL2,val2);
    for (j=0;j<x;j++) val1[j]-=val2[j];
    EcritCanal(canE,val1);
     }

LibereCanal(canE);
LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(imD);
}


Image MultR(Image imS1, Image imS2, Image imD)
/********************************************/

{
int i,j,x,y;
Canal canL1, canL2, canE;
Reel *val1,*val2;

if (TesteFenetre(imS1,imS2)) return(NULL);
if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS1,&x,&y);
if ((val1=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((val2=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL1,val1);
    LitCanal(canL2,val2);
    for (j=0;j<x;j++) val1[j]*=val2[j];
    EcritCanal(canE,val1);
     }

LibereCanal(canE);
LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(imD);
}




Image DivR(Image imS1, Image imS2, Image imD)
/*******************************************/

{
int i,j,x,y;
Canal canL1, canL2, canE;
Reel *val1,*val2;

if (TesteFenetre(imS1,imS2)) return(NULL);
if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS1,&x,&y);
if ((val1=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((val2=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL1,val1);
    LitCanal(canL2,val2);
    for (j=0;j<x;j++) val1[j] = val2[j]!=0 ? val1[j]/val2[j] : MAXFLOAT;
    EcritCanal(canE,val1);
     }

LibereCanal(canE);
LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(imD);
}



Image SqRtR(Image imS,Image imD)
/******************************/
{
int 	i,j,x,y;
Reel 	*valS,**grilleD;
Canal 	canS;


if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);
if ((valS=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canS=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canS,valS);
    for (j=0;j<x;j++)
		if (valS[j]>=0) grilleD[i][j]=(float)(sqrt(valS[j]));
		 else grilleD[i][j]=-1;
    }

LibereGrille(grilleD);
LibereCanal(canS);
free(valS);
return(imD);
}



Image CarreR(Image imS,Image imD)
/*******************************/
{
int 	i,j,x,y;
Reel 	*valS,**grilleD;
Canal 	canS;


if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);
if ((valS=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canS=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canS,valS);
    for (j=0;j<x;j++)
		grilleD[i][j]=valS[j]*valS[j];
    }

LibereGrille(grilleD);
LibereCanal(canS);
free(valS);
return(imD);
}



Image UnSurR(Image imS, Image imD)
/********************************/

{
int i,j,x,y;
Canal canL,canE;
Reel *val;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS,&x,&y);
if ((val=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL,val);
    for (j=0;j<x;j++) val[j]= val[j]!=0 ? 1/val[j] : MAXFLOAT;
    EcritCanal(canE,val);
     }

LibereCanal(canE);
LibereCanal(canL);
free(val);
return(imD);
}


Image LogR(Image imS, Image imD)
/******************************/

{
int i,j,x,y;
Canal canL,canE;
Reel *val;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS,&x,&y);
if ((val=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
    {
    LitCanal(canL,val);
    for (j=0;j<x;j++)
        if (val[j]>0) val[j]=(float)(log(val[j]));
        else val[j]=-MAXFLOAT;
    EcritCanal(canE,val);
     }

LibereCanal(canE);
LibereCanal(canL);
free(val);
return(imD);
}



Image ExpR(Image imS, Image imD)
/******************************/

{
int i,j,x,y;
Canal canL,canE;
Reel *val,borne;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imS,&x,&y);
if ((val=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
borne=log(MAXFLOAT);
for (i=0;i<y;i++)
	 {
	 LitCanal(canL,val);
	 for (j=0;j<x;j++)
		{
		if (val[j]<borne)	val[j]=(float)(exp(val[j]));
		else val[j]=MAXFLOAT;
      }
	 EcritCanal(canE,val);
	  }

LibereCanal(canE);
LibereCanal(canL);
free(val);
return(imD);
}

Image Norme1R(Image imS,Image imD)
/********************************/
{
Canal canL;
Reel *tampon,**grilleD;
ReelL norme1;
int x,y,i,j;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);
if ((tampon=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

norme1=0;
for (i=0;i<y;i++)
	 {
	LitCanal(canL,tampon);
	for (j=0;j<x;j++)
		norme1+=fabs(tampon[j]);
	 }
if (norme1==0) return(NULL);

PoseCanal(canL,0,0);
for (i=0;i<y;i++)
	{
	LitCanal(canL,tampon);
	for (j=0;j<x;j++) grilleD[i][j]=tampon[j]/norme1;
	 }

LibereGrille(grilleD);
LibereCanal(canL);
free(tampon);
return(imD);
}


Image Norme2R(Image imS,Image imD)
/********************************/
{
Canal canL;
Reel *tampon,**grilleD;
ReelL norme2,val;
int x,y,i,j;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imS,&x,&y);
if ((tampon=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

norme2=0;
for (i=0;i<y;i++)
	 {
	LitCanal(canL,tampon);
	for (j=0;j<x;j++)
		{
		val=tampon[j];
		norme2+=val*val;
		  }
	 }
if ((norme2=sqrt(norme2))==0) return(NULL);

PoseCanal(canL,0,0);
for (i=0;i<y;i++)
	{
	LitCanal(canL,tampon);
	for (j=0;j<x;j++) grilleD[i][j]=tampon[j]/norme2;
	 }

LibereGrille(grilleD);
LibereCanal(canL);
free(tampon);
return(imD);
}


Image CepstreR(Image imS,Image imD)
/*********************************/
{
Image imC;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
if ((imC=ExtraitFenetreC(imS,NULL))==NULL) return(NULL);
TFRDirecteC(imC,imC);
ModuleR(imC,imD);
LogR(imD,imD);


/*EcreteR(imD,imD,0,);*/
FermeNR(imD,imD,1);

AlterneSigneC(imD,imC);
TFRInverseC(imC,imC);
TransfereR(imC,imD);
LibereImage(imC);
return(imD);
}


Image HistoR (Image imaS,Image imaD,Reel min,Reel max,Reel l)
/***********************************************************/
{
int		i,j,k,x,y;
Entier	nbClasses;
Canal   canL;
Reel  *	valeur,** grille,n=0,eMin,eMax;


if ((imaS==NULL) || (l<=0.) || (max<min)) return(NULL);
LitTailleFenetre(imaS,&x,&y);
if ((canL=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((valeur=(Reel*)calloc(x,sizeof(Reel)))==NULL) return(NULL);

if ((nbClasses=(Entier)ceil((max-min)/l)) == 0) nbClasses=1;
max=min+nbClasses*l;

if ((imaD!=NULL)&&(imaD->visu!=V_HISTO)) return (NULL);
if ((imaD=CreeImageSimple(imaD,T_REEL,V_HISTO,nbClasses,1))==NULL) return(NULL);
NiveauR(imaD,imaD,0);
if ((grille=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return(NULL);

for(i=0;i<y;i++)
	{
	LitCanal(canL,valeur);
	for(j=0;j<x;j++)
		if ( (valeur[j]>=min)&&(valeur[j]<max) )
        	{
			k=(valeur[j]-min)/l;
			grille[0][k]++;
            n++;
            }                             
	}

if (n)
	for (k=0;k<nbClasses;k++)
		grille[0][k]/=n;

LibereGrille(grille);
free(valeur);
LibereCanal(canL);

MinMaxR(imaD,&eMin,&eMax);
if ((imaD->info=(char *)CreeInfoHisto(C_X,eMin,eMax,E_LIN,min,max,n))==NULL) return(NULL);

return(imaD);
}



int Moment4R(Image imS,Reel * mom1,Reel * mom2,Reel * mom3,Reel * mom4)
/*********************************************************************/
{
int    	x,y,i,j;
Canal  	canL;
Reel	eType;
ReelL * valeur,
	som1=0.,som2=0.,som3=0.,som4=0.,n,moy1,moy2,moy3,moy4;

if (imS==NULL) return(1);
LitTailleFenetre(imS,&x,&y);
n=(ReelL)x*(ReelL)y;
if (n<=1) return (NULL);
if ((valeur=(ReelL *)calloc(x,sizeof(ReelL)))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REELL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
	 {
	 LitCanal(canL,valeur);
	 for (j=0;j<x;j++)
	{
	som1+=valeur[j];
	som2+=valeur[j]*valeur[j];
	som3+=valeur[j]*valeur[j]*valeur[j];
	som4+=valeur[j]*valeur[j]*valeur[j]*valeur[j];
		  }
	 }

*mom1=(Reel)( som1/n );
moy1=*mom1;
moy2=moy1*moy1;
moy3=moy1*moy1*moy1;
moy4=moy1*moy1*moy1*moy1;
*mom2=(Reel)( (som2-2.*moy1*som1+n*moy2)/(n-1.) );
*mom3=(Reel)( (som3-3.*moy1*som2+3.*moy2*som1-n*moy3)/n );
*mom4=(Reel)( (som4-4.*moy1*som3+6.*moy2*som2-4.*moy3*som1+n*moy4)/n );

/* moments centrés adimensionnés d'ordre 3 et 4 */
eType=(Reel)sqrt((double)(*mom2));
if (*mom2!=0) *mom4/=((*mom2)*(*mom2));
else *mom4=MAXFLOAT;
if ((*mom2)*eType!=0 ) *mom3/=((*mom2)*eType);
else *mom3=MAXFLOAT;
*mom2=eType /* /(*mom1) */ ;
LibereCanal (canL);
free (valeur);
return(0);
}


int FMoment4R(Image image,FILE *text)
/***********************************/
{
Reel 		mom1,mom2,mom3,mom4;

if ((text==NULL)||(image==NULL)) return(1);

Moment4R(image,&mom1,&mom2,&mom3,&mom4);
fprintf(text,"%g\t %g\t%g\t%g\t%ld\n",
	mom1,mom2,mom3,mom4,(long)image->taille.x*(long)image->taille.y);
return(0);
}


Image MoyenneAnnulaireR(Image imaS,Image imaD,int cx,int cy)
/**********************************************************/
/* les coordonnees du centre cx et cy sont donnees en absolue */
{
int		ox,oy,x,y,r,r1,r2,rc;
Reel 	** grilleD;
Image		disq1,disq2;

if (LitFenetre(imaS,&ox,&oy,&x,&y)) return(NULL);
if ((ox>cx)||(cx>x+ox)) return(NULL);
if ((oy>cy)||(cy>y+oy)) return(NULL);
r1=cx-ox;
r=x+ox-cx;
if (r1<r) r=r1;
r1=cy-oy;
r2=y+oy-cy;
if (r2<r1) r1=r2;
if (r1<r) r=r1;
if ((imaD=CreeImageSimple(imaD,T_REEL,V_COURBE,r,1))==NULL) return(NULL);
if ((grilleD=(Reel **)CreeGrille(imaD,Z_FENETRE))==NULL) return(NULL);
if ((disq1=CreeImageDest(imaS,NULL,T_REEL))==NULL) return(NULL);
disq2=CercleR(imaS,NULL,cx-ox,cy-oy,r,1.);
RempliR(disq2,disq2,cx-ox,cy-oy,1.,1.);
for (rc=r-1;rc>=0;rc--)
	{
	NiveauR(disq1,disq1,0.);
	CercleR(disq1,disq1,cx-ox,cy-oy,rc,1.);
	RempliR(disq1,disq1,cx-ox,cy-oy,1.,1.);
	SoustrR(disq2,disq1,disq2);
	MoyenneMasqueR(imaS,disq2,1.,&grilleD[0][rc]);
	disq2=TransfereR(disq1,disq2);
	}
LibereGrille(grilleD);
LibereImage(disq1);
LibereImage(disq2);
return(imaD);
}


//Image RayonsR(Image imS,Image imD,int cx,int cy,float da)
/*******************************************************/
/* les coordonnees du centre cx et cy sont donnees en absolue
	l'ecart angulaire da en degrés 						 */
/*{
int x,y,ox,oy,r,r1,un,r2,na,i;
Reel **grille;
double a;
float p;
Image imR1,imR2;

if (LitFenetre(imS,&ox,&oy,&x,&y)) return(NULL);
if ((ox>cx)||(cx>x+ox)) return(NULL);
if ((oy>cy)||(cy>y+oy)) return(NULL);
r1=cx-ox;
r=x+ox-cx;
if (r1<r) r=r1;
r1=cy-oy;
r2=y+oy-cy;
if (r2<r1) r1=r2;
if (r1<r) r=r1;
na=360/da;
da=da*M_PI/180;
if ((imD=CreeImageSimple(imD,T_REEL,imS->visu,r,na))==NULL) return(NULL);
if ((grille=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
for (i=0,a=0;i<na;i++,a+=da)
	{
	x=cx+r*cos(a);
	y=cy+r*sin(a);
	imR1=ExtraitDroiteR(imS,NULL,cx,cy,x,y);
	LitTailleFenetre(imR1,&r1,&un);
	p=(float)r/r1;
	if (p!=1) imR2=AnamorXR(imR1,NULL,p);
	else imR2=TransfereR(imR1,NULL);
	LitLigneR(imR2,0,grille[i]);
	LibereImage(imR2);
	LibereImage(imR1);
	}
LibereGrille(grille);
return(imD);
} */


Image SommeColonneR(Image imS,Image imD)
/**************************************/
{
int 	x,y,i,j;
Reel 	**grille,*val;
Canal canL;

if (LitTailleFenetre(imS,&x,&y)) return(NULL);
if((imD=CreeImageSimple(imD,T_REEL,V_COURBE,x,1))==NULL) return(NULL);
grille=(Reel**)CreeGrille(imD,Z_FENETRE);
val=(Reel*)calloc(x,sizeof(Reel));
canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE);
if (grille&&val&&canL)
	for (i=0;i<y;i++)
		{
		LitCanal(canL,val);
		for (j=0;j<x;j++) grille[0][j]+=val[j];
		}
LibereCanal(canL);
free(val);
LibereGrille(grille);
return(imD);
}

Image ExtraitTrameR(Image imS,Image imD,int pair)
/**********************************************/

{
int 	x,yS,yD,i;
Reel 	*ligne;
Canal 	canL,canE;

if(imS==NULL) return(NULL);
if ( (pair!=1) && (pair!=0) ) return(NULL);
LitTailleFenetre(imS,&x,&yS);
if (yS==1) return(NULL);

yD= (yS/2)+(yS%2)*pair;
if ((imD=CreeImageSimple(imD,T_REEL,V_CARTE,x,yD))==NULL) return(NULL);
if ((ligne=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);

if (!pair) LitCanal(canL,ligne);
for(i=0;i<yD-1;i++)
        {
	LitCanal(canL,ligne);
	EcritCanal(canE,ligne);
	LitCanal(canL,ligne);
	}
LitCanal(canL,ligne);
EcritCanal(canE,ligne);

LibereCanal(canL);
LibereCanal(canE);
free(ligne);

return(imD);
}


Image EntrelaceR(Image imS1,Image imS2,Image imD)
/***********************************************/

{
int 	x,y,i;
Reel *  ligne;
Canal 	canL1,canL2,canE;

if ((imS1==NULL)||(imS2==NULL)) return(NULL);
LitTailleFenetre(imS1,&x,&y);
if (TesteFenetre(imS1,imS2)) return(NULL);

if ((imD=CreeImageSimple(imD,T_REEL,V_CARTE,x,2*y))==NULL) return(NULL);
if ((canL1=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canL2=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((canE=CreeCanal(imD,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
if ((ligne=(Reel *)calloc(x,sizeof(Reel)))==NULL) return(NULL);

for(i=0;i<y;i++)
		  {
	LitCanal(canL1,ligne);
	EcritCanal(canE,ligne);
	LitCanal(canL2,ligne);
	EcritCanal(canE,ligne);
	}

free(ligne);
LibereCanal(canL1);
LibereCanal(canL2);
LibereCanal(canE);

return(imD);
}



int LitPointR(Image imS, Point *point, Reel *valeur)
/**************************************************/

{
Canal canL;

if ((canL=CreeCanal(imS,T_REEL,B_POINT,Z_FENETRE))==NULL) return(1);
if (PoseCanal(canL,point->x,point->y)) {LibereCanal(canL);return(1);}
LitCanal(canL,valeur);
LibereCanal(canL);
return(0);
}



int EcritPointR(Image imS, Point *point, Reel valeur)
/***************************************************/

{
Canal canL;

if ((canL=CreeCanal(imS,T_REEL,B_POINT,Z_FENETRE))==NULL) return(1);
if (PoseCanal(canL,point->x,point->y)) {LibereCanal(canL);return(1);}
EcritCanal(canL,&valeur);
LibereCanal(canL);
return(0);
}

int LitLigneR(Image imS,int py, Reel *valeur)
/*******************************************/

{
Canal canL;

if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(1);
if (PoseCanal(canL,0,py)) {LibereCanal(canL);return(1);}
LitCanal(canL,valeur);
LibereCanal(canL);
return(0);
}



int EcritLigneR(Image imS,int py, Reel *valeur)
/*********************************************/

{
Canal canL;

if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(1);
if (PoseCanal(canL,0,py)) {LibereCanal(canL);return(1);}
EcritCanal(canL,valeur);
LibereCanal(canL);
return(0);
}


int PosMinMaxR(Image imS, Point *posMin, Point *posMax, Reel *min, Reel *max)
/***************************************************************************/
{
int i,j,x,y;
Reel * valeur;
Canal canL;

if (imS==NULL) return(1);

LitTailleFenetre(imS,&x,&y);
if ((valeur=calloc(x,sizeof(Reel)))==NULL) return(1);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(1);

LitCanal(canL, valeur);
*max=*valeur;
*min=*valeur;
posMin->x=posMin->y=0;
*posMax=*posMin;
for (i=0;i<y-1;i++)
    {
    for (j=0;j<x;j++)
        {
        if (valeur[j]<*min)
            {
            *min=valeur[j];
            posMin->x=j;
            posMin->y=i;
            }
        if (valeur[j]>*max)
            {
            *max=valeur[j];
            posMax->x=j;
            posMax->y=i;
            }
         }
    LitCanal(canL, valeur);
    }
for (j=0;j<x;j++)
    {
    if (valeur[j]<*min)
        {
        *min=valeur[j];
        posMin->x=j;
        posMin->y=i;
        }
    if (valeur[j]>*max)
        {
        *max=valeur[j];
        posMax->x=j;
        posMax->y=i;
		}
     }

LibereCanal(canL);
free(valeur);
return (0);
}


int FPosMinMaxR(Image imS, FILE *text)
/************************************/
{
 Point posMin, posMax;
 Reel min, max;
if ((text==NULL)||(imS==NULL)) return(1);

PosMinMaxR(imS,&posMin,&posMax,&min,&max);
fprintf(text,"%g\t %d\t%d\t%g\t%d\t%d\n",
		min,posMin.x,posMin.y,max,posMax.x,posMax.y);

return(0);
}


Image Max1DirR(Image imS,Image imD)
/*********************************/

{
int i,ii,j,jj,x,y;
Canal canL;
Reel **grille,*lig0,*lig1,*lig2,*ptr,m0,m1,m2,d0,d1,d2,g0,g1,g2;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imD,&x,&y);
if ((x<2)||(y<2)) return(NULL);
lig0=(Reel*)calloc(x,sizeof(Reel));
lig1=(Reel*)calloc(x,sizeof(Reel));
lig2=(Reel*)calloc(x,sizeof(Reel));
grille=(Reel**)CreeGrille(imD,Z_FENETRE);
canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE);

if (lig0 && lig1 && lig2 && grille && canL)
	{
    PoseCanal(canL,0,y-2);
	LitCanal(canL,lig0);
	LitCanal(canL,lig1);
	PoseCanal(canL,0,0);
    ii=y-1;
	for (i=0;i<y;i++)
		{
		LitCanal(canL,lig2);
		g0=lig0[x-2];
		g1=lig1[x-2];
		g2=lig2[x-2];
		m0=lig0[x-1];
		m1=lig1[x-1];
		m2=lig2[x-1];
        jj=x-1;
		for (j=0;j<x;j++)
			{
			d0=lig0[j];
			d1=lig1[j];
			d2=lig2[j];

			if (	((m1>m0)&&(m1>m2)) || ((m1==m0)&&(m1==m2)) ||
					((m1>=g1)&&(m1>=d1)) || ((m1==g1)&&(m1==d1)) ||
					((m1>=g0)&&(m1>=d2)) || ((m1==g0)&&(m1==d2)) ||
					((m1>=d0)&&(m1>=g2)) || ((m1==d0)&&(m1==g2))) grille[ii][jj]=m1;
            else grille[ii][jj]=0; 

			jj=(jj+1)%x;
			g0=m0;
			m0=d0;
			g1=m1;
			m1=d1;
			g2=m2;
			m2=d2;
			}
		ii=(ii+1)%y;
		ptr=lig0;
		lig0=lig1;
		lig1=lig2;
        lig2=ptr;
        }
	}

LibereCanal(canL);
LibereGrille(grille);
free(lig2);
free(lig1);
free(lig0);
return(imD);
}


Image Max4DirR(Image imS,Image imD)
/*********************************/

{
int i,ii,j,jj,x,y;
Canal canL;
Reel **grille,*lig0,*lig1,*lig2,*ptr,m0,m1,m2,d0,d1,d2,g0,g1,g2;

if ((imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imD,&x,&y);
if ((x<2)||(y<2)) return(NULL);
lig0=(Reel*)calloc(x,sizeof(Reel));
lig1=(Reel*)calloc(x,sizeof(Reel));
lig2=(Reel*)calloc(x,sizeof(Reel));
grille=(Reel**)CreeGrille(imD,Z_FENETRE);
canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE);

if (lig0 && lig1 && lig2 && grille && canL)
	{
	PoseCanal(canL,0,y-2);
	LitCanal(canL,lig0);
	LitCanal(canL,lig1);
	PoseCanal(canL,0,0);
	ii=y-1;
	for (i=0;i<y;i++)
		{
		LitCanal(canL,lig2);
		g0=lig0[x-2];
		g1=lig1[x-2];
		g2=lig2[x-2];
		m0=lig0[x-1];
		m1=lig1[x-1];
		m2=lig2[x-1];
		jj=x-1;
		for (j=0;j<x;j++)
			{
			d0=lig0[j];
			d1=lig1[j];
			d2=lig2[j];

			if (	(((m1>m0)&&(m1>m2)) || ((m1==m0)&&(m1==m2))) &&
					(((m1>g1)&&(m1>d1)) || ((m1==g1)&&(m1==d1))) &&
					(((m1>g0)&&(m1>d2)) || ((m1==g0)&&(m1==d2))) &&
					(((m1>d0)&&(m1>g2)) || ((m1==d0)&&(m1==g2)))) grille[ii][jj]=m1;
			else grille[ii][jj]=0;

			jj=(jj+1)%x;
			g0=m0;
			m0=d0;
			g1=m1;
			m1=d1;
			g2=m2;
			m2=d2;
			}
		ii=(ii+1)%y;
		ptr=lig0;
		lig0=lig1;
		lig1=lig2;
        lig2=ptr;
        }
	}

LibereCanal(canL);
LibereGrille(grille);
free(lig2);
free(lig1);
free(lig0);
return(imD);
}




Image  CircR ( Image imS, Image profil, Image imD )
/*************************************************/
{
int i,j,x,y,xf,yf,k;
Canal canL;
ReelL x1,y1;
Reel **grille,*f;

if ((imS==NULL)||(profil==NULL)) return(NULL);
LitTailleFenetre(profil,&xf,&yf);
LitTailleFenetre(imS,&x,&y);
if (yf>1) return(NULL);

if( (imD=CreeImageSimple(imD,T_REEL,V_CARTE,x,y))==NULL) return(NULL);

if ((f=(Reel*)calloc(xf,sizeof(Reel)))==NULL) return(NULL);
if ((grille=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
if ((canL=CreeCanal(profil,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
LitCanal(canL,f);
LibereCanal(canL);

for(i=0;i<y;i++)
        {
        for(j=0;j<x;j++)
                {
                x1=j-x/2;
                y1=i-y/2;
                k=(int)(sqrt(x1*x1+y1*y1)+.5);
                if (k<xf)
                        grille[i][j]=f[k];
                }
        }

LibereGrille(grille);
free(f);
return(imD);
}



Image  AlterneSigneR ( Image imS, Image imD )
/*******************************************/

{
int i,j,x,y;
Reel **grille;
Reel sgn;
Canal canL;

if ( (imD=CreeImageDest(imS,imD,T_REEL))==NULL) return(NULL);

LitTailleFenetre(imD,&x, &y);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
if ((canL=CreeCanal(imS, T_REEL, B_LIGNE, Z_FENETRE))==NULL) return(NULL);

sgn=1;
for (i=0;i<y;i++)
   {
   LitCanal(canL, grille[i]);
   for (j=0;j<x;j++)
       {
       grille[i][j]*=sgn;
       sgn=-sgn;
       }
   sgn=-sgn;
   }

LibereCanal(canL);
LibereGrille(grille);
return (imD) ;
}


Image  ConvolueR ( Image imS1, Image imS2, Image imD )
/****************************************************/
{
Image imT;
if((imT=ConvolueC(imS1,imS2,NULL))==NULL) return (NULL);
imD=TransfereR(imT,imD);
LibereImage(imT);
return(imD);
}



Image  CorreleR ( Image imS1, Image imS2, Image imD )
/***************************************************/
{
Image imT;
if((imT=CorreleC(imS1,imS2,NULL))==NULL) return (NULL);
imD=TransfereR(imT,imD);
LibereImage(imT);
return(imD);
}



Image  AutoConvolueR ( Image imS, Image imD )
/*******************************************/

{
Image imT;
if((imT=AutoConvolueC(imS,NULL))==NULL) return (NULL);
imD=TransfereR(imT,imD);
LibereImage(imT);
return(imD);
}



Image  AutoCorreleR ( Image imS, Image imD )
/******************************************/

{
Image imT;
if((imT=AutoCorreleC(imS,NULL))==NULL) return (NULL);
imD=TransfereR(imT,imD);
LibereImage(imT);
return(imD);
}


/*
Image GenereBruitR(int x,int y,Reel sigma ,int distr)
{
int i,j;
long k,km;
int visu;
Image imD;
Reel **grille;
double a,xx,yy,s2;
time_t t;

if (y==1) visu=V_COURBE;
else visu=V_CARTE;
if ((imD=CreeImage(NULL,NULL,T_REEL,visu,x,y,NULL,NULL))==NULL) return(NULL);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

srand((unsigned) time(&t));
a=(double)((unsigned long)(1<<14)-1);
s2=2*sigma*sigma;
km=(long)x*y;

switch(distr)
	 {
	 case 0:
		for (i=0;i<y;i++)
		for (j=0;j<x;j++) grille[i][j]=(Reel)(random(1<<14)/a);
		break;
	 case 1:
		for (k=0;k<km-1;k+=1)
		  {
	xx=random(1<<14)/a;
	while (xx==0) xx=random(1<<14)/a;
	yy=(Reel)(sqrt(-s2*log(xx)));
	xx=2*M_PI*random(1<<14)/a;
	grille[(int)(k/x)][(int)(k%x)]=(Reel)(yy*cos(xx));
		  k++;
	grille[(int)(k/x)][(int)(k%x)]=(Reel)(yy*sin(xx));
		  }
		  if (km%2)
		  {
			xx=random(1<<14)/a;
			while (xx==0) xx=random(1<<14)/a;
			yy=(Reel)(sqrt(-s2*log(xx)));
			xx=2*M_PI*random(1<<14)/a;
			grille[(int)(k/x)][(int)(k%x)]=(Reel)(yy*cos(xx));
		  }
		  break;
	 case 2:
		for (i=0;i<y;i++)
				for (j=0;j<x;j++)
					{
					xx=random(1<<14)/a;
					while (xx==0) xx=random(1<<14)/a;
					grille[i][j]=(Reel)(sqrt(-s2*log(xx)));
					}
	break;
	 }

LibereGrille(grille);
return(imD);
}
*/

// Pas compatible unix
//Image GenereBruitR(Image imD,int x,int y,Reel sigma ,int distr)
/*************************************************************/
/*{
int i,j;
long k,km;
int visu;
Reel **grille;
double a,xx,yy,s2;
time_t t;

if (y==1) visu=V_COURBE;
else visu=V_CARTE;
if ((imD=CreeImageSimple(imD,T_REEL,visu,x,y))==NULL) return(NULL);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

srand((unsigned) time(&t));
a=(double)((unsigned long)(1<<14)-1);
s2=2*sigma*sigma;
km=(long)x*y;

switch(distr)
	 {
	 case 0:  // Distribution uniforme (à valeurs dans [0,1])
		for (i=0;i<y;i++)
		for (j=0;j<x;j++) grille[i][j]=(Reel)(random(1<<14)/a);
		break;
	 case 1:  // Distribution de Gauss (à valeurs dans |R)
		for (k=0;k<km-1;k+=1)
		  {
	xx=random(1<<14)/a;
	while (xx==0) xx=random(1<<14)/a;
	yy=(Reel)(sqrt(-s2*log(xx)));
	xx=2*M_PI*random(1<<14)/a;
	grille[(int)(k/x)][(int)(k%x)]=(Reel)(yy*cos(xx));
		  k++;
	grille[(int)(k/x)][(int)(k%x)]=(Reel)(yy*sin(xx));
		  }
		  if (km%2)
		  {
			xx=random(1<<14)/a;
			while (xx==0) xx=random(1<<14)/a;
			yy=(Reel)(sqrt(-s2*log(xx)));
			xx=2*M_PI*random(1<<14)/a;
			grille[(int)(k/x)][(int)(k%x)]=(Reel)(yy*cos(xx));
		  }
		  break;
	 case 2:  // Distribution de Rayleigh (à valeurs dans |R+)
		for (i=0;i<y;i++)
				for (j=0;j<x;j++)
					{
					xx=random(1<<14)/a;
					while (xx==0) xx=random(1<<14)/a;
					grille[i][j]=(Reel)(sqrt(-s2*log(xx)));
					}
	break;
	 }

LibereGrille(grille);
return(imD);
} */


Image MireSinusR(Image imD,int x,int y,int periode,Reel angle)
/************************************************************/
{
int i,j,visu;
Reel **grille,dx,dy,w;

if (y==1) visu=V_COURBE;
else visu=V_CARTE;
if ((imD=CreeImageSimple(imD,T_REEL,visu,x,y))==NULL) return(NULL);
if ((grille=(Reel **)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

dx=(Reel)cos(angle*M_PI/180);
dy=(Reel)sin(angle*M_PI/180);
w=2*M_PI/periode;
for (i=0;i<y;i++)
	for (j=0;j<x;j++) grille[i][j]=(Reel) sin(w*(j*dx+i*dy));

LibereGrille(grille);
return(imD);
}



Image  CircProfilR ( Image profil, Image imD, int taille)
/*******************************************************/
{
int i,j,x,y,xf,yf,k;
Canal canL;
ReelL x1,y1;
Reel **grille,*f;

if (profil==NULL) return(NULL);
LitTailleFenetre(profil,&xf,&yf);
if (yf>1) return(NULL);
x=y=taille;

if( (imD=CreeImageSimple(imD,T_REEL,V_CARTE,x,y))==NULL) return(NULL);

if ((f=(Reel*)calloc(xf,sizeof(Reel)))==NULL) return(NULL);
if ((grille=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);
if ((canL=CreeCanal(profil,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);
LitCanal(canL,f);
LibereCanal(canL);

for(i=0;i<y;i++)
        {
        for(j=0;j<x;j++)
                {
                x1=j-x/2;
                y1=i-y/2;
                k=(int)(sqrt(x1*x1+y1*y1)+.5);
                if (k<xf)
                        grille[i][j]=f[k];
                }
        }

LibereGrille(grille);
free(f);
return(imD);
}



Image TransCourbeImageLR(Image imLS,Image imD)
/********************************************/
{
int i,x,y,xx,yy;
Reel **grille;
Canal canL;
Image imC;

if ((y=CompteImageL(imLS))==NULL) return(NULL);
imC=LitImageL(imLS,0);
LitTailleFenetre(imC,&x,&yy);

if ((imD=CreeImageSimple(imD,T_REEL,V_CARTE,x,y))==NULL) return(NULL);
if ((grille=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return(NULL);

for (i=0;i<y;i++)
	{
    imC=LitImageL(imLS,i);
	if ((canL=CreeCanal(imC,T_REEL,B_LIGNE,Z_FENETRE))==NULL) break;
	LitTailleFenetre(imC,&xx,&yy);
    if (xx<=x) LitCanal(canL,grille[i]);
    LibereCanal(canL);
	}

LibereGrille(grille);
return(imD);
}



Image TransImageCourbeLR(Image imS,Image imLD)
/********************************************/
{
int i,x,y;
Canal canL;
Reel **grille;
Image imC;

if ((LitTailleFenetre(imS,&x,&y))) return(NULL);
if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return(NULL);


for (i=0;i<y;i++)
	{
	if ((imC=CreeImageSimple(NULL,T_REEL,V_COURBE,x,1))==NULL) return(NULL);
	if ((grille=(Reel**)CreeGrille(imC,Z_FENETRE))==NULL) return(NULL);
	LitCanal(canL,grille[0]);
	LibereGrille(grille);

    InsereImageL(&imLD,imC,i);
	}

LibereCanal(canL);
return(imLD);
}



Image RempliR(Image imaS,Image imaD, int germex,int germey, Reel b, Reel c)
/*************************************************************************/
/* les coordonnees du germe sont donnees en relatif */
{
 /* remplissage à c de tous les pixels de niveau inferieur strictement à b */

 int xs,ys,x, y, xg, xd, xx, yy, xanc;

 Reel **grille;
 if (imaS==NULL) return(NULL);
 if (imaD==NULL) imaD=TransfereR(imaS,imaD);

 if ((grille=(Reel **)CreeGrille(imaD,Z_FENETRE))==NULL)
	return (NULL);
 LitTailleFenetre(imaD,&xs,&ys);

 x=germex; y=germey;

 tete=NULL;
 Empiler(x,y);

 while (tete!=NULL)

     {
	 poi=Depiler();
	 x = poi -> xcoord;
     y = poi -> ycoord;
     free(poi);
	 if ((grille[y][x] <b)&&(grille[y][x]!=c))

	{


	 xx=x;

	 while ((xx<xs) && (grille[y][xx] < b)&&(grille[y][xx]!=c))

	    {  grille[y][xx++]=c; }

	 xd=xx-1;

	 xx=x-1;

	 while((xx>=0) && (grille[y][xx] <  b)&&(grille[y][xx]!=c))

	    {  grille[y][xx--]=c; }

	 xg=xx+1;

	 if (y-1>=0)

	    {

	     yy=y-1; xx=xg;

	     while (xx<=xd)

		{

		 while((xx<=xd)&&((grille[yy][xx]>=b)||(grille[yy][xx]==c)))xx++;

		 if (xx<=xd)

		    {


		     Empiler(xx,yy); 


		     while((xx<=xd)&&(grille[yy][xx]<b)&&(grille[yy][xx]!=c)) xx++;

		     }

		}

	    }

	 if (y+1<ys)

	    {

	     yy=y+1; xx=xg;

	     while(xx<=xd)

		{

		 xanc=xx;

		 while((xx<=xd)&&((grille[yy][xx]>=b)||(grille[yy][xx]==c)))xx++;

		 if (xx<=xd)

		    {
			Empiler(xx,yy);


		     while((xx<=xd)&&(grille[yy][xx]<b)&&(grille[yy][xx]!=c))
			 xx++;

		    }

		 if(xanc==xx) return(NULL); 

		}

	    }

	}
     }
LibereGrille(grille);
return(imaD);
}



Image SegmentR (Image imaS,Image imaD,int p1x,int p1y,int p2x,int p2y,Reel val)
/*****************************************************************************/
/* Trace d'un segment: le systeme de coordonnees est le systeme image
zero en haut a gauche, les arguments sont les coordonnees entieres des points
de depart et d'arrivee,  algorithme de Lucas */
{
int  	j,dx,dy,xinc,yinc,cumul,x,y;
Reel	**grilleD;

if (imaS==NULL) return(NULL);
if ((imaD=CreeImageDest(imaS,imaD,T_REEL))==NULL) return(NULL);;
LitTailleFenetre(imaD,&x,&y);
if ((p1x<0)||(p1x>=x)||(p1y<0)||(p1y>=y)||(p2x<0)||(p2x>=x)||(p2y<0)||(p2y>=y)) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return(NULL);

x=p1x;
y=p1y;
grilleD[y][x]=val;
if(p1x<p2x) xinc=1;
 else xinc=-1;
if(p1y<p2y) yinc=1;
 else yinc=-1;
dx=p2x-p1x;
if(dx<0) dx=-dx;
dy=p2y-p1y;
if(dy<0) dy=-dy;
if(dx>dy)
	{
	cumul=dx/2;
	for(j=1;j<=dx;j++)
	    {
	    x=x+xinc;
	    cumul=cumul+dy;
	    if (cumul>=dx)
		{
		cumul=cumul-dx;
		y=y+yinc;
		}
	    grilleD[y][x]=val;
	    }
	}
    else
	{
	cumul=dy/2;
	for(j=1;j<=dy;j++)
	    {
	    y=y+yinc;
	    cumul=cumul+dx;
	    if(cumul>=dy)
		{
		cumul=cumul-dy;
		x=x+xinc;
		}
		 grilleD[y][x]=val;
	    }
	}

LibereGrille(grilleD);
return(imaD);
}



Image CercleR (Image imaS,Image imaD,int ox,int oy,int r,Reel val)
/****************************************************************/
/* tracé de cercle selon l'algorithme de Michener */
/* les coordonnees du centre sont donnees en relatif */
{
int  	tx,ty,x,y,c;
Reel	**grilleD;

if ((imaS==NULL)||(r<0)) return(NULL);
if ((imaD=CreeImageDest(imaS,imaD,T_REEL))==NULL) return(NULL);;
LitTailleFenetre(imaD,&tx,&ty);
if ((ox<0)||(ox>=tx)||(oy<0)||(oy>=ty)) return(NULL);
if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return(NULL);

if (r==0)
	grilleD[oy][ox]=val;
 else
{
x = r;
y = 0;
c = 3 - 2*r;
while (x>=y)
	{
	if (x != y)
         {
	 if (((int)oy+y>=0)&&(oy+y<ty)&&((int)ox+x>=0)&&(ox+x<tx)) grilleD[oy+y][ox+x]=val;
	 if (((int)oy-x>=0)&&(oy-x<ty)&&((int)ox+y>=0)&&(ox+y<tx)) grilleD[oy-x][ox+y]=val;
	 if (((int)oy-y>=0)&&(oy-y<ty)&&((int)ox-x>=0)&&(ox-x<tx)) grilleD[oy-y][ox-x]=val;
	 if (((int)oy+x>=0)&&(oy+x<ty)&&((int)ox-y>=0)&&(ox-y<tx)) grilleD[oy+x][ox-y]=val;
         }
	if (y != 0)
         {
	 if (((int)oy-y>=0)&&(oy-y<ty)&&((int)ox+x>=0)&&(ox+x<tx)) grilleD[oy-y][ox+x]=val;
	 if (((int)oy-x>=0)&&(oy-x<ty)&&((int)ox-y>=0)&&(ox-y<tx)) grilleD[oy-x][ox-y]=val;
	 if (((int)oy+y>=0)&&(oy+y<ty)&&((int)ox-x>=0)&&(ox-x<tx)) grilleD[oy+y][ox-x]=val;
	 if (((int)oy+x>=0)&&(oy+x<ty)&&((int)ox+y>=0)&&(ox+y<tx)) grilleD[oy+x][ox+y]=val;
         } 
	if (c<0)
	   c += 4*y + 6;
	 else
	 	{
	   	c += -4*x + 4*y +10;
	   	x--;
	  	}
	y++;
	}
}

LibereGrille(grilleD);
return(imaD);
}

//*****************************************************************************
// Rehausse l'image par rapport au niveau de gris moyen de tel sorte qu'il
// soit égale à val et que le minimum de l'image soit à 0
//*****************************************************************************
Image RehausseR(Image imS1,Image imD,Reel val)
{
int i,j,w,h ;
Reel mo=0,mn=MAXINT,cste ;
Canal canL ;
Reel **grilleD ;


if ((imD=CreeImageDest(imS1,imD,T_REEL))==NULL) return(NULL);
LitTailleFenetre(imS1,&w,&h);
if ((canL=CreeCanal(imS1,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return (NULL);

// Initialisation des images
for(i=0;i<h;i++){
 LitCanal(canL,grilleD[i]);
 for(j=0;j<w;j++)
   mn=min(mn,grilleD[i][j]) ;
 }

for(i=0;i<h;i++)
 for(j=0;j<w;j++){
   grilleD[i][j]=(grilleD[i][j]-mn) ;
   mo+=grilleD[i][j] ;
 }

cste=0;
if (mo>0)
  mo=val*w*h/mo ;
else
  {
  mo=1;
  if (mn!=0) cste=val;
  }
for(i=0;i<h;i++)
 for(j=0;j<w;j++)
   grilleD[i][j]=grilleD[i][j]*mo+cste ;

LibereGrille(grilleD) ;
LibereCanal(canL) ;

return(imD);
}

