⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gif_zoom.c

📁 ucOS 模拟环境
💻 C
字号:

//----------------------------------------------------------------------
// File Name :		gif_zoom.c
// Project   :		gsm_gprs
// Module    :
// Memo      :
//                Author       Date       Description
//              -----------------------------------------------
//				  dts			  2004.3.10
//               
//----------------------------------------------------------------------
#include "gif_read.h"
typedef struct tagPIXELCOLORRGB
{
	uchar red;
	uchar green;
	uchar blue;
}PIXELCOLORRGB;

typedef unsigned char  BYTE; 
#define BOUND(x,a,b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)))
#define ABS(x)	(((x) < 0) ? -(x) : (((x) > 0) ? (x) : 0))

//====================================================================================
// Function Name:	Bool half_find(int* arr, int len, int value)
// Purpose      :	half search arithmetic
// Parameter    :	
// Return       :	none		
// Remarks      :	
// Change Log   :	
//                Author       Date       Description	
//              -----------------------------------------------	
//=====================================================================================
Bool half_find(int* arr, int len, int value)
{
   int data = 0;
	int head,tail,middle;
	head = 0;
	tail = len;
	if(arr[head]>value || arr[tail]<value)
   {
		return FALSE;
   }
	if(arr[head] == value || arr[tail] == value)
		return TRUE;
	middle = (head + tail)/2;
	while( middle> head && middle <tail)
	{
		if(arr[middle]>value)
		{
			tail = middle;
			middle = (head + tail)/2;
		}
		else if(arr[middle]<value)
		{
			head = middle;
			middle = (head + tail)/2;
		}
		else
		{
			return TRUE;
		}
	}
	if(arr[middle] != value)
   {
		return FALSE;
   }
	else
   {
		return TRUE;
   }
}

//====================================================================================
// Function Name:	void StrechPixels(int S_size, int D_size, int* select  )
// Purpose      :	record the pixels index which is preserved
// Parameter    :	
// Return       :	none		
// Remarks      :	
// Change Log   :	
//                Author       Date       Description	
//              -----------------------------------------------	
//=====================================================================================
void StrechPixels(int S_size, int D_size, int* select  )
{
	int p1 = 0, count = 0,p2;
	for ( p2 = 0; p2 < D_size; p2++ )
	{
		count += S_size;
		select[p2] = p1; 
		while ( count >= D_size )
		{
			count -= D_size;
			p1++;
		}
	}
}
//====================================================================================
// Function Name:	int get_real_height_index(int height,int code,int* record)
// Purpose      :	
// Parameter    :	
// Return       :	none		
// Remarks      :	
// Change Log   :	
//                Author       Date       Description	
//              -----------------------------------------------	
//=====================================================================================
int get_real_height_index(int height,int code,int* record)
{
	int i;
	for( i = 0; i< height; i++)
	{
		if(record[i] == code)
		{
			break;
		}
	}
	return i;
}
//====================================================================================
// Function Name:	static float Sinxx(float fx)
// Purpose      :	
// Parameter    :	
// Return       :	none		
// Remarks      :	
// Change Log   :	
//                Author       Date       Description	
//              -----------------------------------------------	
//=====================================================================================
static float Sinxx(float fx)
{
	float fabsx = ABS(fx);
	float fxx = fabsx * fabsx;
	float fxxx = fxx * fabsx;
	if(fabsx < 1.0f) 
   {
      return (1.0f - 2.0f * fxx + fxxx);
   }
	else if(fabsx < 2.0f) 
   {
		return (4.0f - 8.0f * fabsx + 5.0f * fxx - fxxx); 
   }
	else 
   {
      return 0.0f;
   }
}
//====================================================================================
// Function Name:	static PIXELCOLORRGB Interpolate(uchar* lpbySrcXY,  int x,  int y,  
//                  float fu,  float fv,  int nScanWidth,  int nScanHeight,ulong ScaleType)
// Purpose      :	
// Parameter    :	
// Return       :	none		
// Remarks      :	
// Change Log   :	
//                Author       Date       Description	
//              -----------------------------------------------	
//=====================================================================================
static PIXELCOLORRGB Interpolate(uchar* lpbySrcXY,  int x,  int y,  float fu,  float fv,  int nScanWidth,  int nScanHeight,ulong ScaleType)
{
	PIXELCOLORRGB rgb;
	BYTE* pbySrc;
	BYTE* pbySrcTemp ;
	int xx[4], yy[4];
	int i,j;
	float afu[4], afv[4];
	//相邻四个像素的像素值
	BYTE abyRed[4][4], abyGreen[4][4], abyBlue[4][4];
	float afRed[4] = {0.0f, 0.0f, 0.0f, 0.0f};
	float afGreen[4] = {0.0f, 0.0f, 0.0f, 0.0f};
	float afBlue[4] = {0.0f, 0.0f, 0.0f, 0.0f};
	BYTE* pbySrcBase;

	//行字节数, 可以将dwWidthBytes作为参数传递过来
	ulong dwWidthBytes = (ulong)nScanWidth * 4;
	switch(ScaleType)
	{
		case IMAGE_GEOMETRY_NEAREST_NEIGHBOR_INTERPOLATE :
		{
			pbySrc = lpbySrcXY;
			rgb.blue = *pbySrc++;
			rgb.green = *pbySrc++;
			rgb.red = *pbySrc++;
			break;
		}
		case IMAGE_GEOMETRY_BILINEAR_INTERPOLATE :
		{
			//相邻的四个像素最右下角点的x, y坐标偏移量
			int nx = 1;
			int ny = 1;
			if((x + 1) > (nScanWidth - 1)) nx = 0;
			if((y + 1) > (nScanHeight - 1)) ny = 0;
			
			//相邻四个像素的像素值
			
			
			//像素点(x, y)的数据位置
			 pbySrc = lpbySrcXY;
			//获取像素数值.
			//(x, y) = (x, y) + (0, 0)
			abyBlue[0][0] = *pbySrc++;
			abyGreen[0][0] = *pbySrc++;
			abyRed[0][0] = *pbySrc++;
			
			//(x + 1, y) = (x, y) + (1, 0)
			pbySrc = (lpbySrcXY + nx * 4);
			abyBlue[1][0] = *pbySrc++;
			abyGreen[1][0] = *pbySrc++;
			abyRed[1][0] = *pbySrc++;

			
			//指向下一行数据
			pbySrcTemp = (lpbySrcXY + ny * dwWidthBytes);

			//(x , y + 1) = (x, y) + (0, 1)
			pbySrc = pbySrcTemp;
			abyBlue[0][1] = *pbySrc++;
			abyGreen[0][1] = *pbySrc++;
			abyRed[0][1] = *pbySrc++;

			//(x + 1, y + 1) = (x, y) + (1, 1)
			pbySrc = pbySrcTemp + (4 * nx);
			abyBlue[1][1] = *pbySrc++;
			abyGreen[1][1] = *pbySrc++;
			abyRed[1][1] = *pbySrc++;
			
			rgb.red = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyRed[0][0]) + 
				      (1 - fu) * fv * ((float)abyRed[0][1]) + 
					  fu * (1 - fv) * ((float)abyRed[1][0]) +
					  fu * fv * ((float)abyRed[1][1])), 0, 255));
			rgb.green = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyGreen[0][0]) + 
				      (1 - fu) * fv * ((float)abyGreen[0][1]) + 
					  fu * (1 - fv) * ((float)abyGreen[1][0]) +
					  fu * fv * ((float)abyGreen[1][1])), 0, 255));

			rgb.blue = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyBlue[0][0]) + 
				      (1 - fu) * fv * ((float)abyBlue[0][1]) + 
					  fu * (1 - fv) * ((float)abyBlue[1][0]) +
					  fu * fv * ((float)abyBlue[1][1])), 0, 255));
			break;
		}
		
		case IMAGE_GEOMETRY_THREE_ORDER_INTERPOLATE :
		{
			//像素坐标
		
			xx[0] = -1;  xx[1] = 0; xx[2] = 1; xx[3] = 2;
			yy[0] = -1;  yy[1] = 0; yy[2] = 1; yy[3] = 2;

			//保证合法
			if((x - 1) < 0) xx[0] = 0;
			if((x + 1) > (nScanWidth - 1)) xx[2] = 0;
			if((x + 2) > (nScanWidth - 1)) xx[3] = ((xx[2] == 0) ? 0 : 1);

			if((y - 1) < 0) yy[0] = 0;
			if((y + 1) > (nScanHeight - 1)) yy[2] = 0;
			if((y + 2) > (nScanHeight - 1)) yy[3] = ((yy[2] == 0) ? 0 : 1);

			//像素点(x, y)的数据位置
			//获取数据
			
			for(i = 0;i < 4;i++)
			{
				//像素点(x, y)的数据位置
				pbySrcBase = lpbySrcXY + yy[i] * dwWidthBytes;

				for( j = 0;j < 4;j++)
				{
					pbySrc = pbySrcBase + 4 * xx[j];
					abyBlue[i][j] = *pbySrc++;
					abyGreen[i][j] = *pbySrc++;
					abyRed[i][j] = *pbySrc++;
				}
			}

			//u, v向量
			
			afu[0] = Sinxx(1.0f + fu);
			afu[1] = Sinxx(fu);
			afu[2] = Sinxx(1.0f - fu);
			afu[3] = Sinxx(2.0f - fu);

			afv[0] = Sinxx(1.0f + fv);
			afv[1] = Sinxx(fv);
			afv[2] = Sinxx(1.0f - fv);
			afv[3] = Sinxx(2.0f - fv);

			//矩阵乘向量的中间值
		

			for(i = 0;i < 4;i++)
			{
				for(j = 0;j < 4;j++)
				{
					afRed[i] += afv[j] * abyRed[j][i];
					afGreen[i] += afv[j] * abyGreen[j][i];
					afBlue[i] += afv[j] * abyBlue[j][i];				
				}
			}
			rgb.red = (BYTE)(BOUND((afu[0] * afRed[0] + afu[1] * afRed[1] + afu[2] * afRed[2] + 
						afu[3] * afRed[3]), 0, 255));
			rgb.green = (BYTE)(BOUND((afu[0] * afGreen[0] + afu[1] * afGreen[1] + afu[2] * afGreen[2] + 
						afu[3] * afGreen[3]), 0, 255));
			rgb.blue = (BYTE)(BOUND((afu[0] * afBlue[0] + afu[1] * afBlue[1] + afu[2] * afBlue[2] + 
						afu[3] * afBlue[3]), 0, 255));
			break;
		}
		default : 
         break;
	}//end switch

	return rgb;
}

//====================================================================================
// Function Name:	Bool Gif_Scale(uchar* lpbyBitsSrc32, int nScanWidth,  int nScanHeight, 
//                  uchar* lpbyBitsDst32, int nWidthImgDst, int nHeightImgDst,ulong ScaleType)
// Purpose      :	
// Parameter    :	
// Return       :	none		
// Remarks      :	
// Change Log   :	
//                Author       Date       Description	
//              -----------------------------------------------	
//=====================================================================================
Bool Gif_Scale(uchar* lpbyBitsSrc32, int nScanWidth,  int nScanHeight, uchar* lpbyBitsDst32, int nWidthImgDst, int nHeightImgDst,ulong ScaleType)
{
	int i,j;
	float fScalex,fScaley ;
	ulong dwWidthBytes;
	uchar* pbyDst;
	float fYInverse;
	float fXInverse;
	int yy ;
	float fv ;
	uchar* pbySrc;
	int xx ;
	float fu ;
	uchar* pbyCurrent;
	PIXELCOLORRGB rgb;

	//第一步, 进行参数合法性检测
	
	//有效区域的宽度和高度
	int w = nScanWidth ;
	int h =  nScanHeight ;
	
	//注意事项:
	//第一:
	//如果(w <  nWidth), 或者(h <  nHeight)则表示指的区域比能够有效获取数据的区域要大, 
	//这时程序将放大倍数, 使最后缩放的结果总能达到 nWidthImgDst 宽和 nHeightImgDst 高
	
	//第二:	
	//fScalex, fScaley所表示的缩放比为真实缩放比的倒数
	//之所以这样处理是由于, 作一次除法, 总比一次乘法要慢.

	//宽度缩放比
	fScalex = (float)w / (float)nWidthImgDst;
	fScaley = (float)h / (float)nHeightImgDst;

	//行字节数
	dwWidthBytes = (ulong)nScanWidth * 4;
	//开始数据基索引
	
	//指向目标数据
	pbyDst = lpbyBitsDst32;
	//完成变换
	for( i = 0; i < nHeightImgDst;i++)
	{
		//反向变换后获得的浮点y值
		fYInverse = i * fScaley;
		//取整
		yy = (int)fYInverse;

		//坐标差值
		fv = fYInverse - yy;
		
		//对应于原图像的y坐标
		yy += 0;

		pbySrc = lpbyBitsSrc32 + yy * dwWidthBytes;

		for( j = 0;j < nWidthImgDst;j++)
		{
			//反向变换后获得的浮点x值
			fXInverse = j * fScalex;
			//取整
			xx = (int)fXInverse;

			//坐标差值
			fu = fXInverse - xx;
			
			//对应于原图像的y坐标
			xx += 0;
					
			//获取数据
			pbyCurrent =  pbySrc + 4 * xx;
			rgb = Interpolate(pbyCurrent, xx, yy, fu, fv, nScanWidth,  nScanHeight,ScaleType);
			
			*pbyDst++ = rgb.blue;
			*pbyDst++ = rgb.green;
			*pbyDst++ = rgb.red;
	
			//alpha数据由外部填充.
			pbyDst++;	
		}
	}
	return TRUE;
}







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -