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

📄 rotatezoom.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
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 + -