#include <stdlib.h>
#include <math.h>
#include "image.h"
#include "grille.h"
#include "canal.h"
#include "r.h"

static int TesteEgaliteR(Image imS1,Image imS2);


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

{
Canal canL, canE;
Reel **valeur, *dil, *paux;
float aux;
int tx, ty, i, j, k;


if ((imD = CreeImageDest (imS, imD, T_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);

LitTailleFenetre (imD, &tx, &ty);

if ((dil = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

if (ty == 1)
     {
     if ((paux = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

     LitCanal (canL, paux);
     aux = paux[0];
     if (paux[1] > aux)  aux = paux[1];
     dil[0] = aux;
     for (j=1; j<tx-1; j++)
          {
          aux = paux[j-1];
          if (paux[j] > aux)  aux = paux[j];
          if (paux[j+1] > aux)  aux = paux[j+1];
          dil[j] = aux;
          }
     aux = paux[tx-2];
     if (paux[tx-1] > aux)  aux = paux[tx-1];
     dil[tx-1] = aux;
     EcritCanal(canE, dil);

     free(paux);
     }
else
     {

if ((valeur = (Reel **)calloc(3,sizeof(Reel *))) == NULL)  return (NULL);
for (i=0; i<3; i++)
     if ((valeur[i] = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);


/***** premiŠre ligne *****/

LitCanal (canL, valeur[1]);
LitCanal (canL, valeur[2]);

/** i=0  j=0 **/
aux = valeur[1][0];
if (valeur[1][1] > aux)  aux = valeur[1][1];
if (valeur[2][0] > aux)  aux = valeur[2][0];
dil[0] = aux;

/** i=0  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[2][j];
     for (k=j-1; k<j+2; k++)
          if (valeur[1][k] > aux)  aux = valeur[1][k];
     dil[j] = aux;
     }

/** i=0  j=tx-1 **/
aux = valeur[1][tx-2];
if (valeur[1][tx-1] > aux)  aux = valeur[1][tx-1];
if (valeur[2][tx-1] > aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


/***** lignes 1 … ty-2 *****/

/** i=1..ty-2 **/
for (i=1; i<ty-1; i++)
     {
     paux = valeur[0];
     valeur[0] = valeur[1];
     valeur[1] = valeur[2];
     valeur[2] = paux;
     LitCanal (canL, valeur[2]);

     /** j=0 **/
     aux = valeur[1][1];
     for (k=0; k<3; k++)
          if (valeur[k][0] > aux)  aux = valeur[k][0];
     dil[0] = aux;

     /** j=1..tx-2 **/
     for (j=1; j<tx-1; j++)
          {
          aux = valeur[0][j];
          if (valeur[2][j] > aux)  aux = valeur[2][j];
          for (k=j-1; k<j+2; k++)
               if (valeur[1][k] > aux)  aux = valeur[1][k];
          dil[j] = aux;
          }

     /** j=tx-1 **/
     aux = valeur[1][tx-2];
     for (k=0; k<3; k++)
          if (valeur[k][tx-1] > aux)  aux = valeur[k][tx-1];
     dil[tx-1] = aux;

     EcritCanal(canE, dil);
     }


/***** derniŠre ligne *****/

/** i=ty-1  j=0 **/
aux = valeur[1][0];
if (valeur[2][0] > aux)  aux = valeur[2][0];
if (valeur[2][1] > aux)  aux = valeur[2][1];
dil[0] = aux;

/** i=ty-1  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[1][j];
     for (k=j-1; k<j+2; k++)
          if (valeur[2][k] > aux)  aux = valeur[2][k];
     dil[j] = aux;
     }

/** i=ty-1  j=tx-1 **/
aux = valeur[1][tx-1];
if (valeur[2][tx-2] > aux)  aux = valeur[2][tx-2];
if (valeur[2][tx-1] > aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


for (i=2; i<=0; i--) free(valeur[i]);
free(valeur);

     }

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





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

{
Canal canL, canE;
Reel **valeur, *dil, *paux;
float aux;
int tx, ty, i, j, k;


if ((imD = CreeImageDest (imS, imD, T_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);

LitTailleFenetre (imD, &tx, &ty);

if ((dil = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

if (ty == 1)
     {
     if ((paux = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

     LitCanal (canL, paux);
     aux = paux[0];
     if (paux[1] > aux)  aux = paux[1];
     dil[0] = aux;
     for (j=1; j<tx-1; j++)
          {
          aux = paux[j-1];
          if (paux[j] > aux)  aux = paux[j];
          if (paux[j+1] > aux)  aux = paux[j+1];
          dil[j] = aux;
          }
     aux = paux[tx-2];
     if (paux[tx-1] > aux)  aux = paux[tx-1];
     dil[tx-1] = aux;
     EcritCanal(canE, dil);

     free(paux);
     }
else
     {

if ((valeur = (Reel **)calloc(3,sizeof(Reel *))) == NULL)  return (NULL);
for (i=0; i<3; i++)
     if ((valeur[i] = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);


/***** premiŠre ligne *****/

LitCanal (canL, valeur[1]);
LitCanal (canL, valeur[2]);

/** i=0  j=0 **/
aux = valeur[1][0];
if (valeur[1][1] > aux)  aux = valeur[1][1];
if (valeur[2][0] > aux)  aux = valeur[2][0];
if (valeur[2][1] > aux)  aux = valeur[2][1];
dil[0] = aux;

/** i=0  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[1][j-1];
     if (valeur[1][j] > aux)  aux = valeur[1][j];
     if (valeur[1][j+1] > aux)  aux = valeur[1][j+1];
     for (k=j-1; k<j+2; k++)
          if (valeur[2][k] > aux)  aux = valeur[2][k];
     dil[j] = aux;
     }

/** i=0  j=tx-1 **/
aux = valeur[1][tx-2];
if (valeur[1][tx-1] > aux)  aux = valeur[1][tx-1];
if (valeur[2][tx-2] > aux)  aux = valeur[2][tx-2];
if (valeur[2][tx-1] > aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


/***** lignes 1 … ty-2 *****/

/** i=1..ty-2 **/
for (i=1; i<ty-1; i++)
     {
     paux = valeur[0];
     valeur[0] = valeur[1];
     valeur[1] = valeur[2];
     valeur[2] = paux;
     LitCanal (canL, valeur[2]);

     /** j=0 **/
     aux = valeur[0][0];
     if (valeur[0][1] > aux)  aux = valeur[0][1];
     for (k=0; k<2; k++)
          {
          if (valeur[1][k] > aux)  aux = valeur[1][k];
          if (valeur[2][k] > aux)  aux = valeur[2][k];
          }
     dil[0] = aux;

     /** j=1..tx-2 **/
     for (j=1; j<tx-1; j++)
          {
          aux = valeur[0][j-1];
          if (valeur[0][j] > aux)  aux = valeur[0][j];
          if (valeur[0][j+1] > aux)  aux = valeur[0][j+1];
          for (k=j-1; k<j+2; k++)
               {
               if (valeur[1][k] > aux)  aux = valeur[1][k];
               if (valeur[2][k] > aux)  aux = valeur[2][k];
               }
          dil[j] = aux;
          }

     /** j=tx-1 **/
     aux = valeur[0][tx-2];
     if (valeur[0][tx-1] > aux)  aux = valeur[0][tx-1];
     for (k=tx-2; k<tx; k++)
          {
          if (valeur[1][k] > aux)  aux = valeur[1][k];
          if (valeur[2][k] > aux)  aux = valeur[2][k];
          }
     dil[tx-1] = aux;

     EcritCanal(canE, dil);
     }


/***** derniŠre ligne *****/

/** i=ty-1  j=0 **/
aux = valeur[1][0];
if (valeur[1][1] > aux)  aux = valeur[1][1];
if (valeur[2][0] > aux)  aux = valeur[2][0];
if (valeur[2][1] > aux)  aux = valeur[2][1];
dil[0] = aux;

/** i=ty-1  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[1][j-1];
     if (valeur[1][j] > aux)  aux = valeur[1][j];
     if (valeur[1][j+1] > aux)  aux = valeur[1][j+1];
     for (k=j-1; k<j+2; k++)
          if (valeur[2][k] > aux)  aux = valeur[2][k];
     dil[j] = aux;
     }

/** i=ty-1  j=tx-1 **/
aux = valeur[1][tx-2];
if (valeur[1][tx-1] > aux)  aux = valeur[1][tx-1];
if (valeur[2][tx-2] > aux)  aux = valeur[2][tx-2];
if (valeur[2][tx-1] > aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


for (i=2; i<=0; i--) free(valeur[i]);
free(valeur);

     }

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





Image  DilateNFoisR ( Image imS, Image imD, int N )
/*************************************************/

{
int i;


if (N <= 0) return (NULL);

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

if ((DilateCroixR(imS, imD)) == NULL)  return (NULL);

for (i=2; i<=N; i++)
     {
     DilateCarreR(imD,imD);
     i++;
     if (i<=N) DilateCroixR(imD,imD);
     }

return (imD);
}





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

{
Canal canL, canE;
Reel **valeur, *dil, *paux;
float aux;
int tx, ty, i, j, k;


if ((imD = CreeImageDest (imS, imD, T_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);

LitTailleFenetre (imD, &tx, &ty);

if ((dil = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

if (ty == 1)
     {
     if ((paux = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

     LitCanal (canL, paux);
     aux = paux[0];
     if (paux[1] < aux)  aux = paux[1];
     dil[0] = aux;
     for (j=1; j<tx-1; j++)
          {
          aux = paux[j-1];
          if (paux[j] < aux)  aux = paux[j];
          if (paux[j+1] < aux)  aux = paux[j+1];
          dil[j] = aux;
          }
     aux = paux[tx-2];
     if (paux[tx-1] < aux)  aux = paux[tx-1];
     dil[tx-1] = aux;
     EcritCanal(canE, dil);

     free(paux);
     }
else
     {

if ((valeur = (Reel **)calloc(3,sizeof(Reel *))) == NULL)  return (NULL);
for (i=0; i<3; i++)
     if ((valeur[i] = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);


/***** premiŠre ligne *****/

LitCanal (canL, valeur[1]);
LitCanal (canL, valeur[2]);

/** i=0  j=0 **/
aux = valeur[1][0];
if (valeur[1][1] < aux)  aux = valeur[1][1];
if (valeur[2][0] < aux)  aux = valeur[2][0];
dil[0] = aux;

/** i=0  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[2][j];
     for (k=j-1; k<j+2; k++)
          if (valeur[1][k] < aux)  aux = valeur[1][k];
     dil[j] = aux;
     }

/** i=0  j=tx-1 **/
aux = valeur[1][tx-2];
if (valeur[1][tx-1] < aux)  aux = valeur[1][tx-1];
if (valeur[2][tx-1] < aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


/***** lignes 1 … ty-2 *****/

/** i=1..ty-2 **/
for (i=1; i<ty-1; i++)
     {
     paux = valeur[0];
     valeur[0] = valeur[1];
     valeur[1] = valeur[2];
     valeur[2] = paux;
     LitCanal (canL, valeur[2]);

     /** j=0 **/
     aux = valeur[1][1];
     for (k=0; k<3; k++)
          if (valeur[k][0] < aux)  aux = valeur[k][0];
     dil[0] = aux;

     /** j=1..tx-2 **/
     for (j=1; j<tx-1; j++)
          {
          aux = valeur[0][j];
          if (valeur[2][j] < aux)  aux = valeur[2][j];
          for (k=j-1; k<j+2; k++)
               if (valeur[1][k] < aux)  aux = valeur[1][k];
          dil[j] = aux;
          }

     /** j=tx-1 **/
     aux = valeur[1][tx-2];
     for (k=0; k<3; k++)
          if (valeur[k][tx-1] < aux)  aux = valeur[k][tx-1];
     dil[tx-1] = aux;

     EcritCanal(canE, dil);
     }


/***** derniŠre ligne *****/

/** i=ty-1  j=0 **/
aux = valeur[1][0];
if (valeur[2][0] < aux)  aux = valeur[2][0];
if (valeur[2][1] < aux)  aux = valeur[2][1];
dil[0] = aux;

/** i=ty-1  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[1][j];
     for (k=j-1; k<j+2; k++)
          if (valeur[2][k] < aux)  aux = valeur[2][k];
     dil[j] = aux;
     }

/** i=ty-1  j=tx-1 **/
aux = valeur[1][tx-1];
if (valeur[2][tx-2] < aux)  aux = valeur[2][tx-2];
if (valeur[2][tx-1] < aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


for (i=2; i<=0; i--) free(valeur[i]);
free(valeur);

     }

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





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

{
Canal canL, canE;
Reel **valeur, *dil, *paux;
float aux;
int tx, ty, i, j, k;


if ((imD = CreeImageDest (imS, imD, T_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);

LitTailleFenetre (imD, &tx, &ty);

if ((dil = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

if (ty == 1)
     {
     if ((paux = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);

     LitCanal (canL, paux);
     aux = paux[0];
     if (paux[1] < aux)  aux = paux[1];
     dil[0] = aux;
     for (j=1; j<tx-1; j++)
          {
          aux = paux[j-1];
          if (paux[j] < aux)  aux = paux[j];
          if (paux[j+1] < aux)  aux = paux[j+1];
          dil[j] = aux;
          }
     aux = paux[tx-2];
     if (paux[tx-1] < aux)  aux = paux[tx-1];
     dil[tx-1] = aux;
     EcritCanal(canE, dil);

     free(paux);
     }
else
     {

if ((valeur = (Reel **)calloc(3,sizeof(Reel *))) == NULL)  return (NULL);
for (i=0; i<3; i++)
     if ((valeur[i] = (Reel *)calloc(tx,sizeof(Reel))) == NULL)  return (NULL);


/***** premiŠre ligne *****/

LitCanal (canL, valeur[1]);
LitCanal (canL, valeur[2]);

/** i=0  j=0 **/
aux = valeur[1][0];
if (valeur[1][1] < aux)  aux = valeur[1][1];
if (valeur[2][0] < aux)  aux = valeur[2][0];
if (valeur[2][1] < aux)  aux = valeur[2][1];
dil[0] = aux;

/** i=0  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[1][j-1];
     if (valeur[1][j] < aux)  aux = valeur[1][j];
     if (valeur[1][j+1] < aux)  aux = valeur[1][j+1];
     for (k=j-1; k<j+2; k++)
          if (valeur[2][k] < aux)  aux = valeur[2][k];
     dil[j] = aux;
     }

/** i=0  j=tx-1 **/
aux = valeur[1][tx-2];
if (valeur[1][tx-1] < aux)  aux = valeur[1][tx-1];
if (valeur[2][tx-2] < aux)  aux = valeur[2][tx-2];
if (valeur[2][tx-1] < aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


/***** lignes 1 … ty-2 *****/

/** i=1..ty-2 **/
for (i=1; i<ty-1; i++)
     {
     paux = valeur[0];
     valeur[0] = valeur[1];
     valeur[1] = valeur[2];
     valeur[2] = paux;
     LitCanal (canL, valeur[2]);

     /** j=0 **/
     aux = valeur[0][0];
     if (valeur[0][1] < aux)  aux = valeur[0][1];
     for (k=0; k<2; k++)
          {
          if (valeur[1][k] < aux)  aux = valeur[1][k];
          if (valeur[2][k] < aux)  aux = valeur[2][k];
          }
     dil[0] = aux;

     /** j=1..tx-2 **/
     for (j=1; j<tx-1; j++)
          {
          aux = valeur[0][j-1];
          if (valeur[0][j] < aux)  aux = valeur[0][j];
          if (valeur[0][j+1] < aux)  aux = valeur[0][j+1];
          for (k=j-1; k<j+2; k++)
               {
               if (valeur[1][k] < aux)  aux = valeur[1][k];
               if (valeur[2][k] < aux)  aux = valeur[2][k];
               }
          dil[j] = aux;
          }

     /** j=tx-1 **/
     aux = valeur[0][tx-2];
     if (valeur[0][tx-1] < aux)  aux = valeur[0][tx-1];
     for (k=tx-2; k<tx; k++)
          {
          if (valeur[1][k] < aux)  aux = valeur[1][k];
          if (valeur[2][k] < aux)  aux = valeur[2][k];
          }
     dil[tx-1] = aux;

     EcritCanal(canE, dil);
     }


/***** derniŠre ligne *****/

/** i=ty-1  j=0 **/
aux = valeur[1][0];
if (valeur[1][1] < aux)  aux = valeur[1][1];
if (valeur[2][0] < aux)  aux = valeur[2][0];
if (valeur[2][1] < aux)  aux = valeur[2][1];
dil[0] = aux;

/** i=ty-1  j=1..tx-2 **/
for (j=1; j<tx-1; j++)
     {
     aux = valeur[1][j-1];
     if (valeur[1][j] < aux)  aux = valeur[1][j];
     if (valeur[1][j+1] < aux)  aux = valeur[1][j+1];
     for (k=j-1; k<j+2; k++)
          if (valeur[2][k] < aux)  aux = valeur[2][k];
     dil[j] = aux;
     }

/** i=ty-1  j=tx-1 **/
aux = valeur[1][tx-2];
if (valeur[1][tx-1] < aux)  aux = valeur[1][tx-1];
if (valeur[2][tx-2] < aux)  aux = valeur[2][tx-2];
if (valeur[2][tx-1] < aux)  aux = valeur[2][tx-1];
dil[tx-1] = aux;

EcritCanal(canE, dil);


for (i=2; i<=0; i--) free(valeur[i]);
free(valeur);

     }

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





Image  ErodeNFoisR ( Image imS, Image imD, int N )
/************************************************/

{
int i;


if (N <= 0) return (NULL);

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

if ((ErodeCroixR(imS, imD)) == NULL)  return (NULL);

for (i=2; i<=N; i++)
     {
     ErodeCarreR(imD,imD);
     i++;
     if (i<=N) ErodeCroixR(imD,imD);
     }

return (imD);
}

Image OuvreNR(Image imaS,Image imaD,int n)
/****************************************/
{
if (n <= 0) return (NULL);
if ((imaD = CreeImageDest (imaS, imaD, T_REEL)) == NULL) return (NULL);
if ((imaD=ErodeNFoisR(imaS, imaD,n)) == NULL)  return (NULL);
if ((imaD=DilateNFoisR(imaD, imaD,n)) == NULL)  return (NULL);
return(imaD);
}

Image FermeNR(Image imaS,Image imaD,int n)
/****************************************/
{
if (n <= 0) return (NULL);
if ((imaD = CreeImageDest (imaS, imaD, T_REEL)) == NULL) return (NULL);
if ((imaD=DilateNFoisR(imaS, imaD,n)) == NULL)  return (NULL);
if ((imaD=ErodeNFoisR(imaD, imaD,n)) == NULL)  return (NULL);
return(imaD);
}



/*- Reconstruction par marqueur -*/

static int TesteEgaliteR(Image imS1,Image imS2)
/*********************************************/
{
int 	i,j,x,y,test=1;
Canal 	canL1,canL2;
Reel 	*val1,*val2;

if (TesteFenetre(imS1,imS2)) return(0);

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);

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

LibereCanal(canL2);
LibereCanal(canL1);
free(val2);
free(val1);
return(test);
}


Image ReconstruitR(Image imS,Image imMarqueur,Image imD)
/******************************************************/
{
Image im=NULL;

if (TesteFenetre(imS,imMarqueur)) return(NULL);
if ((imD=TransfereR(imMarqueur,imD))==NULL) return (NULL);
do
	{
	im=TransfereR(imD,im);
	DilateCarreR(im,imD);
	IntersecteR(imS,imD,imD);
	}
while (TesteEgaliteR(imD,im)==0);

LibereImage(im);
return(imD);
}





//*****************************************************************************
// Indique si une image est vide (tout les pixels à la même valeur) ou non
//*****************************************************************************
int TestImageConstR(Image imS){

  int i,j,w,h ;
  Canal canL ;
  Reel *val,v ;


  LitTailleFenetre(imS,&w,&h) ;
  if ((canL=CreeCanal(imS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (1) ;
  if ((val=(Reel *)calloc(w,sizeof(Reel)))==NULL) return (1) ;

  for(i=0;i<h;i++){
    LitCanal(canL,val) ;
    if (i==0) v=val[0] ;
    for(j=0;j<w;j++)
      if (val[j]!=v) return (0) ; // Un point n'est pas du même niveau donc
  }                                 // l'image n'est pas vide

  free(val) ;
  LibereCanal(canL) ;

  return (1) ;
}



//*****************************************************************************
// Ebarbulages itératifs en niveau de gris
// n=nb maxi d'itérations (s'arrète avant s'il n'y a plus d'évolution)
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image EbarbuleR(Image imaS,Image imaD,int n){

  Reel f2,f3,f4,f5,f6,f8,f9 ;
  int i,j,k,i1,i2,w,h ;
  Reel sn,sm,m ;
  int fin ;
  //Image imaI=NULL ;
  Canal canL ;
  //Reel **grilleI ;
  Reel **grilleD ;


  if ((imaD=CreeImageDest(imaS,imaD,T_REEL))==NULL) return(NULL);
  LitTailleFenetre(imaS,&w,&h) ;
  if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return (NULL);
  if ((canL=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if (n==0) n=max(w,h);
  //if ((imaI=CreeImageDest(imaS,imaI,T_REEL))==NULL) return(NULL);
  //if ((grilleI=(Reel**)CreeGrille(imaI,Z_FENETRE))==NULL) return (NULL);

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

  // Ebarbulage suivant un réseau carré
  k=0; fin=0;
  while ((k++<n)&&(!fin)){
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      f3=grilleD[i1][1];
      f5=grilleD[i][0]; f6=grilleD[i][1];
      f9=grilleD[i2][1];
      for(j=2;j<w;j++){

        // voisinage de m:  f1  f2  f3
        //                  f4 m=f5 f6
        //                  f7  f8  f9
        f2=f3; f3=grilleD[i1][j];
        f4=f5; f5=f6; f6=grilleD[i][j];
        f8=f9; f9=grilleD[i2][j]; m=f5 ;

        // Famille E4 (Ref: Précis d'analyse d'image p185)
        if ((sn=f2)<m)
          if ((sn=max(sn,f4))<m){
            if ((sm=max(sn,f6))<m) m=sm ;
            if ((sn=max(sn,f8))<m) m=min(sn,m) ;
          }
        if ((sn=f6)<m)
          if ((sn=max(sn,f8))<m){
            if ((sm=max(sn,f4))<m) m=min(sm,m) ;
            if ((sn=max(sn,f2))<m) m=min(sn,m) ;
          }
        grilleD[i][j-1]=m ;
        fin=fin && (m==f5) ;
      }
    }
    //for(i=0;i<h;i++)
    //  for(j=0;j<w;j++)
    //    grilleD[i][j]=grilleI[i][j] ;
  }
//  LibereGrille(grilleI);
//  LibereImage(imaI);
  LibereCanal(canL);
  LibereGrille(grilleD);
  return(imaD);
}




//*****************************************************************************
// Amincissements itératifs en série en niveau de gris
// n=nb d'itérations maxi (s'arrète avant s'il n'y a plus d'évolution)
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image AmincitR(Image imaS,Image imaD,int n){

  Reel f5 ;
  int k,i,j,i1,i2,j1,j2,w,h ;
  Reel sn ;
  int fin ;
  Canal canL;
  Image imaI=NULL;
  Reel **grilleI;
  Reel **grilleD;


  if ((imaD=CreeImageDest(imaS,imaD,T_REEL))==NULL) return(NULL);
  LitTailleFenetre(imaS,&w,&h) ;
  if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return (NULL);
  if ((canL=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((imaI=CreeImageDest(imaS,imaI,T_REEL))==NULL) return(NULL);
  if ((grilleI=(Reel**)CreeGrille(imaI,Z_FENETRE))==NULL) return (NULL);
  if (n==0) n=max(w,h);

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


  k=0; fin=0;
  while((k++<n)&&(!fin)){

     //Amincissement réseau carré
     // On applique les différentes matrices de configuration
     // voisinage de m:  f1  f2  f3
     //                  f4 m=f5 f6
     //                  f7  f8  f9
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i1][j1])<f5)
            if ((sn=max(grilleD[i1][j],sn))<f5)
              if ((sn=max(grilleD[i1][j2],sn))<f5)
                if ((grilleD[i2][j1]>=f5)&&(grilleD[i2][j]>=f5)&&(grilleD[i2][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i1][j1])<f5)
            if ((sn=max(grilleI[i][j1],sn))<f5)
              if ((sn=max(grilleI[i2][j1],sn))<f5)
                if ((grilleI[i1][j2]>=f5)&&(grilleI[i][j2]>=f5)&&(grilleI[i2][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i2][j1])<f5)
            if ((sn=max(grilleD[i2][j],sn))<f5)
              if ((sn=max(grilleD[i2][j2],sn))<f5)
                if ((grilleD[i1][j1]>=f5)&&(grilleD[i1][j]>=f5)&&(grilleD[i1][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i1][j2])<f5)
            if ((sn=max(grilleI[i][j2],sn))<f5)
              if ((sn=max(grilleI[i2][j2],sn))<f5)
                if ((grilleI[i1][j1]>=f5)&&(grilleI[i][j1]>=f5)&&(grilleI[i2][j1]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i1][j])<f5)
            if ((sn=max(grilleD[i][j2],sn))<f5)
                if ((grilleD[i][j1]>=f5)&&(grilleD[i2][j1]>=f5)&&(grilleD[i2][j]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i1][j])<f5)
            if ((sn=max(grilleI[i][j1],sn))<f5)
                if ((grilleI[i][j2]>=f5)&&(grilleI[i2][j]>=f5)&&(grilleI[i2][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i][j1])<f5)
            if ((sn=max(grilleD[i2][j],sn))<f5)
                if ((grilleD[i1][j]>=f5)&&(grilleD[i1][j2]>=f5)&&(grilleD[i][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i][j2])<f5)
            if ((sn=max(grilleI[i2][j],sn))<f5)
                if ((grilleI[i1][j1]>=f5)&&(grilleI[i1][j]>=f5)&&(grilleI[i][j1]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }


  }

  LibereGrille(grilleI);
  LibereImage(imaI);
  LibereGrille(grilleD);
  LibereCanal(canL);
  return(imaD);
}

//*****************************************************************************
// Amincissement (par rapport à imS2) d'une image (imS1)
// n=nb d'itération cet algo s'effectue en parallèle
// Risque de déplacement du squelette (Amincir est plus sûr)
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image Amincit2R(Image imS1,Image imD,int n){

  Reel f1,f2,f3,f4,f5,f6,f7,f8,f9 ;
  int k,i,j,i1,i2,w,h ;
  Reel sn,m ;
  int fin ;
  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);
  if (n==0) n=max(w,h);

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

  // amincissement
  k=0; fin=0;
  while((k++<n)&&(!fin)){
    //Amincissement réseau carré
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      f2=grilleD[i1][0]; f3=grilleD[i1][1];
      f5=grilleD[i][0]; f6=grilleD[i][1];
      f8=grilleD[i2][0]; f9=grilleD[i2][1];
      for(j=2;j<w;j++){

        // voisinage de m:  f1  f2  f3
        //                  f4 m=f5 f6
        //                  f7  f8  f9
        f1=f2; f2=f3; f3=grilleD[i1][j];
        f4=f5; f5=f6; f6=grilleD[i][j];
        f7=f8; f8=f9; f9=grilleD[i2][j]; m=f5 ;

          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=max(f1,max(f2,f3)))<m)
            if ((f7>=f5)&&(f8>=f5)&&(f9>=f5)) m=sn;
          if ((sn=max(f1,max(f4,f7)))<m)
            if ((f3>=f5)&&(f6>=f5)&&(f9>=f5)) m=sn;
          if ((sn=max(f7,max(f8,f9)))<m)
            if ((f1>=f5)&&(f2>=f5)&&(f3>=f5)) m=sn;
          if ((sn=max(f3,max(f6,f9)))<m)
            if ((f1>=f5)&&(f4>=f5)&&(f7>=f5)) m=sn;
          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=max(f2,f6))<m)
            if ((f4>=f5)&&(f7>=f5)&&(f8>=f5)) m=sn;
          if ((sn=max(f2,f4))<m)
            if ((f6>=f5)&&(f8>=f5)&&(f9>=f5)) m=sn;
          if ((sn=max(f4,f8))<m)
            if ((f2>=f5)&&(f3>=f5)&&(f6>=f5)) m=sn;
          if ((sn=max(f6,f8))<m)
            if ((f1>=f5)&&(f2>=f5)&&(f4>=f5)) m=sn;

        grilleD[i][j-1]=m ;// Niveau du nouveau pixel
        fin=fin && (m==f5) ;
        f5=m ;
      }
    }
  }

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





//*****************************************************************************
// Amincissement conditionnel (par rapport à imS2) d'une image (imS1)
// imS2 sert de masque pour indiquer les pixels à amincir : pixels de niveau >0
// n=nb d'itération. Algo en série
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image AmincitCondR(Image imS1,Image imS2,Image imD,int n){

  Reel f5 ;
  int k,i,j,i1,i2,j1,j2,w,h ;
  Reel sn ;
  int fin ;
  Image imI=NULL;
  Canal canL,canM;
  Reel **grilleI;
  Reel **grilleD;
  Reel **grilleM;


  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 ((canM=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return (NULL);
  if ((imI=CreeImageDest(imS1,imI,T_REEL))==NULL) return(NULL);
  if ((grilleI=(Reel**)CreeGrille(imI,Z_FENETRE))==NULL) return (NULL);
  if ((grilleM=(Reel**)CreeGrille(imS2,Z_FENETRE))==NULL) return (NULL) ;
  if (n==0) n=max(w,h);

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

  // amincissement
  k=0; fin=0;

  while((k++<n)&&(!fin)){
    //Amincissement réseau carré
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i1][j1])<f5)
            if ((sn=max(grilleD[i1][j],sn))<f5)
              if ((sn=max(grilleD[i1][j2],sn))<f5)
                if ((grilleD[i2][j1]>=f5)&&(grilleD[i2][j]>=f5)&&(grilleD[i2][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i1][j1])<f5)
            if ((sn=max(grilleI[i][j1],sn))<f5)
              if ((sn=max(grilleI[i2][j1],sn))<f5)
                if ((grilleI[i1][j2]>=f5)&&(grilleI[i][j2]>=f5)&&(grilleI[i2][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i2][j1])<f5)
            if ((sn=max(grilleD[i2][j],sn))<f5)
              if ((sn=max(grilleD[i2][j2],sn))<f5)
                if ((grilleD[i1][j1]>=f5)&&(grilleD[i1][j]>=f5)&&(grilleD[i1][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i1][j2])<f5)
            if ((sn=max(grilleI[i][j2],sn))<f5)
              if ((sn=max(grilleI[i2][j2],sn))<f5)
                if ((grilleI[i1][j1]>=f5)&&(grilleI[i][j1]>=f5)&&(grilleI[i2][j1]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i1][j])<f5)
            if ((sn=max(grilleD[i][j2],sn))<f5)
                if ((grilleD[i][j1]>=f5)&&(grilleD[i2][j1]>=f5)&&(grilleD[i2][j]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i1][j])<f5)
            if ((sn=max(grilleI[i][j1],sn))<f5)
                if ((grilleI[i][j2]>=f5)&&(grilleI[i2][j]>=f5)&&(grilleI[i2][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i][j1])<f5)
            if ((sn=max(grilleD[i2][j],sn))<f5)
                if ((grilleD[i1][j]>=f5)&&(grilleD[i1][j2]>=f5)&&(grilleD[i][j2]>=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i][j2])<f5)
            if ((sn=max(grilleI[i2][j],sn))<f5)
                if ((grilleI[i1][j1]>=f5)&&(grilleI[i1][j]>=f5)&&(grilleI[i][j1]>=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
  }

  LibereGrille(grilleM);
  LibereGrille(grilleI);
  LibereImage(imI);
  LibereGrille(grilleD);
  LibereCanal(canM);
  LibereCanal(canL);
  return(imD);
}




//*****************************************************************************
// Amincissement conditionnel (par rapport à imS2) d'une image (imS1)
// imS2 sert de masque pour indiquer les pixels à amincir : pixels de niveau >0
// n=nb d'itération cet algo s'effectue en parallèle
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image AmincitCond2R(Image imS1,Image imS2,Image imD,int n){

  Reel f1,f2,f3,f4,f5,f6,f7,f8,f9 ;
  int k,i,j,i1,i2,w,h ;
  Reel sn,m ;
  int fin ;
  Canal canL,canM;
  Reel **grilleD;
  Reel **grilleM;


  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 ((canM=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return (NULL);
  if ((grilleM=(Reel**)CreeGrille(imS2,Z_FENETRE))==NULL) return (NULL) ;
  if (n==0) n=max(w,h);

  // Initialisation des images
  for(i=0;i<h;i++){
    LitCanal(canL,grilleD[i]);
    LitCanal(canM,grilleM[i]);
  }

  // amincissement
  k=0; fin=0;
  while((k++<n)&&(!fin)){
    //Amincissement réseau carré
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      f2=grilleD[i1][0]; f3=grilleD[i1][1];
      f5=grilleD[i][0]; f6=grilleD[i][1];
      f8=grilleD[i2][0]; f9=grilleD[i2][1];
      for(j=2;j<w;j++){

        // voisinage de m:  f1  f2  f3
        //                  f4 m=f5 f6
        //                  f7  f8  f9
        f1=f2; f2=f3; f3=grilleD[i1][j];
        f4=f5; f5=f6; f6=grilleD[i][j];
        f7=f8; f8=f9; f9=grilleD[i2][j]; m=f5 ;

        // Amincicement sous la condition de imS2
        if (grilleM[i][j-1]>0){
          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=max(f1,max(f2,f3)))<m)
            if ((f7>=f5)&&(f8>=f5)&&(f9>=f5)) m=sn;
          if ((sn=max(f1,max(f4,f7)))<m)
            if ((f3>=f5)&&(f6>=f5)&&(f9>=f5)) m=sn;
          if ((sn=max(f7,max(f8,f9)))<m)
            if ((f1>=f5)&&(f2>=f5)&&(f3>=f5)) m=sn;
          if ((sn=max(f3,max(f6,f9)))<m)
            if ((f1>=f5)&&(f4>=f5)&&(f7>=f5)) m=sn;
          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=max(f2,f6))<m)
            if ((f4>=f5)&&(f7>=f5)&&(f8>=f5)) m=sn;
          if ((sn=max(f2,f4))<m)
            if ((f6>=f5)&&(f8>=f5)&&(f9>=f5)) m=sn;
          if ((sn=max(f4,f8))<m)
            if ((f2>=f5)&&(f3>=f5)&&(f6>=f5)) m=sn;
          if ((sn=max(f6,f8))<m)
            if ((f1>=f5)&&(f2>=f5)&&(f4>=f5)) m=sn;
        }
        grilleD[i][j-1]=m ;// Niveau du nouveau pixel
        fin=fin && (m==f5) ;
        f5=m ;
      }
    }
  }

  LibereGrille(grilleM);
  LibereGrille(grilleD);
  LibereCanal(canM);
  LibereCanal(canL);
  return(imD);
}



//*****************************************************************************
// Epaississements itératifs en série en niveau de gris
// n=nb d'itérations maxi (s'arrète avant s'il n'y a plus d'évolution)
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image EpaissitR(Image imaS,Image imaD,int n){
      
  Reel f5 ;
  int k,i,j,i1,i2,j1,j2,w,h ;
  Reel sn ;
  int fin ;
  Canal canL;
  Image imaI=NULL;
  Reel **grilleI;
  Reel **grilleD;


  if ((imaD=CreeImageDest(imaS,imaD,T_REEL))==NULL) return(NULL);
  LitTailleFenetre(imaS,&w,&h) ;
  if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return (NULL);
  if ((canL=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((imaI=CreeImageDest(imaS,imaI,T_REEL))==NULL) return(NULL);
  if ((grilleI=(Reel**)CreeGrille(imaI,Z_FENETRE))==NULL) return (NULL);
  if (n==0) n=max(w,h);

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


  k=0; fin=0;
  while((k++<n)&&(!fin)){

     //Epaississement réseau carré
     // On applique les différentes matrices de configuration
     // voisinage de m:  f1  f2  f3
     //                  f4 m=f5 f6
     //                  f7  f8  f9
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i1][j1])>f5)
            if ((sn=min(grilleD[i1][j],sn))>f5)
              if ((sn=min(grilleD[i1][j2],sn))>f5)
                if ((grilleD[i2][j1]<=f5)&&(grilleD[i2][j]<=f5)&&(grilleD[i2][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i1][j1])>f5)
            if ((sn=min(grilleI[i][j1],sn))>f5)
              if ((sn=min(grilleI[i2][j1],sn))>f5)
                if ((grilleI[i1][j2]<=f5)&&(grilleI[i][j2]<=f5)&&(grilleI[i2][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i2][j1])>f5)
            if ((sn=min(grilleD[i2][j],sn))>f5)
              if ((sn=min(grilleD[i2][j2],sn))>f5)
                if ((grilleD[i1][j1]<=f5)&&(grilleD[i1][j]<=f5)&&(grilleD[i1][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i1][j2])>f5)
            if ((sn=min(grilleI[i][j2],sn))>f5)
              if ((sn=min(grilleI[i2][j2],sn))>f5)
                if ((grilleI[i1][j1]<=f5)&&(grilleI[i][j1]<=f5)&&(grilleI[i2][j1]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i1][j])>f5)
            if ((sn=min(grilleD[i][j2],sn))>f5)
                if ((grilleD[i][j1]<=f5)&&(grilleD[i2][j1]<=f5)&&(grilleD[i2][j]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i1][j])>f5)
            if ((sn=min(grilleI[i][j1],sn))>f5)
                if ((grilleI[i][j2]<=f5)&&(grilleI[i2][j]<=f5)&&(grilleI[i2][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
          if ((sn=grilleD[i][j1])>f5)
            if ((sn=min(grilleD[i2][j],sn))>f5)
                if ((grilleD[i1][j]<=f5)&&(grilleD[i1][j2]<=f5)&&(grilleD[i][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
          if ((sn=grilleI[i][j2])>f5)
            if ((sn=min(grilleI[i2][j],sn))>f5)
                if ((grilleI[i1][j1]<=f5)&&(grilleI[i1][j]<=f5)&&(grilleI[i][j1]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }


  }

  LibereGrille(grilleI);
  LibereImage(imaI);
  LibereGrille(grilleD);
  LibereCanal(canL);
  return(imaD);
}



//*****************************************************************************
// Epaississement (par rapport à imS2) d'une image (imS1)
// n=nb d'itération cet algo s'effectue en parallèle
// Risque de déplacement du squelette (EpaissitR est plus sûr)
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image Epaissit2R(Image imS1,Image imD,int n){

  Reel f1,f2,f3,f4,f5,f6,f7,f8,f9 ;
  int k,i,j,i1,i2,w,h ;
  Reel sn,m ;
  int fin ;
  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);
  if (n==0) n=max(w,h);

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

  // Epaississement
  k=0; fin=0;
  while((k++<n)&&(!fin)){
    //Epaississement réseau carré
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      f2=grilleD[i1][0]; f3=grilleD[i1][1];
      f5=grilleD[i][0]; f6=grilleD[i][1];
      f8=grilleD[i2][0]; f9=grilleD[i2][1];
      for(j=2;j<w;j++){

        // voisinage de m:  f1  f2  f3
        //                  f4 m=f5 f6
        //                  f7  f8  f9
        f1=f2; f2=f3; f3=grilleD[i1][j];
        f4=f5; f5=f6; f6=grilleD[i][j];
        f7=f8; f8=f9; f9=grilleD[i2][j]; m=f5 ;

          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=min(f1,min(f2,f3)))>m)
            if ((f7<=f5)&&(f8<=f5)&&(f9<=f5)) m=sn;
          if ((sn=min(f1,min(f4,f7)))>m)
            if ((f3<=f5)&&(f6<=f5)&&(f9<=f5)) m=sn;
          if ((sn=min(f7,min(f8,f9)))>m)
            if ((f1<=f5)&&(f2<=f5)&&(f3<=f5)) m=sn;
          if ((sn=min(f3,min(f6,f9)))>m)
            if ((f1<=f5)&&(f4<=f5)&&(f7<=f5)) m=sn;
          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=min(f2,f6))>m)
            if ((f4<=f5)&&(f7<=f5)&&(f8<=f5)) m=sn;
          if ((sn=min(f2,f4))>m)
            if ((f6<=f5)&&(f8<=f5)&&(f9<=f5)) m=sn;
          if ((sn=min(f4,f8))>m)
            if ((f2<=f5)&&(f3<=f5)&&(f6<=f5)) m=sn;
          if ((sn=min(f6,f8))>m)
            if ((f1<=f5)&&(f2<=f5)&&(f4<=f5)) m=sn;

        grilleD[i][j-1]=m ;// Niveau du nouveau pixel
        fin=fin && (m==f5) ;
        f5=m ;
      }
    }
  }

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



//*****************************************************************************
// Epaississement conditionnel (par rapport à imS2) d'une image (imS1)
// imS2 sert de masque pour indiquer les pixels à epaissir : pixels de niveau >0
// n=nb d'itération. Algo en série
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image EpaissitCondR(Image imS1,Image imS2,Image imD,int n){

  Reel f5 ;
  int k,i,j,i1,i2,j1,j2,w,h ;
  Reel sn ;
  int fin ;
  Image imI=NULL;
  Canal canL,canM;
  Reel **grilleI;
  Reel **grilleD;
  Reel **grilleM;


  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 ((canM=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return (NULL);
  if ((imI=CreeImageDest(imS1,imI,T_REEL))==NULL) return(NULL);
  if ((grilleI=(Reel**)CreeGrille(imI,Z_FENETRE))==NULL) return (NULL);
  if ((grilleM=(Reel**)CreeGrille(imS2,Z_FENETRE))==NULL) return (NULL) ;
  if (n==0) n=max(w,h);

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

  // Epaississement
  k=0; fin=0;

  while((k++<n)&&(!fin)){
    //Epaississement réseau carré
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i1][j1])>f5)
            if ((sn=min(grilleD[i1][j],sn))>f5)
              if ((sn=min(grilleD[i1][j2],sn))>f5)
                if ((grilleD[i2][j1]<=f5)&&(grilleD[i2][j]<=f5)&&(grilleD[i2][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i1][j1])>f5)
            if ((sn=min(grilleI[i][j1],sn))>f5)
              if ((sn=min(grilleI[i2][j1],sn))>f5)
                if ((grilleI[i1][j2]<=f5)&&(grilleI[i][j2]<=f5)&&(grilleI[i2][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i2][j1])>f5)
            if ((sn=min(grilleD[i2][j],sn))>f5)
              if ((sn=min(grilleD[i2][j2],sn))>f5)
                if ((grilleD[i1][j1]<=f5)&&(grilleD[i1][j]<=f5)&&(grilleD[i1][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i1][j2])>f5)
            if ((sn=min(grilleI[i][j2],sn))>f5)
              if ((sn=min(grilleI[i2][j2],sn))>f5)
                if ((grilleI[i1][j1]<=f5)&&(grilleI[i][j1]<=f5)&&(grilleI[i2][j1]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i1][j])>f5)
            if ((sn=min(grilleD[i][j2],sn))>f5)
                if ((grilleD[i][j1]<=f5)&&(grilleD[i2][j1]<=f5)&&(grilleD[i2][j]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i1][j])>f5)
            if ((sn=min(grilleI[i][j1],sn))>f5)
                if ((grilleI[i][j2]<=f5)&&(grilleI[i2][j]<=f5)&&(grilleI[i2][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleD[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleD[i][j1])>f5)
            if ((sn=min(grilleD[i2][j],sn))>f5)
                if ((grilleD[i1][j]<=f5)&&(grilleD[i1][j2]<=f5)&&(grilleD[i][j2]<=f5))
                  {f5=sn; fin=0 ;}
        grilleI[i][j]=f5 ;
      }
    }
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      for(j=1;j<(w-1);j++){
        j1=j-1; j2=j+1;
        f5=grilleI[i][j] ;
        if (grilleM[i][j]>0)
          if ((sn=grilleI[i][j2])>f5)
            if ((sn=min(grilleI[i2][j],sn))>f5)
                if ((grilleI[i1][j1]<=f5)&&(grilleI[i1][j]<=f5)&&(grilleI[i][j1]<=f5))
                  {f5=sn; fin=0 ;}
        grilleD[i][j]=f5 ;
      }
    }
  }

  LibereGrille(grilleM);
  LibereGrille(grilleI);
  LibereImage(imI);
  LibereGrille(grilleD);
  LibereCanal(canM);
  LibereCanal(canL);
  return(imD);
}



//*****************************************************************************
// Epaississement conditionnel (par rapport à imS2) d'une image (imS1)
// imS2 sert de masque pour indiquer les pixels à epaissir : pixels de niveau >0
// n=nb d'itération cet algo s'effectue en parallèle
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image EpaissitCond2R(Image imS1,Image imS2,Image imD,int n){

  Reel f1,f2,f3,f4,f5,f6,f7,f8,f9 ;
  int k,i,j,i1,i2,w,h ;
  Reel sn,m ;
  int fin ;
  Canal canL,canM;
  Reel **grilleD;
  Reel **grilleM;


  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 ((canM=CreeCanal(imS2,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((grilleD=(Reel**)CreeGrille(imD,Z_FENETRE))==NULL) return (NULL);
  if ((grilleM=(Reel**)CreeGrille(imS2,Z_FENETRE))==NULL) return (NULL) ;
  if (n==0) n=max(w,h);

  // Initialisation des images
  for(i=0;i<h;i++){
    LitCanal(canL,grilleD[i]);
    LitCanal(canM,grilleM[i]);
  }

  // Epaississement
  k=0; fin=0;
  while((k++<n)&&(!fin)){
    //Epaississement réseau carré
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      f2=grilleD[i1][0]; f3=grilleD[i1][1];
      f5=grilleD[i][0]; f6=grilleD[i][1];
      f8=grilleD[i2][0]; f9=grilleD[i2][1];
      for(j=2;j<w;j++){

        // voisinage de m:  f1  f2  f3
        //                  f4 m=f5 f6
        //                  f7  f8  f9
        f1=f2; f2=f3; f3=grilleD[i1][j];
        f4=f5; f5=f6; f6=grilleD[i][j];
        f7=f8; f8=f9; f9=grilleD[i2][j]; m=f5 ;

        // Epaississement sous la condition de imS2
        if (grilleM[i][j-1]>0){
          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=min(f1,min(f2,f3)))>m)
            if ((f7<=f5)&&(f8<=f5)&&(f9<=f5)) m=sn;
          if ((sn=min(f1,min(f4,f7)))>m)
            if ((f3<=f5)&&(f6<=f5)&&(f9<=f5)) m=sn;
          if ((sn=min(f7,min(f8,f9)))>m)
            if ((f1<=f5)&&(f2<=f5)&&(f3<=f5)) m=sn;
          if ((sn=min(f3,min(f6,f9)))>m)
            if ((f1<=f5)&&(f4<=f5)&&(f7<=f5)) m=sn;
          // Famille 1 (Ref: Précis d'analyse d'image p 181)
          if ((sn=min(f2,f6))>m)
            if ((f4<=f5)&&(f7<=f5)&&(f8<=f5)) m=sn;
          if ((sn=min(f2,f4))>m)
            if ((f6<=f5)&&(f8<=f5)&&(f9<=f5)) m=sn;
          if ((sn=min(f4,f8))>m)
            if ((f2<=f5)&&(f3<=f5)&&(f6<=f5)) m=sn;
          if ((sn=min(f6,f8))>m)
            if ((f1<=f5)&&(f2<=f5)&&(f4<=f5)) m=sn;
        }
        grilleD[i][j-1]=m ;// Niveau du nouveau pixel
        fin=fin && (m==f5) ;
        f5=m ;
      }
    }
  }

  LibereGrille(grilleM);
  LibereGrille(grilleD);
  LibereCanal(canM);
  LibereCanal(canL);
  return(imD);
}



//*****************************************************************************
// Carte des distances géodésiques: distance 1 suivant les axes X et Y,
//  et sqrt(2) suivant les diagonales
// n=nb maxi d'itération (à peu près rayon max des particules)
// si n=0 poursuite jusqu'à stabilisation
//*****************************************************************************
Image CarteGeodR(Image imaS,Image imaD,int n){

  Reel f1,f2,f3,f4,f5,f6,f7,f8,f9 ;
  int k,i,j,i1,i2,w,h ;
  Reel d_diag,d_axe,racine2 ;
  int fin ;
  Image imaI=NULL;
  Canal canL;
  Reel **grilleI;
  Reel **grilleD;


  if ((imaD=CreeImageDest(imaS,imaD,T_REEL))==NULL) return(NULL);
  LitTailleFenetre(imaS,&w,&h) ;
  if ((grilleD=(Reel**)CreeGrille(imaD,Z_FENETRE))==NULL) return (NULL);
  if ((canL=CreeCanal(imaS,T_REEL,B_LIGNE,Z_FENETRE))==NULL) return (NULL);
  if ((imaI=CreeImageDest(imaS,imaI,T_REEL))==NULL) return(NULL);
  if ((grilleI=(Reel**)CreeGrille(imaI,Z_FENETRE))==NULL) return (NULL);
  if (n==0) n=max(w,h);

  // Initialisation des images
  for(i=0;i<h;i++){
    LitCanal(canL,grilleD[i]);
    for(j=0;j<w;j++)
      {
      if (grilleD[i][j]>0)
        grilleD[i][j]=grilleI[i][j]=max(w,h);
      else grilleI[i][j]=grilleD[i][j]=0;
      }
  }

  k=0; fin=0;
  racine2=sqrt(2);
  while((k++<n)&&(!fin)){
    fin=1 ;
    for(i=1;i<(h-1);i++){
      i1=i-1; i2=i+1;
      f2=grilleD[i1][0]; f3=grilleD[i1][1];
      f5=grilleD[i][0]; f6=grilleD[i][1];
      f8=grilleD[i2][0]; f9=grilleD[i2][1];
      for(j=2;j<w;j++){
        // voisinage de f5: f1  f2  f3
        //                  f4  f5  f6
        //                  f7  f8  f9
        f1=f2; f2=f3; f3=grilleD[i1][j];
        f4=f5; f5=f6; f6=grilleD[i][j];
        f7=f8; f8=f9; f9=grilleD[i2][j];
        d_diag=min(f1,min(f3,min(f7,f9)));// distance suivant les diagonales
        d_axe=min(f2,min(f4,min(f6,f8)));// distance suivant les axes X et Y
        if ((f5>d_diag)||(f5>d_axe))
          fin=((grilleI[i][j-1]=min(d_diag+racine2,d_axe+1))==f5) && fin ;
        else
          {grilleI[i][j-1]=f5;}
      }
    }
    // Recopie
    for(i=1;i<(h-1);i++)
      for(j=1;j<(w-1);j++)
        grilleD[i][j]=grilleI[i][j] ;
  }

  LibereGrille(grilleI);
  LibereImage(imaI);
  LibereCanal(canL);
  LibereGrille(grilleD);
  return(imaD);
}




//*****************************************************************************
// Efface les bords de l'image (particules qui touchent le bord)
//*****************************************************************************
Image EffaceBordR(Image imaS,Image imaD){

  int w,h ;


  if (imaS==NULL) return(NULL);
  LitTailleFenetre(imaS,&w,&h) ;
  if (TestImageConstR(imaS)) return (imaD=TransfereR(imaS,imaD)) ;
  imaD=EtaleR(imaS,imaD,1,0);
  EcritFenetre(imaD,0,0,w,1);
  imaD=NiveauR(imaD,imaD,0);
  EcritFenetre(imaD,0,0,1,h);
  imaD=NiveauR(imaD,imaD,0);
  EcritFenetre(imaD,0,h-1,w,1);
  imaD=NiveauR(imaD,imaD,0);
  EcritFenetre(imaD,w-1,0,1,h);
  imaD=NiveauR(imaD,imaD,0);
  EcritFenetre(imaD,0,0,w,h);
  imaD=RempliR(imaD,imaD,0,0,1,1);
  if (!TestImageConstR(imaD)) imaD=EtaleR(imaD,imaD,1,0);
  return (imaD) ;
}



