📄 gif_zoom.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 + -