www.pudn.com > EZW_.rar > IMAGE.C


#include "image.h" 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* Some of the code are from elsewhere. The PGM routines are taken from  
 * G. Daivs code. 
 * 
 * Mow-Song, Ng 2/9/2002 
 * msng@mmu.edu.my 
 * http://www.pesona.mmu.edu.my/~msng 
 * 
 * I do not claim copyright to the code, but if you use them or modify them, 
 * please drop me a mail. 
 * 
 */ 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int SetImage(PIMAGE pimageSrc, unsigned char val) 
{ 
	if (pimageSrc->pixel[0] != NULL){ 
		memset(pimageSrc->pixel[0], val, (pimageSrc->xsize) * (pimageSrc->ysize) * sizeof(unsigned char)); 
		return 1; 
	} 
	else{ 
		return 0; 
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int ImageDynamicRange(PIMAGE pimage, unsigned char *MaxPixel, unsigned char *MinPixel) 
{ 
	unsigned char TempPixel; 
	int i, j; 
 
	*MaxPixel=MIN_GREY; 
	*MinPixel=MAX_GREY; 
 
	if (pimage->pixel[0] != NULL){ 
 
		for (j=0; jysize; j++){ 
			for (i=0; ixsize; i++){ 
				 
				TempPixel=pimage->pixel[j][i]; 
				 
				if (TempPixel > *MaxPixel){ 
					*MaxPixel=TempPixel; 
				} 
				 
				if (TempPixel < *MinPixel){ 
					*MinPixel=TempPixel; 
				} 
			} 
		}	 
		 
		return 1; 
	} 
	else{ 
		return 0; 
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PIMAGE ReadRawGreyFile(int xsize, int ysize, char *filename) 
{    
   int i; 
   PIMAGE pimage; 
   FILE *fp; 
	 
   pimage = (PIMAGE)malloc(sizeof(IMAGE)); 
   pimage->xsize=xsize; 
   pimage->ysize=ysize; 
	 
   /* Allocate memory */ 
   if(!ImageBufferAlloc(pimage)){ 
      free(pimage); 
      return NULL; 
   } 
	 
   /* open the file */ 
   if ((fp=fopen(filename, "rb"))==NULL){       
      ImageBufferFree(pimage); 
      free(pimage); 
      return NULL; 
   } 
	 
   i=fread(pimage->pixel[0], sizeof(unsigned char),  
      (pimage->xsize)*(pimage->ysize), fp); 
	 
   fclose(fp); 
	 
   if (i!=(pimage->ysize)*(pimage->xsize)){ 
      ImageBufferFree(pimage); 
      free(pimage); 
      return NULL; 
   } 
   else{ 
      return pimage; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PFIMAGE ReadRawGreyFileToFloat(int xsize, int ysize, char *filename) 
{    
   int i; 
   PFIMAGE pfimage; 
   FILE *fp; 
	unsigned char **temp, *tempLinear; 
 
	/* temporary buffer */ 
	temp = Byte_Alloc(ysize , xsize); 
	tempLinear=temp[0]; 
 
   if(temp == NULL){ 
      return NULL; 
   } 
  
	/* open the file */ 
   if ((fp=fopen(filename, "rb"))==NULL){       
      free(temp[0]); 
		return NULL; 
   } 
	 
   /* read the image */ 
	i=fread(temp[0], sizeof(unsigned char), xsize*ysize, fp); 
	fclose(fp); 
	 
	if (i!=ysize*xsize){ 
      free(temp[0]); 
      return NULL; 
   } 
 
   pfimage = (PFIMAGE)malloc(sizeof(FIMAGE)); 
   pfimage->xsize=xsize; 
   pfimage->ysize=ysize; 
	 
   /* Allocate memory */ 
   if(!FImageBufferAlloc(pfimage)){ 
      free(pfimage); 
      free(temp[0]); 
		return NULL; 
   } 
	 
   /* Copy */ 
	for (i=0; i< xsize*ysize; i++){ 
		pfimage->pixelLinear[i]=(double)tempLinear[i]; 
	} 
	 
	free(temp[0]); 
 
	return pfimage; 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int WriteFloatToRawGreyFile(PFIMAGE pfimage, char *filename) 
{ 
   int i; 
   FILE *fp; 
	unsigned char **temp, *tempLinear; 
    
	temp=Byte_Alloc(pfimage->ysize, pfimage->xsize); 
	tempLinear=temp[0]; 
 
	if (temp==NULL){ 
		return 0; 
	} 
 
	if((fp=fopen(filename, "wb"))==NULL){ 
		free(temp[0]); 
      return 0; 
   } 
	 
	/* Copy */ 
	for (i=0; ixsize*pfimage->ysize; i++){ 
		tempLinear[i]=(int)((pfimage->pixelLinear[i]+0.5) < 0.0 ? 0 :  
						 ((pfimage->pixelLinear[i]+0.5) > 255.0 ? 255 :  
						  (pfimage->pixelLinear[i]+0.5))); 
	} 
 
   i=fwrite(temp[0], sizeof(unsigned char), (pfimage->ysize)*(pfimage->xsize), fp); 
	 
   fclose(fp); 
 
	free(temp[0]); 
 
   if (i!=(pfimage->ysize)*(pfimage->xsize)){ 
      return 0; 
   } 
   else{ 
      return i; 
   }	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PLIMAGE ReadRaw32File(int xsize, int ysize, char *filename) 
{    
   int i; 
   PLIMAGE plimage; 
   FILE *fp; 
	 
   plimage = (PLIMAGE)malloc(sizeof(LIMAGE)); 
   plimage->xsize=xsize; 
   plimage->ysize=ysize; 
	 
   /* Allocate memory */ 
   if(!LImageBufferAlloc(plimage)){ 
      free(plimage); 
      return NULL; 
   } 
	 
   /* open the file */ 
   if ((fp=fopen(filename, "rb"))==NULL){       
      LImageBufferFree(plimage); 
      free(plimage); 
      return NULL; 
   } 
	 
   i=fread(plimage->pixel[0], sizeof(int), 
      (plimage->xsize)*(plimage->ysize), fp); 
	 
   fclose(fp); 
	 
   if (i!=(plimage->ysize)*(plimage->xsize)){ 
      LImageBufferFree(plimage); 
      free(plimage); 
      return NULL; 
   } 
   else{ 
      return plimage; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PFIMAGE ReadRawFloatFile(int xsize, int ysize, char *filename) 
{    
   int i; 
   PFIMAGE pfimage; 
   FILE *fp; 
	 
   pfimage = (PFIMAGE)malloc(sizeof(FIMAGE)); 
   pfimage->xsize=xsize; 
   pfimage->ysize=ysize; 
	 
   /* Allocate memory */ 
   if(!FImageBufferAlloc(pfimage)){ 
      free(pfimage); 
      return NULL; 
   } 
	 
   /* open the file */ 
   if ((fp=fopen(filename, "rb"))==NULL){       
      FImageBufferFree(pfimage); 
      free(pfimage); 
      return NULL; 
   } 
	 
   i=fread(pfimage->pixel[0], sizeof(double), 
      (pfimage->xsize)*(pfimage->ysize), fp); 
	 
   fclose(fp); 
	 
   if (i!=(pfimage->ysize)*(pfimage->xsize)){ 
      FImageBufferFree(pfimage); 
      free(pfimage); 
      return NULL; 
   } 
   else{ 
      return pfimage; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int WriteRawGreyFile(PIMAGE pimage, char *filename) 
{ 
   int i; 
   FILE *fp; 
    
   if((fp=fopen(filename, "wb"))==NULL){ 
      return 0; 
   } 
	 
   i=fwrite(pimage->pixel[0], sizeof(unsigned char), 
      (pimage->ysize)*(pimage->xsize), fp); 
	 
   fclose(fp); 
	 
   if (i!=(pimage->ysize)*(pimage->xsize)){ 
      return 0; 
   } 
   else{ 
      return i; 
   } 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int WriteRaw32File(PLIMAGE plimage, char *filename) 
{ 
   int i; 
   FILE *fp; 
    
   if((fp=fopen(filename, "wb"))==NULL){ 
      return 0; 
   } 
	 
   i=fwrite(plimage->pixel[0], sizeof(int), 
      (plimage->xsize)*(plimage->ysize), fp); 
	 
   fclose(fp); 
	 
   if (i!=(plimage->ysize)*(plimage->xsize)){ 
      return 0; 
   } 
   else{ 
      return i; 
   } 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int WriteRawFloatFile(PFIMAGE pfimage, char *filename) 
{ 
   int i; 
   FILE *fp; 
    
   if((fp=fopen(filename, "wb"))==NULL){ 
      return 0; 
   } 
	 
   i=fwrite(pfimage->pixel[0], sizeof(double), 
      (pfimage->xsize)*(pfimage->ysize), fp); 
	 
   fclose(fp); 
	 
   if (i!=(pfimage->ysize)*(pfimage->xsize)){ 
      return 0; 
   } 
   else{ 
      return i; 
   } 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int ImageBufferAlloc(PIMAGE pimage) 
{ 
   /* allocate memory */ 
   pimage->pixel = Byte_Alloc(pimage->ysize , pimage->xsize); 
	pimage->pixelLinear=pimage->pixel[0]; 
	 
   if(pimage->pixel[0] == NULL){ 
      return FALSE; 
   } 
   return TRUE; 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void ImageFree(PIMAGE pimage) 
{ 
   ImageBufferFree(pimage); 
   free(pimage); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void ImageBufferFree(PIMAGE pimage) 
{ 
	free(pimage->pixelLinear); 
	free(pimage->pixel); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int LImageBufferAlloc(PLIMAGE plimage) 
{ 
   /* allocate memory */ 
   plimage->pixel = Int_Alloc(plimage->ysize , plimage->xsize); 
	plimage->pixelLinear=plimage->pixel[0]; 
	 
   if(plimage->pixel[0] == NULL){ 
      return FALSE; 
   } 
   return TRUE; 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void LImageFree(PLIMAGE plimage) 
{ 
	LImageBufferFree(plimage); 
	free(plimage); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void LImageBufferFree(PLIMAGE plimage) 
{ 
	int i; 
	free(plimage->pixelLinear); 
	/* free the row pointers */ 
	free(plimage->pixel); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void FImageFree(PFIMAGE pfimage) 
{ 
   FImageBufferFree(pfimage); 
   free(pfimage); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int FImageBufferAlloc(PFIMAGE pfimage) 
{ 
   /* allocate memory */ 
   pfimage->pixel = (double **)Mem_Alloc(pfimage->ysize ,  
      pfimage->xsize, sizeof(double)); 
 
	pfimage->pixelLinear=pfimage->pixel[0]; 
    
	if(pfimage->pixel[0] == NULL){ 
      return FALSE; 
   } 
   return TRUE; 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void FImageBufferFree(PFIMAGE pfimage) 
{ 
	free(pfimage->pixelLinear); 
	free(pfimage->pixel); 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int CopyImage(PIMAGE pimageDest, PIMAGE pimageSrc) 
{ 
   assert((pimageDest->xsize == pimageSrc->xsize) && 
      (pimageDest->ysize == pimageSrc->ysize)); 
	 
   memcpy(pimageDest->pixel[0], pimageSrc->pixel[0],  
      (pimageDest->xsize)*(pimageDest->ysize)); 
	 
   return TRUE; 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int CopyLImage(PLIMAGE plimageDest, PLIMAGE plimageSrc) 
{ 
   assert((plimageDest->xsize == plimageSrc->xsize) && 
      (plimageDest->ysize == plimageSrc->ysize)); 
	 
   memcpy(plimageDest->pixel[0], plimageSrc->pixel[0],  
      (plimageDest->xsize)*(plimageDest->ysize)*sizeof(int)); 
	 
   return TRUE; 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int CopyFImage(PFIMAGE pfimageDest, PFIMAGE pfimageSrc) 
{ 
   assert((pfimageDest->xsize == pfimageSrc->xsize) && 
      (pfimageDest->ysize == pfimageSrc->ysize)); 
	 
   memcpy(pfimageDest->pixel[0], pfimageSrc->pixel[0],  
      (pfimageDest->xsize)*(pfimageDest->ysize)*sizeof(double)); 
	 
   return TRUE; 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int CopyImageToFImage(PFIMAGE pfimageDest, PIMAGE pimageSrc) 
{ 
	int i, j; 
	 
   assert((pfimageDest->xsize == pimageSrc->xsize) && 
      (pfimageDest->ysize == pimageSrc->ysize)); 
	 
	for (j=0; jysize; j++){ 
		for (i=0; ixsize; i++){ 
			pfimageDest->pixel[j][i] = (double)pimageSrc->pixel[j][i]; 
		} 
	} 
    
   return TRUE; 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int CopyFImageToImage(PIMAGE pimageDest, PFIMAGE pfimageSrc) 
{ 
	int i, j; 
	 
   assert((pimageDest->xsize == pfimageSrc->xsize) && 
      (pimageDest->ysize == pfimageSrc->ysize)); 
	 
	for (j=0; jysize; j++){ 
		for (i=0; ixsize; i++){ 
			pimageDest->pixel[j][i] = (int)( (pfimageSrc->pixel[j][i]+0.5) < 0.0 ? 0 :  
											( (pfimageSrc->pixel[j][i]+0.5) > 255.0 ?  
												255 : (pfimageSrc->pixel[j][i]+0.5))); 
		} 
	} 
    
   return TRUE; 
	 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* 
 * Average2x2Image 
 * Return a floating point image by 2x2  
 * averaging the source image 
 */ 
PFIMAGE Average2x2Image(PIMAGE pimageSrc, int type) 
{ 
   PFIMAGE pfimage; 
   int ii, jj, i, j, XLimit, YLimit; 
	 
   /* allocate the memory */ 
   pfimage = (PFIMAGE)malloc(sizeof(FIMAGE)); 
	 
   pfimage->xsize=pimageSrc->xsize/2; 
   pfimage->ysize=pimageSrc->ysize/2; 
	 
   if (FImageBufferAlloc(pfimage)){ 
      switch (type){ 
		case 0: ii = 0; jj = 0; break; 
		case 1: ii = 1; jj = 0; break; 
		case 2: ii = 0; jj = 1; break; 
		case 3: ii = 1; jj = 1; break; 
      } 
		 
		XLimit = (pimageSrc->xsize - ii) / 2; 
		YLimit = (pimageSrc->ysize - jj) / 2; 
 
      for (j=0; jpixel[j][i]= (double) 
               0.25*(pimageSrc->pixel[(j<<1) + jj][(i<<1) + ii] + 
					pimageSrc->pixel[(j<<1) + jj][(i<<1) + ii + 1] + 
					pimageSrc->pixel[(j<<1) + jj + 1][(i<<1) + ii] + 
					pimageSrc->pixel[(j<<1) + jj + 1][(i<<1) + ii + 1]); 
         } 
      } 
      return pfimage; 
   } 
   else{ 
      return NULL; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/*  
 * Average3x3Image 
 * Return a floating point image by 3x3  
 * averaging the source image 
 */ 
PFIMAGE Average3x3Image(PIMAGE pimageSrc, int type) 
{ 
   PFIMAGE pfimage; 
   int ii, jj, i, j, XLimit, YLimit; 
	 
   /* allocate the memory */ 
   pfimage = (PFIMAGE)malloc(sizeof(FIMAGE)); 
	 
   pfimage->xsize=pimageSrc->xsize/3; 
   pfimage->ysize=pimageSrc->ysize/3; 
 
   if (FImageBufferAlloc(pfimage)){ 
      switch (type){ 
		case 0: ii = 0; jj = 0; break; 
		case 1: ii = 1; jj = 0; break; 
		case 2: ii = 2; jj = 0; break; 
		case 3: ii = 0; jj = 1; break; 
		case 4: ii = 1; jj = 1; break; 
		case 5: ii = 2; jj = 1; break; 
		case 6: ii = 0; jj = 2; break; 
		case 7: ii = 1; jj = 2; break; 
		case 8: ii = 2; jj = 2; break; 
      } 
		 
		XLimit = (pimageSrc->xsize - ii) / 3; 
		YLimit = (pimageSrc->ysize - jj) / 3; 
 
      for (j=0; jpixel[j][i] = (double) 
               (  pimageSrc->pixel[3*j + jj    ][3*i + ii    ] + 
					   pimageSrc->pixel[3*j + jj    ][3*i + ii + 1] + 
					   pimageSrc->pixel[3*j + jj    ][3*i + ii + 2] + 
					   pimageSrc->pixel[3*j + jj + 1][3*i + ii    ] + 
					   pimageSrc->pixel[3*j + jj + 1][3*i + ii + 1] + 
					   pimageSrc->pixel[3*j + jj + 1][3*i + ii + 2] + 
					   pimageSrc->pixel[3*j + jj + 2][3*i + ii    ] + 
					   pimageSrc->pixel[3*j + jj + 2][3*i + ii + 1] + 
					   pimageSrc->pixel[3*j + jj + 2][3*i + ii + 2])/(double)9.0; 
         } 
      } 
 
      return pfimage; 
   } 
   else{ 
      return NULL; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* 
 * Average3x3ImageFilter0 
 * Return a floating point image by 3x3 with filter 
 * averaging the source image 
 */ 
PFIMAGE Average3x3ImageFilter0(PIMAGE pimageSrc, int type) 
{ 
   PFIMAGE pfimage; 
   int ii, jj, i, j, XLimit, YLimit; 
	double FilterCoeff[9] = {0.25, 0.50, 0.25,  
		                   0.50, 1.00, 0.50, 
								 0.25, 0.50, 0.25}; 
	 
   /* allocate the memory */ 
   pfimage = (PFIMAGE)malloc(sizeof(FIMAGE)); 
	 
   pfimage->xsize=pimageSrc->xsize/3; 
   pfimage->ysize=pimageSrc->ysize/3; 
	 
   if (FImageBufferAlloc(pfimage)){ 
      switch (type){ 
		case 0: ii = 0; jj = 0; break; 
		case 1: ii = 1; jj = 0; break; 
		case 2: ii = 2; jj = 0; break; 
		case 3: ii = 0; jj = 1; break; 
		case 4: ii = 1; jj = 1; break; 
		case 5: ii = 2; jj = 1; break; 
		case 6: ii = 0; jj = 2; break; 
		case 7: ii = 1; jj = 2; break; 
		case 8: ii = 2; jj = 2; break; 
      } 
		 
		 
		XLimit = (pimageSrc->xsize - ii) / 3; 
		YLimit = (pimageSrc->ysize - jj) / 3; 
 
      for (j=0; jpixel[j][i] = (double) 
               (  FilterCoeff[0]*pimageSrc->pixel[3*j + jj    ][3*i + ii    ] + 
					   FilterCoeff[1]*pimageSrc->pixel[3*j + jj    ][3*i + ii + 1] + 
					   FilterCoeff[2]*pimageSrc->pixel[3*j + jj    ][3*i + ii + 2] + 
					   FilterCoeff[3]*pimageSrc->pixel[3*j + jj + 1][3*i + ii    ] + 
					   FilterCoeff[4]*pimageSrc->pixel[3*j + jj + 1][3*i + ii + 1] + 
					   FilterCoeff[5]*pimageSrc->pixel[3*j + jj + 1][3*i + ii + 2] + 
					   FilterCoeff[6]*pimageSrc->pixel[3*j + jj + 2][3*i + ii    ] + 
					   FilterCoeff[7]*pimageSrc->pixel[3*j + jj + 2][3*i + ii + 1] + 
					   FilterCoeff[8]*pimageSrc->pixel[3*j + jj + 2][3*i + ii + 2])/(double)4.0; 
         } 
      } 
      return pfimage; 
   } 
   else{ 
      return NULL; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int ImageInitialize(int XSize, int YSize, PIMAGE pimage) 
{ 
	assert(XSize>0 && YSize>0); 
	 
	pimage->xsize=XSize; 
   pimage->ysize=YSize; 
	 
   /* Allocate memory */ 
   if(!ImageBufferAlloc(pimage)){ 
      return 0; 
   } 
	else{ 
		return 1;  
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int LImageInitialize(int XSize, int YSize, PLIMAGE plimage) 
{ 
	assert(XSize>0 && YSize>0); 
	 
	plimage->xsize=XSize; 
   plimage->ysize=YSize; 
	 
   /* Allocate memory */ 
   if(!LImageBufferAlloc(plimage)){ 
      return 0; 
   } 
	else{ 
		return 1;  
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
int FImageInitialize(int XSize, int YSize, PFIMAGE pfimage) 
{ 
	assert(XSize>0 && YSize>0); 
	 
	pfimage->xsize=XSize; 
   pfimage->ysize=YSize; 
	 
   /* Allocate memory */ 
   if(!FImageBufferAlloc(pfimage)){ 
      return 0; 
   } 
	else{ 
		return 1; 
	} 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PIMAGE ImageAlloc(int XSize, int YSize) 
{ 
   PIMAGE pimage; 
	 
	assert(XSize>0 && YSize>0); 
	 
   pimage = (PIMAGE)malloc(sizeof(IMAGE)); 
   pimage->xsize=XSize; 
   pimage->ysize=YSize; 
	 
   /* Allocate memory */ 
   if(!ImageBufferAlloc(pimage)){ 
      return NULL; 
   } 
	else{ 
		return pimage;  
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PLIMAGE LImageAlloc(int XSize, int YSize) 
{ 
   PLIMAGE plimage; 
	 
	assert(XSize>0 && YSize>0); 
	 
   plimage = (PLIMAGE)malloc(sizeof(LIMAGE)); 
   plimage->xsize=XSize; 
   plimage->ysize=YSize; 
	 
   /* Allocate memory */ 
   if(!LImageBufferAlloc(plimage)){ 
      return NULL; 
   } 
	else{ 
		return plimage;  
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
PFIMAGE FImageAlloc(int XSize, int YSize) 
{ 
   PFIMAGE pfimage; 
	 
	assert(XSize>0 && YSize>0); 
	 
   pfimage = (PFIMAGE)malloc(sizeof(FIMAGE)); 
   pfimage->xsize=XSize; 
   pfimage->ysize=YSize; 
	 
   /* Allocate memory */ 
   if(!FImageBufferAlloc(pfimage)){ 
      return NULL; 
   } 
	else{ 
		return pfimage;  
	} 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------*/	 
/* Adapted from G.Davis Baseline Wavelet Transform Coder Construction Kit		*/ 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
 
/*----------------------------------------------------------------------------*/	 
/*----------------------------------------------------------------------------*/	 
PIMAGE ReadPGM(char *PGMFileName) 
{ 
	FILE *fp;			//图像的文件名 
	PIMAGE pimage;	//pgm图像的数据存放空间 
	unsigned char ch=' '; 
	char ftype;			//pgm的类型 
	int MaxG;			//图像的最大灰度值 
	//分配图像数据的内存空间 
	pimage=(PIMAGE)malloc(sizeof(IMAGE)); 
	if (pimage==NULL){ 
		return NULL; 
	} 
	//打开指定路径的pgm图像 
	if ((fp=fopen(PGMFileName, "rb"))==NULL){ 
		free(pimage); 
		return NULL; 
	} 
	 
	//处理文件头信息 
	while ((ch != 'P') && (ch != '#')){  
		ch = fgetc(fp); 
	} 
	 
	//跳过图像信息部分 
	PGMSkipComments(fp, &ch); 
 
	//提取所支持的文件类型:这里仅支持P5类型 
	ftype = fgetc(fp); 
	//异常处理 
	if (ftype != '5'){ 
		ImageWarning("Only binary PGM is supported.\n"); 
		free(pimage); 
		fclose(fp); 
		return NULL; 
	} 
	//获取图像的宽、高数值 
	pimage->xsize=(int)PGMGetVal(fp); 
	pimage->ysize=(int)PGMGetVal(fp); 
	//获取图像灰度值的最大值 
	MaxG=(int)PGMGetVal(fp); 
	 
	//分配图像数据的内存空间 
	if(!ImageBufferAlloc(pimage)){ 
		free(pimage); 
		return NULL; 
	} 
	 
	//从文件尾开始的指针偏移,以避免读取无用的图像附加信息 
	fseek(fp, -1*pimage->xsize * pimage->ysize, SEEK_END); 
 
	//加载图像数据 
	if (fread(pimage->pixel[0], sizeof(unsigned char), 
		pimage->xsize*pimage->ysize, fp) != (unsigned int)pimage->xsize*pimage->ysize){ 
		fclose(fp); 
		ImageBufferFree(pimage); 
		free(pimage); 
		return NULL; 
	} 
	else{ 
		fclose(fp); 
		return pimage; 
	} 
} 
 
/*----------------------------------------------------------------------------*/	 
/*----------------------------------------------------------------------------*/	 
PFIMAGE ReadPGMToFloat(char *PGMFileName) 
{ 
	FILE *fp;			//图像的文件名 
	PIMAGE pimage;	//pgm图像的数据存放空间 
	PFIMAGE pfimage;	//图像数据的浮点存放空间 
	unsigned char ch=' '; 
	char ftype;			//pgm的类型 
	int MaxG,i;			//图像的最大灰度值 
	//分配图像数据的内存空间 
	pimage=(PIMAGE)malloc(sizeof(IMAGE)); 
	if (pimage==NULL){ 
		return NULL; 
	} 
	//分配浮点型的数据内存空间,这个是函数的输出 
	pfimage=(PFIMAGE)malloc(sizeof(FIMAGE)); 
	if (pfimage==NULL){ 
		free(pimage); 
		return NULL; 
	} 
	//打开指定路径的pgm图像 
	if ((fp=fopen(PGMFileName, "rb"))==NULL){ 
		free(pimage); 
		return NULL; 
	} 
	//处理文件头 
	while ((ch != 'P') && (ch != '#')){  
		ch = fgetc(fp); 
	} 
	 
	//跳过文件附件信息 
	PGMSkipComments(fp, &ch); 
 
	//规定支持打开的pgm类型为P5 
	ftype = fgetc(fp); 
	//异常处理 
	if (ftype != '5'){ 
		ImageWarning("Only binary PGM is supported.\n"); 
		free(pfimage); 
		free(pimage); 
		fclose(fp); 
		return NULL; 
	} 
	//获取图像的宽、高数值 
	pimage->xsize=(int)PGMGetVal(fp); 
	pimage->ysize=(int)PGMGetVal(fp); 
	//获取图像灰度值的最大值 
	MaxG=(int)PGMGetVal(fp); 
	 
	//分配图像数据的内存空间 
	if(!ImageBufferAlloc(pimage)){ 
		free(pimage); 
		free(pfimage); 
		return NULL; 
	} 
	 
	//从文件尾开始的指针偏移,以避免读取无用的图像附加信息 
	fseek(fp, -1*pimage->xsize * pimage->ysize, SEEK_END); 
 
	//加载图像数据,如果发现数据的大小不匹配,则出错退出,释放原有的图像数据空间,关闭已打开的pgm文件 
	if (fread(pimage->pixel[0], sizeof(unsigned char), 
		pimage->xsize*pimage->ysize, fp) != (unsigned int)pimage->xsize*pimage->ysize){ 
		fclose(fp); 
		ImageBufferFree(pimage); 
		free(pimage); 
		free(pfimage); 
		return NULL; 
	} 
	fclose(fp); 
	//将数据类型转换为浮点型 
	pfimage->xsize=pimage->xsize; 
	pfimage->ysize=pimage->ysize;	 
 
	//分配内存空间 
	if(!FImageBufferAlloc(pfimage)){ 
		free(pfimage); 
		ImageFree(pimage); 
		return NULL; 
	} 
	//将pimage中的数据转换后拷贝到pfimage中,完成浮点转换 
	for (i=0; i< pfimage->xsize*pfimage->ysize; i++){ 
		pfimage->pixelLinear[i]=(double)pimage->pixelLinear[i]; 
	} 
	//释放暂存用的整形数据空间 
	ImageFree(pimage); 
 
	return pfimage; 
} 
 
 
/*----------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------*/	 
int WritePGM(PIMAGE pimage, char *PGMFileName) 
{ 
	FILE *fp; 
	int i; 
	 
	if ((fp=fopen(PGMFileName, "wb+"))==NULL){ 
		return 0; 
	} 
	 
	fprintf(fp, "P5\n#%s\n%d %d\n255\n", PGMFileName, pimage->xsize, pimage->ysize); 
 
	i=fwrite(pimage->pixel[0], sizeof(unsigned char), 
		(pimage->xsize)*(pimage->ysize), fp); 
	 
	fclose(fp); 
	 
	if (i!=(pimage->ysize)*(pimage->xsize)){ 
      return 0; 
   } 
   else{ 
      return i; 
   } 
} 
 
/*----------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------*/	 
int WriteFloatToPGM(PFIMAGE pfimage, char *PGMFileName) 
{ 
	FILE *fp; 
	unsigned char **temp, *tempLinear; 
	int i; 
	 
	temp=Byte_Alloc(pfimage->ysize, pfimage->xsize); 
	tempLinear=temp[0]; 
 
	if (temp==NULL){ 
		return 0; 
	} 
 
	if ((fp=fopen(PGMFileName, "wb+"))==NULL){ 
		return 0; 
	} 
	 
	fprintf(fp, "P5\n#%s\n%d %d\n255\n", PGMFileName, pfimage->xsize, pfimage->ysize); 
 
	/* Copy */ 
	for (i=0; ixsize*pfimage->ysize; i++){ 
		tempLinear[i]=(int)((pfimage->pixelLinear[i]+0.5) < 0.0 ? 0 :  
						 ((pfimage->pixelLinear[i]+0.5) > 255.0 ? 255 :  
						  (pfimage->pixelLinear[i]+0.5))); 
	} 
 
	i=fwrite(temp[0], sizeof(unsigned char), (pfimage->xsize)*(pfimage->ysize), fp); 
	fclose(fp); 
	 
	free(temp[0]); 
	free(temp); 
 
	if (i!=(pfimage->ysize)*(pfimage->xsize)){ 
      return 0; 
   } 
   else{ 
      return i; 
   } 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* Get a number from a pgm file header, skipping comments etc. */ 
unsigned int PGMGetVal (FILE* infile) 
{ 
  unsigned int tmp; 
  unsigned char ch; 
  do {  
	  ch = fgetc(infile);  
  } while ((ch <= ' ') && (ch != '#')); 
 
  PGMSkipComments(infile, &ch); 
 
  ungetc(ch, infile); 
 
  /* Do not understand this part */ 
  if (fscanf(infile,"%u",&tmp) != 1) { 
    ImageError("%s\n","Error parsing file!"); 
  } 
 
  return(tmp); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void PGMSkipComments(FILE* infile, unsigned char *ch) 
{ 
	while ((*ch == '#')){ 
		while (*ch != '\n'){  
			*ch = fgetc(infile);  
		} 
		while (*ch < ' '){ 
			*ch = fgetc(infile);  
		} 
	} 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
double ImageCompareMSE(PIMAGE pimage1, PIMAGE pimage2) 
{ 
   int i; 
   double Error, SumOfSquareError=0.0; 
 
   if ((pimage1->xsize != pimage2->xsize) || (pimage1->ysize!=pimage2->ysize)){ 
      ImageWarning("Cannot compare images of different sizes (%dx%d and %dx%d)\n", 
         pimage1->xsize, pimage1->ysize, pimage2->xsize, pimage2->ysize); 
      return 0.0; 
   } 
 
   for (i=0; i< pimage1->xsize*pimage1->ysize; i++){ 
      Error=pimage1->pixelLinear[i]-pimage2->pixelLinear[i]; 
      SumOfSquareError+=Error*Error; 
   } 
 
   return SumOfSquareError/(double)(pimage1->xsize*pimage1->ysize); 
 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
double ImageComparePSNR(PIMAGE pimage1, PIMAGE pimage2) 
{ 
   int i; 
   double Error, SumOfSquareError=0.0, RootMeanSquareError; 
 
   if ((pimage1->xsize != pimage2->xsize) || (pimage1->ysize!=pimage2->ysize)){ 
      ImageWarning("Cannot compare images of different sizes (%dx%d and %dx%d)\n", 
         pimage1->xsize, pimage1->ysize, pimage2->xsize, pimage2->ysize); 
      return 0.0; 
   } 
 
   for (i=0; i< pimage1->xsize*pimage1->ysize; i++){ 
      Error=pimage1->pixelLinear[i]-pimage2->pixelLinear[i]; 
      SumOfSquareError+=Error*Error; 
   } 
 
   RootMeanSquareError = sqrt(SumOfSquareError/(double)(pimage1->xsize*pimage1->ysize)); 
    
   return 20*log10(255.0/RootMeanSquareError); /* assume maximum 255 */ 
 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
double FImageCompareMSE(PFIMAGE pfimage1, PFIMAGE pfimage2) 
{ 
   int i; 
   double Error, SumOfSquareError=0.0; 
 
   if ((pfimage1->xsize != pfimage2->xsize) || (pfimage1->ysize!=pfimage2->ysize)){ 
      ImageWarning("Cannot compare images of different sizes (%dx%d and %dx%d)\n", 
         pfimage1->xsize, pfimage1->ysize, pfimage2->xsize, pfimage2->ysize); 
      return 0.0; 
   } 
 
   for (i=0; i< pfimage1->xsize*pfimage1->ysize; i++){ 
      Error=pfimage1->pixelLinear[i]-pfimage2->pixelLinear[i]; 
      SumOfSquareError+=Error*Error; 
   } 
 
   return SumOfSquareError/(double)(pfimage1->xsize*pfimage1->ysize); 
 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
double FImageComparePSNR(PFIMAGE pfimage1, PFIMAGE pfimage2) 
{ 
   int i; 
   double Error, SumOfSquareError=0.0, RootMeanSquareError; 
 
   if ((pfimage1->xsize != pfimage2->xsize) || (pfimage1->ysize!=pfimage2->ysize)){ 
      ImageWarning("Cannot compare images of different sizes (%dx%d and %dx%d)\n", 
         pfimage1->xsize, pfimage1->ysize, pfimage2->xsize, pfimage2->ysize); 
      return 0.0; 
   } 
 
   for (i=0; i< pfimage1->xsize*pfimage1->ysize; i++){ 
      Error=pfimage1->pixelLinear[i]-pfimage2->pixelLinear[i]; 
      SumOfSquareError+=Error*Error; 
   } 
 
   RootMeanSquareError = sqrt(SumOfSquareError/(double)(pfimage1->xsize*pfimage1->ysize)); 
    
   return 20*log10(255.0/RootMeanSquareError); /* assume maximum 255 */ 
 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* RGB to YCbCr */ 
void rgb2ycc(double r, double g, double b, double *y, double *cb, double *cr) 
{ 
	(*y)  =  0.29900*r + 0.58700*g + 0.11400*b; 
	(*cb) = -0.16874*r - 0.33126*g + 0.50000*b + 128.0; 
	(*cr) =  0.50000*r - 0.41869*g - 0.08131*b + 128.0; 
 
	return; 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* YCbCr to RGB */ 
void ycc2rgb(double y,double cb, double cr, double *r, double *g, double *b) 
{ 
	cb	  = cb - 128.0; 
	cr	  = cr - 128.0; 
	(*r) = y + 1.40200*cr; 
	(*g) = y - 0.34414*cb - 0.71414*cr; 
	(*b) = y + 1.77200*cb; 
} 
 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* Rescales a matrix using bicubic spline interpolation  
 * (taken from Nachtwerk audioDSP library). Coded by Makus Fick 
 * 
 */ 
PIMAGE RescaleImage(PIMAGE pimageSrc, int newWidth, int newHeight, double zeroVal) 
{	 
   int srcXI, srcYI; 
	int xx, yy; 
   int width, height; 
   double xstep, ystep; 
   double **matrix1, **matrix2; 
   double srcX, srcXF, srcY, srcYF; 
   double ip0, ip1, ip2, ip3, a0, a1, a2, a3, yd1, yd2, yd3, inv; 
   PIMAGE pimageDest; 
 
	width = pimageSrc->xsize; 
   height= pimageSrc->ysize;   	 
   xstep = ((double)width) / ((double)newWidth); 
   ystep = ((double)height) / ((double)newHeight); 
    
   pimageDest = ImageAlloc(newWidth, newHeight); 
 
   if (pimageDest==NULL){ 
      return NULL; 
   } 
    
   if ((matrix1 = Double_Alloc(height, newWidth))==NULL){ 
      ImageFree(pimageDest); 
      return NULL; 
   } 
 
   if ((matrix2 = Double_Alloc(newHeight, newWidth))==NULL){ 
      ImageFree(pimageDest); 
      free(matrix1[0]); 
      return NULL; 
   } 
    
   /* first step: decimate width */ 
   if( newWidth != width ){ 
      for (yy=0; yy < height; yy++ ){ 
         for (xx=0; xx= width ) ) ? zeroVal : pimageSrc->pixel[yy][srcXI]); 
            ip1 = (( ( srcXI+1 < 0 ) || ( srcXI+1 >= width ) ) ? zeroVal : pimageSrc->pixel[yy][srcXI+1]); 
            ip2 = (( ( srcXI+2 < 0 ) || ( srcXI+2 >= width ) ) ? zeroVal : pimageSrc->pixel[yy][srcXI+2]); 
				ip3 = (( ( srcXI+3 < 0 ) || ( srcXI+3 >= width ) ) ? zeroVal : pimageSrc->pixel[yy][srcXI+3]); 
				 
            a0  = ip0; 
            a1  = ( 7.0 * ip3 - 31.5 * ip2 + 63.0 * ip1 - 38.5 * ip0) / 21.0; 
            yd1 = (-3.5 * ip3 + 21.0 * ip2 - 10.5 * ip1 -  7.0 * ip0) / 21.0; 
            yd2 = ip1 - ip0; 
            yd3 = a1 + yd1; 
            a3  = yd3 - 2.0 * yd2; 
            a2  = yd2 - a3 - a1; 
             
            inv = ((a3 * srcXF + a2)* srcXF + a1)* srcXF + a0; 
 
            inv = (inv < 0.0) ? 0.0 : ((inv > 255.0) ? 255.0 : inv); 
				matrix1[yy][xx] = inv; 
         } 
      } 
   } 
   else{ 
      for(yy=0; yypixel[yy][xx]; 
         } 
      } 
   } 
 
   /* second step: decimate height */ 
   if (newHeight != height){ 
      for( xx=0; xx= height ) ) ? zeroVal : matrix1[srcYI  ][xx]); 
            ip1 = (( ( srcYI+1 < 0 ) || ( srcYI+1 >= height ) ) ? zeroVal : matrix1[srcYI+1][xx]); 
            ip2 = (( ( srcYI+2 < 0 ) || ( srcYI+2 >= height ) ) ? zeroVal : matrix1[srcYI+2][xx]); 
            ip3 = (( ( srcYI+3 < 0 ) || ( srcYI+3 >= height ) ) ? zeroVal : matrix1[srcYI+3][xx]); 
 
            a0  = ip0; 
            a1  = ( 7.0 * ip3 - 31.5 * ip2 + 63.0 * ip1 - 38.5 * ip0) / 21.0; 
            yd1 = (-3.5 * ip3 + 21.0 * ip2 - 10.5 * ip1 -  7.0 * ip0) / 21.0; 
				yd2 = ip1 - a0; 
            yd3 = a1 + yd1; 
            a3  = yd3 - 2.0 * yd2; 
            a2  = yd2 - a3 - a1; 
 
            inv = ((a3 * srcYF + a2) * srcYF + a1)* srcYF + a0; 
 
            inv = (inv < 0.0) ? 0.0 : ((inv > 255.0) ? 255.0 : inv); 
            matrix2[yy][xx] = inv; 
         } 
      } 
   } 
	else{ 
      for(xx=0; xxpixel[yy][xx]=(unsigned char)matrix2[yy][xx]; 
      } 
   } 
 
   free(matrix1[0]); 
   free(matrix2[0]); 
 
   return pimageDest; 
    
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void ImageError(char *fmt, ...) 
{ 
	va_list argptr; 
	 
	va_start( argptr, fmt ); 
	fprintf(stderr, "ImageError: " ); 
	vprintf( fmt, argptr ); 
	va_end( argptr ); 
	exit( -1 ); 
} 
 
/*---------------------------------------------------------------------------*/ 
/*---------------------------------------------------------------------------*/ 
void ImageWarning(char *fmt, ...) 
{ 
	va_list argptr; 
	 
	va_start( argptr, fmt ); 
	fprintf( stderr, "ImageWarning: " ); 
	vprintf( fmt, argptr ); 
	va_end( argptr ); 
}