// use LoadGGImagePPM(const char* cName)
// and int SaveGGImagePPM(const char *fileN, GGImage *pImage)
// for PPM file IO
//struct 
//{
//	int	xsize;	        /* horizontal size of the image in Pixels */
//	int	ysize;	        /* vertical size of the image in Pixels */
//	unsigned char* data;	  /* pointer to first scanline of Image, PPM pixel 3 bytes
//                                 R, G, B; PGM pixel one byte */
//	int	span;		        /* byte offset between two scanlines, usually set to 0 */
// } GGImage;

#include "StdAfx.h"
#include "PPMandPGMlibrary.h"

//***************************************************************
// get file name without extension
//***************************************************************
char *getFileNameWithoutExtension(char *fileName, char *fileNameWithoutExtension )
{
	strcpy (fileNameWithoutExtension, fileName);
	char *pDot = strrchr (fileNameWithoutExtension, '.');
	*pDot=NULL;
	return fileNameWithoutExtension;
}





//***************************************************************
// get file name extension
//***************************************************************
char *getFileNameExtension(char *fileName, char *fileNameExtension )
{
	char *pDot = strrchr (fileName, '.');
	strcpy(fileNameExtension, ++pDot);
	return fileNameExtension;
}





// upper left corner of the pGGImageGrayScale: (0,0)
// the pGGImageGrayScale is a gray picture!!
//***************************************************************
// crop image
//***************************************************************
GGImage *CropImage(GGImage *pSrc, int nXL, int nYL, int nXR, int nYR)
{
	nXL = MIN(MAX(nXL, 0), pSrc->xsize - 1);
	nXR = MIN(MAX(nXR, 0), pSrc->xsize - 1);
	nYL = MIN(MAX(nYL, 0), pSrc->ysize - 1);
	nYR = MIN(MAX(nYR, 0), pSrc->ysize - 1);

	GGImage *pCrop = AllocGGImage(nXR - nXL + 1, nYR - nYL + 1);

	if (!pCrop)
	{
		 printf("Error in CropImage\n");
		 exit(1);
	}
	unsigned char *cSrc, *cCrop = pCrop->data;
	cSrc = pSrc->data;
	for (int y = nYL; y <= nYR; y ++) 
	{
		for (int x = nXL; x <= nXR; x++)
		{
			*cCrop++ = cSrc[x + y * pSrc->xsize];
		}
	}
	return pCrop;
}




//***************************************************************
// mirror pgm image
//***************************************************************
GGImage *MirrorImagePGM( GGImage *pSrc )
{
	GGImage *pMirror = AllocGGImage(pSrc->xsize, pSrc->ysize);
	if (!pMirror)
	{
		 printf("error in MirrorImagePGM\n");
		 exit(1);
	}
	
	unsigned char *cSrc		= pSrc->data;
	unsigned char *cMirror	= pMirror->data + pMirror->xsize - 1;

	for (int y = 0 ; y < pSrc->ysize ; y ++) 
	{
		for (int x = 0; x < pSrc->xsize ; x++)
		{
			*cMirror = cSrc[x + y * pSrc->xsize];
			cMirror --;
		}

		cMirror += 2 * pMirror->xsize;
	}
	return pMirror;
}



//***************************************************************
// mirror ppm image
//***************************************************************
GGImage *MirrorImagePPM( GGImage *pSrc )
{
	GGImage *pMirror = AllocGGImagePPM(pSrc->xsize, pSrc->ysize);
	if (!pMirror)
	{
		 printf("error in MirrorImagePPM\n");
		 exit(1);
	}
	
	unsigned char *cSrc		= pSrc->data;
	unsigned char *cMirror	= pMirror->data + ( pMirror->xsize )*3 - 1 ;

	for (int y = 0 ; y < pSrc->ysize ; y ++) 
	{
		for (int x = 0; x < pSrc->xsize ; x++)
		{
			*cMirror = cSrc[3*x+2 + y * pSrc->xsize *3];
			cMirror --;
			
			*cMirror = cSrc[3*x+1 + y * pSrc->xsize *3];
			cMirror --;
			
			*cMirror = cSrc[3*x+0 + y * pSrc->xsize *3];
			cMirror --;

		}

		cMirror += ( 2 * pMirror->xsize )*3  ;
	}
	return pMirror;
}




//***************************************************************
// rotate pgm image
//***************************************************************
GGImage *RotatePGMImage( GGImage *pSrc , int angle)
{
	double angleRad = angle*PI/180;
	
	double angleRad90;
	if	(
		(angleRad >= 0) && (angleRad <= PI/2) 
		||
		(angleRad <  0) && (angleRad >= - PI/2)
		) 
	{
		angleRad90 = fabs( angleRad );
	}
	else if ( 
		(angleRad > PI/2) && (angleRad <= PI)
		||
		(angleRad < - PI/2) && (angleRad >= PI)
		) 
	{
		angleRad90 = fabs( PI - angleRad );
	}
	
	/*
	else if ( (angleRad > PI) && (angleRad <= 3/2*PI) ) 
	{
		angleRad90 = PI - angleRad;
	}
	else if ( (angleRad > 3/2*PI) && (angleRad <= 2*PI) ) 
	{
		angleRad90 = 2*PI - angleRad;
	}
	*/
	  
	else 
	{
		printf("Error in RotatePGMImage: Only angles in the Interval [-PI,PI] are allowed.\n");
		exit (1);
	}

	int xmax = pSrc->xsize * cos(angleRad90) + pSrc->ysize * sin(angleRad90) + border;
	int ymax = pSrc->xsize * sin(angleRad90) + pSrc->ysize * cos(angleRad90) + border;
	
	
	GGImage *pRotated = AllocGGImage(xmax, ymax);
	if (!pRotated)
	{
		 printf("Error in RotatePGMImage\n");
		 exit(1);
	}
	
	double x1m = pSrc->xsize / 2;
	double y1m = pSrc->ysize / 2;
	double x2m = pRotated->xsize / 2;
	double y2m = pRotated->ysize / 2;


	unsigned char *cSrc		= pSrc->data;
	unsigned char *cRotated	= pRotated->data; 

	int xs; // x in the source picture
	int ys;
	int ysMath;
	int yMath;

	for ( int y = 0 ; y< pRotated->ysize ; y ++ )
	{
		for ( int x = 0 ; x < pRotated->xsize ; x++ )
		{
			
			yMath = pRotated->ysize - y;
			
			// rotation matrix rotates anti clockwise for a system where x 
			// goes to the right and y goes up
			xs		= (int) (   cos(angleRad)*(x-x2m) + sin(angleRad)*(yMath-y2m) + x1m + 0.5);
			ysMath	= (int) ( - sin(angleRad)*(x-x2m) + cos(angleRad)*(yMath-y2m) + y1m + 0.5);
			
			ys = pSrc->ysize - ysMath;

			
			// test if pixel is in the source image
			if	( 
				( xs >= 0 )
				&&
				( xs < pSrc->xsize )
				&&
				( ys >= 0 )
				&&
				( ys < pSrc->ysize )
				&&
				( xs + ys * pSrc->xsize < pSrc->xsize * pSrc->ysize )
				)
			{
				cRotated[x + y * pRotated->xsize] = cSrc[xs + ys * pSrc->xsize];
			}
			else
			{
				cRotated[x + y * pRotated->xsize] = 0;
			}
		}
			// warum vor cSrc kein *?
	}

	return pRotated;
}




// angle in grad 
void getCoordinatesInRotatedPGMImage(
				double angle, 
				GGImage *pSrc,		GGImage *pRotated,
				int xSource,		int ySource, 
				double *xRotated,	double *yRotated )
{
	double x1m = pSrc->xsize / 2;
	double y1m = pSrc->ysize / 2;
	double x2m = pRotated->xsize / 2;
	double y2m = pRotated->ysize / 2;
	
	int ySourceMath = pSrc->ysize - ySource;
	double angleRad = angle*PI/180;
	*xRotated= ( cos(angleRad)*(xSource-x1m) - sin(angleRad)*(ySourceMath-y1m) +x2m );
	double yRotatedMath= ( + sin(angleRad)*(xSource-x1m) + cos(angleRad)*(ySourceMath-y1m) +y2m );
	*yRotated= pRotated->ysize - yRotatedMath; 
}






//***************************************************************
// rotate ppm image
//***************************************************************
GGImage *RotatePPMImage( GGImage *pSrc , int angle)
{
	double angleRad = angle*PI/180;
	
	double angleRad90;
	if	(
		(angleRad >= 0) && (angleRad <= PI/2) 
		||
		(angleRad < 0 ) && (angleRad >= - PI/2)
		) 
	{
		angleRad90 = fabs( angleRad );
	}
	else if ( 
		(angleRad > PI/2) && (angleRad <= PI)
		||
		(angleRad < - PI/2) && (angleRad >= PI)
		) 
	{
		angleRad90 = fabs( PI - angleRad );
	}
	
	/*
	else if ( (angleRad > PI) && (angleRad <= 3/2*PI) ) 
	{
		angleRad90 = PI - angleRad;
	}
	else if ( (angleRad > 3/2*PI) && (angleRad <= 2*PI) ) 
	{
		angleRad90 = 2*PI - angleRad;
	}
	*/
	  
	else 
	{
		printf("Error in RotatePPMImage: Only angles in the Interval [-PI,PI] are allowed.\n");
		exit (1);
	}

	int xmax = pSrc->xsize * cos(angleRad90) + pSrc->ysize * sin(angleRad90) + border;
	int ymax = pSrc->xsize * sin(angleRad90) + pSrc->ysize * cos(angleRad90) + border;
	
	
	GGImage *pRotated = AllocGGImagePPM(xmax, ymax);
	if (!pRotated)
	{
		 printf("Error in RotatePGMImage\n");
		 exit(1);
	}
	
	double x1m = pSrc->xsize / 2;
	double y1m = pSrc->ysize / 2;
	double x2m = pRotated->xsize / 2;
	double y2m = pRotated->ysize / 2;


	unsigned char *cSrc		= pSrc->data;
	unsigned char *cRotated	= pRotated->data; 

	int xs; // x in the source picture
	int ys;
	int ysMath;
	int yMath;

	for ( int y = 0 ; y< pRotated->ysize ; y ++ )
	{
		for ( int x = 0 ; x < pRotated->xsize ; x++ )
		{
			//printf("x: %d     y: %d \n",x,y);
			
			
			yMath = pRotated->ysize - y;
			
			xs		= (int) (   cos(angleRad)*(x-x2m) + sin(angleRad)*(yMath-y2m) + x1m + 0.5);
			ysMath	= (int) ( - sin(angleRad)*(x-x2m) + cos(angleRad)*(yMath-y2m) + y1m + 0.5);
			
			ys = pSrc->ysize - ysMath;


			// test if pixel is in the source image
			if	( 
				( xs >= 0 )
				&&
				( xs < pSrc->xsize )
				&&
				( ys >= 0 )
				&&
				( ys < pSrc->ysize )
				&&
				( xs + ys * pSrc->xsize < pSrc->xsize * pSrc->ysize )
				)
			{
				// red
				cRotated[(x + y * pRotated->xsize)*3] = cSrc[(xs + ys * pSrc->xsize)*3];
				
				// green
				cRotated[(x + y * pRotated->xsize)*3 + 1] = cSrc[(xs + ys * pSrc->xsize)*3 +1];
		
				// blue
				cRotated[(x + y * pRotated->xsize)*3 + 2] = cSrc[(xs + ys * pSrc->xsize)*3 +2];
		
			}
			else
			{
				// red
				cRotated[(x + y * pRotated->xsize)*3] = 0;
				
				// green
				cRotated[(x + y * pRotated->xsize)*3 + 1] = 0;
		
				// blue
				cRotated[(x + y * pRotated->xsize)*3 + 2] = 255;
		
			}
		}
			// warum vor cSrc kein *?
	}

	return pRotated;
}





// load pgm 
GGImage *LoadGGImagePGM(const char* cName)
{
	int	status = 0;
	FILE *file=fopen(cName, "rb");
	GGImage *pGGImage;
	static char magicBuf[20];
	unsigned int w, h;
	char ch;

	if (!file) 
 	{
		printf("LoadGGImagePGM: can't find %s\n", cName);
 		return NULL;
 	}   
	fscanf(file, "%s\n", magicBuf);

	if (strncmp(magicBuf, "P5", 2) != 0)
 	{
 		printf("LoadGGImagePGM: wrong image format %s\n", cName);
 		return NULL;
 	}   

	/* read comments */
	fread(&ch, sizeof(char), 1, file);
	if (ch == '#')
 	do
  	{ 
  		do 
   			fread(&ch, sizeof(char), 1, file); 
  		while (ch!='\n');
  		fread(&ch, sizeof(char), 1, file);
  	} 
 	while (ch=='#');
    
	fseek(file, -1L, 1);

    /* size of image */
    fscanf(file, "%d %d\n", &w, &h);


	pGGImage = AllocGGImage(w,h);


/*
    if ((pGGImage = (GGImage *) malloc(sizeof(GGImage))) == NULL)
 	{
 		printf("LoadMask_Left: no memory\n");
 		return NULL;
 	}
    if ((pGGImage->data = (unsigned char*) 
                         malloc(sizeof(unsigned char) * w * h)) == NULL)
 	{
 		printf("LoadMask_Left: no memory\n");
 		return NULL;
 	}

    pGGImage->xsize = w;
    pGGImage->ysize = h;

    pGGImage->span = w;

*/



    do fread(&ch, sizeof(char), 1, file); while (ch!='\n');



    /* read data */
    fread(pGGImage->data, w * h, 1, file);
	
    fclose(file); 

    return pGGImage;
}





// load ppm
GGImage *LoadGGImagePPM(const char* cName)
{
    int	status = 0;
    FILE *file=fopen(cName, "rb");
    GGImage *pGGImage;
    static char magicBuf[20];
    unsigned int w, h;
	char ch;
	
    if (!file) 
 	{
 		printf("LoadGGImagePGM: can't find %s\n", cName);
 		return NULL;
 	}   
    fscanf(file, "%s\n", magicBuf);

    if (strncmp(magicBuf, "P6", 2) != 0)
 	{
 		printf("LoadGGImagePGM: wrong image format %s\n", cName);
 		return NULL;
 	}   

    /* read comments */
    fread(&ch, sizeof(char), 1, file);
    if (ch == '#')
 	do
 	{	 
  		do 
   		fread(&ch, sizeof(char), 1, file); 
  		while (ch!='\n');
  		fread(&ch, sizeof(char), 1, file);
  	} 
 	while (ch=='#');
    
    fseek(file, -1L, 1);

    /* size of image */
    fscanf(file, "%d %d\n", &w, &h);


	pGGImage = AllocGGImagePPM(w,h);

/*
    if ((pGGImage = (GGImage *) malloc(sizeof(GGImage))) == NULL)
 	{
 		printf("LoadMask_Left: no memory\n");
 		return NULL;
 	}
    if ((pGGImage->data = (unsigned char*) 
                         malloc(sizeof(unsigned char) * 3 * w * h)) == NULL)
 	{
 		printf("LoadMask_Left: no memory\n");
 		return NULL;
 	}
    pGGImage->xsize = w;
    pGGImage->ysize = h;
    pGGImage->span = w;
*/


	do fread(&ch, sizeof(char), 1, file); while (ch!='\n');

    /* read data */
    fread(pGGImage->data, 3 * w * h, 1, file);

    fclose(file); 

    return pGGImage;
}




// allocated memory for GRAY pictures
GGImage *AllocGGImage(int nW, int nH)
{
    GGImage *pOwnImage = NULL;

    if ((pOwnImage = (GGImage *) malloc(sizeof(GGImage))) == NULL)
 	{
 		printf("AllocGGImage: no memory\n");
 		return NULL;
 	}

    pOwnImage->xsize = nW;
    pOwnImage->ysize = nH;
    pOwnImage->span  = nW;

    if ((pOwnImage->data = (unsigned char*) 
                         malloc(sizeof(unsigned char) * nW * nH)) == NULL)
 	{
 		printf("AllocGGImage: no memory\n");
 		return NULL;
 	}
    return pOwnImage;
}




// allocated memory for ppm pictures
GGImage *AllocGGImagePPM(int nW, int nH)
{
    GGImage *pOwnImage = NULL;

    if ((pOwnImage = (GGImage *) malloc(sizeof(GGImage))) == NULL)
 	{
 		printf("AllocGGImagePPM: no memory\n");
 		return NULL;
 	}

    pOwnImage->xsize = nW;
    pOwnImage->ysize = nH;
    pOwnImage->span  = nW;

    if ((pOwnImage->data = (unsigned char*) 
                         malloc(sizeof(unsigned char) * 3 * nW * nH)) == NULL)
 	{
 		printf("AllocGGImagePPM: no memory\n");
 		return NULL;
 	}
    return pOwnImage;
}





void FreeGGImage(GGImage *pOwnImage)
{
    free(pOwnImage->data);
    free(pOwnImage);
}





int SaveGGImagePGM(const char *fileN, GGImage *pImage)
{
    FILE *file=NULL;

    if ((pImage))
 	{
 		file=fopen(fileN, "wb");
 		if (file)
  		{
  			fprintf(file, "P5\n%d %d\n%d\n",
  			pImage->xsize, pImage->ysize, 255);
  			fwrite(pImage->data, pImage->xsize * pImage->ysize, 1, file);
  			fclose(file);
  			return 0;
  		} 
 	}
    printf("SaveGGImagePGM: can't save %s\n", fileN); 

    return 1;
}






int SaveGGImagePPM(const char *fileN, GGImage *pImage)
{
    FILE *file=NULL;

    if ((pImage))
 	{
 		file=fopen(fileN, "wb");
 		if (file)
  		{
  			fprintf(file, "P6\n%d %d\n%d\n",
  			pImage->xsize, pImage->ysize, 255);
  			fwrite(pImage->data, 3 * pImage->xsize * pImage->ysize, 1, file);
  			fclose(file);
  			return 0;
  		} 
 	}
    printf("SaveGGImagePPM: can't save %s\n", fileN); 

    return 1;
}





// from BERND HEISELE (needed for rotation)


/**************************************************/
/* generate median values                         */
/**************************************************/
static int compare(unsigned char *i, unsigned char *j)
{
  if (*i>*j) return 1;
  if (*i<*j) return -1;
  return 0;
}

/**************************************************/
/* median filtering                    B. Heisele */
/**************************************************/

GGImage *ScaleSizeMedianPGM(GGImage *pSrcImage, int nX, int nY)
{

  register int		x, y, i, j;
  register float	x1, x2, y1, y2;
  unsigned char list[200];
  register int n = 0;
  int destArea, iIndex;
  int destW = nX,
      destH = nY,  
      imageW = pSrcImage->xsize,
      imageH = pSrcImage->ysize;
  int sourceW = imageW,
      sourceH = imageH;  
  unsigned char *destData = NULL,
                *imageData = pSrcImage->data;
  unsigned char	*image, 
                *dest;
  int		intens;
  int		autoscale=0;
  GGImage *pDestImage = NULL;

  pDestImage = AllocGGImage(nX, nY);
  destData = pDestImage->data;
  
  if ((sourceH<=0) | (sourceW<=0)) return 0;

  destArea=destW*destH;

  if (destW<=0)
  { if (sourceW<sourceH)
    { destW=destH*sourceW/sourceH;
      destArea=destH*destH;
      autoscale=destH-destW;
    }
    if (sourceW>=sourceH)
    { destW=destH;
      destH=destW*sourceH/sourceW;
      destArea=destW*destW;
    }
  }
  if (destH<=0)
  { if (sourceW<sourceH)
    { destH=destW;
      destW=destH*sourceW/sourceH;
      destArea=destH*destH;
      autoscale=destH-destW;
    }
    if (sourceW>=sourceH)
    { destH=destW*sourceH/sourceW;
      destArea=destW*destW;
    }
  }

  memset((char *)destData, 0, (unsigned int)destArea);

  image=imageData;
  dest=destData;
  destArea=destW*destH;/*!!*/
 
  y1=y2=0;

  for (y=0; y<destH; y++)
  { 
    y2+=(float)sourceH/destH;

    x1=x2=0;
    for (x=0; x<destW; x++)
    { 

      x2+=(float)sourceW/destW;
      intens=0;

      for (j=y1; j<y2; j++)
      { 
        iIndex = j * imageW + x1;
       
        for (i=x1; i<x2; i++)
        { 
        iIndex = MIN(iIndex, sourceW * sourceH - 1); 
        list[n++]= image[iIndex++];
        }
      }
      x1=x2;
      qsort(list, n, sizeof(unsigned char),
       (int(*)(const void *, const void *))compare);              
      *dest++ = list[n / 2];  
      n = 0;
    }

    if (autoscale)
    {
      dest+=autoscale;
    }
    y1=y2;
  }
  return pDestImage;
}


typedef struct
collut{
unsigned char R;
unsigned char G;
unsigned char B;

} ColLut;



GGImage *ScaleSizeMedianPPM(GGImage *pSrcImage, int nX, int nY)
{

  register int		x, y, i, j;
  register float	x1, x2, y1, y2;
  unsigned char list[200];
  register int n = 0;
  int destArea, iIndex;
  int destW = nX,
      destH = nY,  
      imageW = pSrcImage->xsize,
      imageH = pSrcImage->ysize;
  int sourceW = imageW,
      sourceH = imageH;  
  unsigned char *destData = NULL,
                *imageData = pSrcImage->data;
  unsigned char	*image, 
                *dest;
  int		intens;
  int		autoscale=0;
  GGImage *pDestImage = NULL;
  ColLut ColList[256];

  pDestImage = AllocGGImagePPM(nX, nY);
  destData = pDestImage->data;
  
  if ((sourceH<=0) | (sourceW<=0)) return 0;

  destArea=destW*destH;

  if (destW<=0)
  { if (sourceW<sourceH)
    { destW=destH*sourceW/sourceH;
      destArea=destH*destH;
      autoscale=destH-destW;
    }
    if (sourceW>=sourceH)
    { destW=destH;
      destH=destW*sourceH/sourceW;
      destArea=destW*destW;
    }
  }
  if (destH<=0)
  { if (sourceW<sourceH)
    { destH=destW;
      destW=destH*sourceW/sourceH;
      destArea=destH*destH;
      autoscale=destH-destW;
    }
    if (sourceW>=sourceH)
    { destH=destW*sourceH/sourceW;
      destArea=destW*destW;
    }
  }

  memset((char *)destData, 0, (unsigned int)3 * destArea);

  image=imageData;
  dest=destData;
  destArea=destW*destH;/*!!*/
 
  y1=y2=0;

  for (y=0; y<destH; y++)
  { 
    y2+=(float)sourceH/destH;

    x1=x2=0;
    for (x=0; x<destW; x++)
    { 

      x2+=(float)sourceW/destW;
      intens=0;

      for (j=y1; j<y2; j++)
      { 
        iIndex = j * imageW + x1;
       
        for (i=x1; i<x2; i++)
        { 
        iIndex = MIN(iIndex, sourceW * sourceH - 1); 
        list[n] = (image[3 * iIndex] + image[3 * iIndex + 1] + image[3 * iIndex + 2]) / 3;
        ColList[list[n]].R = image[3 * iIndex]; 
        ColList[list[n]].G = image[3 * iIndex + 1];
        ColList[list[n++]].B = image[3 * iIndex++ + 2]; 
        }
      }
      x1=x2;
      qsort(list, n, sizeof(unsigned char),
       (int(*)(const void *, const void *))compare);              
      *dest++ = ColList[list[n / 2]].R;  
      *dest++ = ColList[list[n / 2]].G;  
      *dest++ = ColList[list[n / 2]].B;  
      n = 0;
    }

    if (autoscale)
    {
      dest+=autoscale;
    }
    y1=y2;
  }
  return pDestImage;
}



GGImage *ScaleSizeMeanPPM(GGImage *pSrcImage, int nX, int nY)
{

  register int		x, y, i, j;
  register float	x1, x2, y1, y2;
   register int n = 0;
  int destArea, iIndex;
  int destW = nX,
      destH = nY,  
      imageW = pSrcImage->xsize,
      imageH = pSrcImage->ysize;
  int sourceW = imageW,
      sourceH = imageH;  
  unsigned char *destData = NULL,
                *imageData = pSrcImage->data;
  unsigned char	*image, 
                *dest;
  int		intens;
  int		autoscale=0;
  GGImage *pDestImage = NULL;
 
  pDestImage = AllocGGImagePPM(nX, nY);
  destData = pDestImage->data;
  
  if ((sourceH<=0) | (sourceW<=0)) return 0;

  destArea=destW*destH;

  if (destW<=0)
  { if (sourceW<sourceH)
    { destW=destH*sourceW/sourceH;
      destArea=destH*destH;
      autoscale=destH-destW;
    }
    if (sourceW>=sourceH)
    { destW=destH;
      destH=destW*sourceH/sourceW;
      destArea=destW*destW;
    }
  }
  if (destH<=0)
  { if (sourceW<sourceH)
    { destH=destW;
      destW=destH*sourceW/sourceH;
      destArea=destH*destH;
      autoscale=destH-destW;
    }
    if (sourceW>=sourceH)
    { destH=destW*sourceH/sourceW;
      destArea=destW*destW;
    }
  }

  memset((char *)destData, 0, (unsigned int)3 * destArea);

  image=imageData;
  dest=destData;
  destArea=destW*destH;/*!!*/
 
  y1=y2=0;
  int blueCounter, faceCounter, r,g,b;
	

  for (y=0; y<destH; y++)
  { 
    y2+=(float)sourceH/destH;

    x1=x2=0;
    for (x=0; x<destW; x++)
    { 

      x2+=(float)sourceW/destW;
      intens=0;

		r=0;
		g=0;
		b=0;
		blueCounter=0;
		faceCounter=0;

      for (j=y1; j<y2; j++)
      { 
        iIndex = j * imageW + x1;
       
        for (i=x1; i<x2; i++)
        { 
        iIndex = MIN(iIndex, sourceW * sourceH - 1); 
        
		
	
		
		if		(
			( image[3 * iIndex] == 0 )
			&&
			( image[3 * iIndex + 1] == 0 )
			&&
			( image[3 * iIndex + 2] == 255 )
				)
		{
			blueCounter ++;
		}
		else
		{
			faceCounter ++;
			r += image[3 * iIndex];
			g += image[3 * iIndex + 1];
			b += image[3 * iIndex + 2];
        }
		
		
		
	
        }
      }
      x1=x2;
      if (blueCounter<faceCounter)
	  //if (blueCounter==0)
	  {

		  *dest++ = r/faceCounter;
		  *dest++ = g/faceCounter;
		  *dest++ = b/faceCounter;
	  }
		else
		{
			*dest++ = 0;
			*dest++ = 0;
			*dest++ = 255;
		}
	  
		n = 0;
    }

    if (autoscale)
    {
      dest+=autoscale;
    }
    y1=y2;
  }
  return pDestImage;
}

