📄 rotatezoom.c
字号:
/******************************************************************************
Copyright(C)2007,Rockchip Co., Ltd. All Rights Reserved.
File:RGBRotateScale_transform.c
Desc:scaler
Note:
Author:hxd
$Log:
Revision 1.0 2007/09/01 hxd
*****************************************************************************/
#if ((defined(BOARD)) || defined(ROCK_FS))
#include "ImageRotateZoom.h"
/*************************************************************************
GLOBAL VARIABLES
**************************************************************************/
#define GET_B(rgb) ((rgb)&0xFF)
#define GET_G(rgb) ((rgb>>8)&0xFF)
#define GET_R(rgb) ((rgb>>16)&0xFF)
#ifdef MAX
#undef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifdef MIN
#undef MIN
#define MIN(a,b) ((a)>(b)?(b):(a))
#endif
//local functions
//访问一个像素点的函数可以写为
targbmodel* RGBRotScaPixels(const tpicregion* pic, const long x, const long y)
{
return (targbmodel*)(((TUInt8*)(pic->pdata) + pic->byte_width*y)) + x;
}
//判断一个点是否在图片内
short RGBRotScaPixelsIsInPic(const tpicregion* pic, const long x, const long y)
{
return ((x >= 0) && (x < pic->width) && (y >= 0) && (y < pic->height));
}
#if 0
//缩略图显示,缩小到ScreenWidth,ScreenHeight大小,存放在Dst->pdata指向的buf中,
//外部开buf,需与ScreenWidth,ScreenHeight匹配, Eddie CF修改
void NineScreenZoom(tpicregion* Dst, const tpicregion* Src, int ScreenWidth, int ScreenHeight)
{
long x;
long y;
unsigned long srcx;
unsigned long srcy;
targbmodel* srcpixels;
targbmodel* dstpixels;
long dstwidth;
long dstheight;
double zoomy;
double zoomx;
long submovedx;
long submovedy;
unsigned long xrIntFloat_16 = 0; //16.16格式定点数
unsigned long yrIntFloat_16 = 0; //16.16格式定点数
targbmodel* pDstLine;
targbmodel* pSrcLine;
if ((0 == Dst->width) || (0 == Dst->height) || (0 == Src->width) || (0 == Src->height))
return;
//若原始图片宽度、高度都小于NINESCREEN的宽高,则目的图片宽高取原始图片宽高
if ((Src->width < ScreenWidth) && (Src->height < ScreenHeight))
{
dstwidth = Src->width;
dstheight = Src->height;
}
else
{//若原始图片宽度、高度有一个大于RGBBuffer的宽高,则目的图片宽高取原始图片宽高按比率缩小后得到的宽高
zoomy = zoomx = MIN((float)ScreenWidth / Src->width, (float)ScreenHeight / Src->height);//以RGBBuffer最大能够容纳原图缩小图片的那个比率为准
dstwidth = (long)(Src->width * zoomx);
dstheight = (long)(Src->height * zoomy);
}
Dst->byte_width = ((Dst->width * sizeof(targbmodel) + 3) & ~3);
submovedx = (ScreenWidth - dstwidth) / 2;//将原图片显示于NINESCREENPIXEL区域中心位置时,需要x轴的正方向平移量
submovedy = (ScreenHeight - dstheight) / 2;//将原图片显示于NINESCREENPIXEL区域中心位置时,需要y轴的正方向平移量
if ((Src->width < ScreenWidth) && (Src->height < ScreenHeight))
{//当原图片高宽都小于九宫缩略图图片高宽尺寸时,按如下缩放处理
for (y = 0;y < Src->height;++y)
{
srcy = y;
for (x = 0;x < Src->width;++x)
{
srcx = x;
srcpixels = RGBRotScaPixels(Src, srcx, srcy);
dstpixels = RGBRotScaPixels(Dst, x + submovedx, y + submovedy);//寻找到九宫图片在SCREENPIXEL尺寸屏幕中的位置,movedx表示x轴正方向偏移量,movedy表示y轴正方向偏移量
*dstpixels = *srcpixels;
}
}
}
else
{
xrIntFloat_16 = (Src->width << 16) / dstwidth + 1; //16.16格式定点数
yrIntFloat_16 = (Src->height << 16) / dstheight + 1; //16.16格式定点数
pDstLine = Dst->pdata;
//当原图片高宽有一项大于九宫缩略图图片高宽尺寸时,按如下缩放处理:现将源图片缩小到NINESCREENPIXEL区域,然后将NINESCREENPIXEL区域的图片整体平移到320×240的SCREENPIXEL屏幕区域的任意位置(由movedx,movedy控制)
for (y = 0;y < dstheight;++y)
{
//srcy = (y*Src->height/dstheight);
srcy = (y * yrIntFloat_16) >> 16;
for (x = 0;x < dstwidth;++x)
{
//srcx = (x*Src->width/dstwidth);
srcx = (x * xrIntFloat_16) >> 16;
srcpixels = RGBRotScaPixels(Src, srcx, srcy);//将源图片缩小为NINESCREENPIXEL区域尺寸(x,y)坐标对应的源图片坐标位置
//将NINESCREENPIXEL区域的屏幕的(x,y)坐标位置整体平移到SCREENPIXEL屏幕的位置(x+movedx,y+movedy),计算平移后点的像素点位置,
//该点的像素值取源坐标位置(srcx,srcy)位置的像素点
dstpixels = RGBRotScaPixels(Dst, x + submovedx, y + submovedy);//寻找到九宫图片在SCREENPIXEL尺寸屏幕中的位置,movedx表示x轴正方向偏移量,movedy表示y轴正方向偏移量
*dstpixels = *srcpixels;//该点的像素值取源坐标位置(srcx,srcy)的像素点
}
}
}
}
#else
void NineScreenZoom(tpicregion* Dst, const tpicregion* Src, int ScreenWidth, int ScreenHeight)
{
long SrcLength, SrcHeight; // 源图片宽高(缩放前)
long Dstlength, DstHeight; // 目标图片宽高(缩放后)
long deltaX, deltaY;
long rate; // 缩放比率 > 1, Q16
long rateInv; // < 1, Q16
long i, j;
long x, y;
long x0, x1, y0, y1;
long p00, p01, p10, p11;
long h, v; // Q10
long coef1, coef2, coef3, coef4;
unsigned long r, g, b;
unsigned long *pRgbBufSrc = (unsigned long*)Src->pdata;
unsigned long *pRgbBufDst = (unsigned long*)Dst->pdata;
if (Dst->pdata == 0 || Src->pdata == 0)
{
return;
}
if (SrcLength == 0 || SrcHeight == 0)
{
return;
}
if (ScreenWidth == 0 || ScreenHeight == 0)
{
return;
}
SrcLength = Src->width;
SrcHeight = Src->height;
if ((SrcLength <= ScreenWidth) && (SrcHeight <= ScreenHeight))
{
// 不需要作缩放
deltaX = (ScreenWidth - SrcLength) / 2;
deltaY = (ScreenHeight - SrcHeight) / 2;
for (j = 0; j < SrcHeight; j++)
{
for (i = 0; i < SrcLength; i++)
{
*(pRgbBufDst + (j + deltaY)*ScreenWidth + deltaX + i) = *(pRgbBufSrc + j * SrcLength + i);
}
}
return;
}
rateInv = MIN((ScreenWidth << 16) / SrcLength, (ScreenHeight << 16) / SrcHeight);
rate = MAX((SrcLength << 16) / ScreenWidth, (SrcHeight << 16) / ScreenHeight);// SrcLength, SrcHeight不能超过65536
Dstlength = rateInv * SrcLength >> 16;
DstHeight = rateInv * SrcHeight >> 16;
deltaX = (ScreenWidth - Dstlength) / 2; //将原图片显示于NINESCREENPIXEL区域中心位置时,需要x轴的正方向平移量
deltaY = (ScreenHeight - DstHeight) / 2;//将原图片显示于NINESCREENPIXEL区域中心位置时,需要y轴的正方向平移量
for (j = 0; j < DstHeight; j++)
{
for (i = 0; i < Dstlength; i++)
{
x = i * rate;
y = j * rate;
x0 = x >> 16;
x1 = x0 + 1;
y0 = y >> 16;
y1 = y0 + 1;
h = ((x1 << 16) - x) >> 6;
v = ((y1 << 16) - y) >> 6;
p00 = *(pRgbBufSrc + y0 * SrcLength + x0);
p01 = *(pRgbBufSrc + y0 * SrcLength + x1);
p10 = *(pRgbBufSrc + y1 * SrcLength + x0);
p11 = *(pRgbBufSrc + y1 * SrcLength + x1);
coef1 = v * h;
coef2 = v * (1024 - h);
coef3 = (1024 - v) * h;
coef4 = (1024 - v) * (1024 - h);
r = (coef1 * GET_R(p00) + coef2 * GET_R(p01) + coef3 * GET_R(p10) + coef4 * GET_R(p11)) >> 20;
g = (coef1 * GET_G(p00) + coef2 * GET_G(p01) + coef3 * GET_G(p10) + coef4 * GET_G(p11)) >> 20;
b = (coef1 * GET_B(p00) + coef2 * GET_B(p01) + coef3 * GET_B(p10) + coef4 * GET_B(p11)) >> 20;
// 需要将图片放在ScreenWidth*ScreenHeight的正中
*(pRgbBufDst + (j + deltaY)*ScreenWidth + deltaX + i) = (b & 0xFF) | ((g & 0xFF) << 8) | ((r & 0xFF) << 16);
}
}
}
#endif
#if 0
//函数假设以原图片的中心点坐标为旋转和缩放的中心,定点版本
void RGBRotScaPicRotaryInt(const tpicregion* Dst, const tpicregion* Src, double ZoomX, double ZoomY, double move_x, double move_y, double centerx0, double centery0, int RotateTimes)
{
double rx0;
double ry0;
double tmprzoomxy = 1.0 / (ZoomX * ZoomY);
double rZoomX = tmprzoomxy * ZoomY;
double rZoomY = tmprzoomxy * ZoomX;
long x;
long y;
long srcx;
long srcy;
targbmodel* srcpixels;
targbmodel* pDstLine = Dst->pdata;
int RGBRotSca_gCosTable[4] = {1, 0, -1, 0};//0,PI/2,PI,PI*3/2
int RGBRotSca_gSinTable[4] = {0, 1, 0, -1};//0,PI/2,PI,PI*3/2
long Ax_16 = (long)(rZoomX * RGBRotSca_gCosTable[RotateTimes & 0x3] * (1 << 16));
long Ay_16 = (long)(rZoomX * RGBRotSca_gSinTable[RotateTimes & 0x3] * (1 << 16));
long Bx_16 = (long)(-rZoomY * RGBRotSca_gSinTable[RotateTimes & 0x3] * (1 << 16));
long By_16 = (long)(rZoomY * RGBRotSca_gCosTable[RotateTimes & 0x3] * (1 << 16));
long Cx_16;
long Cy_16;
long srcx0_16;
long srcy0_16;
long srcx_16;
long srcy_16;
rx0 = centerx0;//Src->width*0.5;
ry0 = centery0;//Src->height*0.5;//(rx0,ry0)为旋转中心
Cx_16 = (long)((-(rx0 + move_x) * rZoomX * RGBRotSca_gCosTable[RotateTimes & 0x3] + (ry0 + move_y) * rZoomY * RGBRotSca_gSinTable[RotateTimes & 0x3] + rx0) * (1 << 16));
Cy_16 = (long)((-(rx0 + move_x) * rZoomX * RGBRotSca_gSinTable[RotateTimes & 0x3] - (ry0 + move_y) * rZoomY * RGBRotSca_gCosTable[RotateTimes & 0x3] + ry0) * (1 << 16));
srcx0_16 = Cx_16;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -