首页 > 代码库 > 图像放大快速算法

图像放大快速算法

图像放大快速算法实现的原理主要有以下两点:

1、横向缩放与纵向缩放分开,而先后顺序取决于缩放前后的图像比例:

   若SrcHeight/DstWidth>SrcWidth/DstWidth,则先纵向缩放,否则横向缩放。

2、利用整数运算代替浮点运算,由于是分步缩放,以横向缩放为例,利用二次线性插值公式,再变形一下如下:

f(i,j+v) = (1-v)f(i,j) +vf(i,j+1);

其中i为第i行,j为第j列,v表示求得放大后坐标的小数部分。

这里最重要的并没有直接用小数运算,而是通过将小数区间(0,1)映射到整数区间(0,128),    

再利用整数来代替小数运算,最后只需要相应的处理一下就可以了。

 

误差分析:

首先二次线性算法本来就有误差,这里主要讨论利用整数代替小数的误差,可以看到每一个整数能代替的小数范围为1/128,所以误差范围为[-1/256,1/256]之间。


代码实现:

//ImageScale.h

[cpp] view plaincopy
  1. #define IN  
  2. #define OUT  
  3. #define _DWORD int  
  4. #define _BYTE byte  
  5. #define _WORD short  
  6.   
  7. struct ImageInfo  
  8. {  
  9.     byte* pRGBData;  
  10.     int nHeight;  
  11.     int nStepValue;  
  12.     int nWidth;  
  13. //  int nFlag;  
  14.     ImageInfo()  
  15.     {  
  16.         pRGBData=http://www.mamicode.com/NULL;
  17.     }  
  18.     ImageInfo(byte *p,int h,int s,int w)  
  19.     {  
  20.     //  pRGBData = (byte*)malloc(h*s);  
  21.         pRGBData = p;  
  22.         nHeight=h;  
  23.         nStepValue=http://www.mamicode.com/s;
  24.         nWidth=w;  
  25.     }  
  26. };  
  27.   
  28. class ImageScale  
  29. {  
  30. public:  
  31.     ImageScale(void);  
  32.     virtual ~ImageScale(void);  
  33.     void Run(BYTE* pSrcImage, int nSrcWidth, int nSrcHeight, BYTE* pTagImage, int nTagWidth, int nTagHeight,int nChannels);  
  34. private:  
  35.     bool DstInSrcIndex(int large_len, int little_len,  int* a3_pIntValue, byte* a4_pByteValue);  
  36.     int DoubleToInt(double d);  
  37.     BOOL HorizontalFill(IN ImageInfo& SrcImageInfo, IN int nTagHeight, IN int nTagWidth, IN int nTagStepValue, IN int bFlag, IN int* pIntValue, IN byte* pByteValue, OUT ImageInfo& DstImageInfo,int nChannels);  
  38.     BOOL VerticalFill(IN ImageInfo& SrcImageInfo, IN int nTagHeight, IN int nTagWidth, IN int nTagStepValue, IN int bFlag, IN int* pIntValue, IN byte* pByteValue, OUT ImageInfo& DstImageInfo,int nChannels);  
  39.     void HorizontalScale(byte *a1_pData_Src, byte *a2_pData_Dst, int nHeight, int nWidth, int *a5_pData_Unknow, byte *a6_pData_Unknow, int srcStepValue, int dstStepValue,  short *a10_pData_Unknow,int nChannels);  
  40.     void VerticalScale(byte *a1_pData_Src, byte *a2_pData_Dst, int a3_nHeight, int a4_nWidth, int *a5_pData_Unknow, byte *a6_pData_Unknow, int a7_nWidth, int a8_nWidthScrible,  short *a10_pData_Unknow,int nChannels);  
  41. };  


//ImageScale.cpp


[cpp] view plaincopy
    1. #include "StdAfx.h"  
    2. #include "ImageScale.h"  
    3.   
    4. short g_pHSDataByte[]=  
    5. {  
    6.     0x4000, 0x0000, 0x3F80, 0x0080, 0x3F00, 0x0100, 0x3E80, 0x0180,  
    7.     0x3E00, 0x0200, 0x3D80, 0x0280, 0x3D00, 0x0300, 0x3C80, 0x0380,  
    8.     0x3C00, 0x0400, 0x3B80, 0x0480, 0x3B00, 0x0500, 0x3A80, 0x0580,  
    9.     0x3A00, 0x0600, 0x3980, 0x0680, 0x3900, 0x0700, 0x3880, 0x0780,  
    10.     0x3800, 0x0800, 0x3780, 0x0880, 0x3700, 0x0900, 0x3680, 0x0980,  
    11.     0x3600, 0x0A00, 0x3580, 0x0A80, 0x3500, 0x0B00, 0x3480, 0x0B80,  
    12.     0x3400, 0x0C00, 0x3380, 0x0C80, 0x3300, 0x0D00, 0x3280, 0x0D80,  
    13.     0x3200, 0x0E00, 0x3180, 0x0E80, 0x3100, 0x0F00, 0x3080, 0x0F80,  
    14.     0x3000, 0x1000, 0x2F80, 0x1080, 0x2F00, 0x1100, 0x2E80, 0x1180,  
    15.     0x2E00, 0x1200, 0x2D80, 0x1280, 0x2D00, 0x1300, 0x2C80, 0x1380,  
    16.     0x2C00, 0x1400, 0x2B80, 0x1480, 0x2B00, 0x1500, 0x2A80, 0x1580,  
    17.     0x2A00, 0x1600, 0x2980, 0x1680, 0x2900, 0x1700, 0x2880, 0x1780,  
    18.     0x2800, 0x1800, 0x2780, 0x1880, 0x2700, 0x1900, 0x2680, 0x1980,  
    19.     0x2600, 0x1A00, 0x2580, 0x1A80, 0x2500, 0x1B00, 0x2480, 0x1B80,  
    20.     0x2400, 0x1C00, 0x2380, 0x1C80, 0x2300, 0x1D00, 0x2280, 0x1D80,  
    21.     0x2200, 0x1E00, 0x2180, 0x1E80, 0x2100, 0x1F00, 0x2080, 0x1F80,  
    22.     0x2000, 0x2000, 0x1F80, 0x2080, 0x1F00, 0x2100, 0x1E80, 0x2180,  
    23.     0x1E00, 0x2200, 0x1D80, 0x2280, 0x1D00, 0x2300, 0x1C80, 0x2380,  
    24.     0x1C00, 0x2400, 0x1B80, 0x2480, 0x1B00, 0x2500, 0x1A80, 0x2580,  
    25.     0x1A00, 0x2600, 0x1980, 0x2680, 0x1900, 0x2700, 0x1880, 0x2780,  
    26.     0x1800, 0x2800, 0x1780, 0x2880, 0x1700, 0x2900, 0x1680, 0x2980,  
    27.     0x1600, 0x2A00, 0x1580, 0x2A80, 0x1500, 0x2B00, 0x1480, 0x2B80,  
    28.     0x1400, 0x2C00, 0x1380, 0x2C80, 0x1300, 0x2D00, 0x1280, 0x2D80,  
    29.     0x1200, 0x2E00, 0x1180, 0x2E80, 0x1100, 0x2F00, 0x1080, 0x2F80,  
    30.     0x1000, 0x3000, 0x0F80, 0x3080, 0x0F00, 0x3100, 0x0E80, 0x3180,  
    31.     0x0E00, 0x3200, 0x0D80, 0x3280, 0x0D00, 0x3300, 0x0C80, 0x3380,  
    32.     0x0C00, 0x3400, 0x0B80, 0x3480, 0x0B00, 0x3500, 0x0A80, 0x3580,  
    33.     0x0A00, 0x3600, 0x0980, 0x3680, 0x0900, 0x3700, 0x0880, 0x3780,  
    34.     0x0800, 0x3800, 0x0780, 0x3880, 0x0700, 0x3900, 0x0680, 0x3980,  
    35.     0x0600, 0x3A00, 0x0580, 0x3A80, 0x0500, 0x3B00, 0x0480, 0x3B80,  
    36.     0x0400, 0x3C00, 0x0380, 0x3C80, 0x0300, 0x3D00, 0x0280, 0x3D80,  
    37.     0x0200, 0x3E00, 0x0180, 0x3E80, 0x0100, 0x3F00, 0x0080, 0x3F80,  
    38.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000  
    39. };  
    40.   
    41.   
    42. ImageScale::ImageScale(void)  
    43. {  
    44. }  
    45.   
    46.   
    47. ImageScale::~ImageScale(void)  
    48. {  
    49.   
    50. }  
    51.   
    52. void ImageScale::Run(BYTE* pSrcImage, int nSrcWidth, int nSrcHeight,  BYTE* pTagImage, int nTagWidth, int nTagHeight, int nChannels)  
    53. {  
    54.   
    55.     if (!(nChannels==1||nChannels==4))  
    56.         return;  
    57.     if(nSrcWidth<=0 || nSrcHeight<=0 )  
    58.         return;  
    59.     if(nTagWidth<nSrcWidth || nTagHeight<nSrcHeight)  
    60.         return;  
    61.     int nSrcStepValue=http://www.mamicode.com/(nSrcWidth+15) & ~15;
    62.     int nTagStepValue=http://www.mamicode.com/nTagWidth;
    63.   
    64.     //申请四个内存空间  
    65.     int* pIntValueTmp_nHeight = (int*)malloc(nTagHeight*sizeof(int));//存储纵坐标索引值  
    66.     if (pIntValueTmp_nHeight)  
    67.     {  
    68.         memset(pIntValueTmp_nHeight, 0,nTagHeight*sizeof(int));  
    69.     }  
    70.       
    71.     byte* pByteValueTmp_nHeight = (byte*)malloc(nTagHeight);//存储纵坐标下的小数映射到整数空间下的值  
    72.     if (pByteValueTmp_nHeight)  
    73.     {  
    74.         memset(pByteValueTmp_nHeight, 0, nTagHeight);  
    75.     }  
    76.   
    77.     int* pIntValueTmp_nWidth = (int*)malloc(nTagWidth*sizeof(int));//存储横坐标索引值  
    78.     if (pIntValueTmp_nWidth)  
    79.     {  
    80.         memset(pIntValueTmp_nWidth, 0, nTagWidth*sizeof(int));  
    81.     }  
    82.   
    83.     byte* pByteValueTmp_nWidth = (byte*)malloc(nTagWidth);//存储横坐标下的小数映射到整数空间下的值  
    84.     if (pByteValueTmp_nWidth)  
    85.     {  
    86.         memset(pByteValueTmp_nWidth, 0, nTagWidth);  
    87.     }  
    88.     DstInSrcIndex(nTagWidth,nSrcWidth, pIntValueTmp_nWidth, pByteValueTmp_nWidth);  
    89.     DstInSrcIndex(nTagHeight, nSrcHeight, pIntValueTmp_nHeight, pByteValueTmp_nHeight);  
    90.     int nValueTmp1 = nSrcHeight * nTagWidth;  
    91.     int nValueTmp2 = nSrcWidth * nTagHeight;  
    92.   
    93.     ImageInfo SrcImageInfo(pSrcImage,nSrcHeight,nSrcStepValue,nSrcWidth);  
    94.     ImageInfo ImageInfo_Tmp1;  
    95.     ImageInfo ImageInfo_Tmp2;  
    96.   
    97.     if (nValueTmp1 > nValueTmp2)  
    98.     {  
    99.         VerticalFill(SrcImageInfo, nTagHeight, nTagWidth, nTagStepValue, 0, pIntValueTmp_nHeight, pByteValueTmp_nHeight, ImageInfo_Tmp1,nChannels);  
    100.   
    101.         HorizontalFill(ImageInfo_Tmp1, nTagHeight, nTagWidth, nTagStepValue,  0, pIntValueTmp_nWidth , pByteValueTmp_nWidth, ImageInfo_Tmp2,nChannels);  
    102.     }  
    103.     else  
    104.     {  
    105.         HorizontalFill(SrcImageInfo, nTagHeight, nTagWidth, nTagStepValue, 1, pIntValueTmp_nWidth, pByteValueTmp_nWidth, ImageInfo_Tmp1,nChannels);  
    106.         VerticalFill(ImageInfo_Tmp1, nTagHeight, nTagWidth, nTagStepValue,  1,pIntValueTmp_nHeight, pByteValueTmp_nHeight, ImageInfo_Tmp2,nChannels);  
    107.     }  
    108.     //pTagImage=(byte*)malloc(nTagHeight * nTagWidth);  
    109.    for (int i=0; i<nTagHeight; i++)  
    110.     {  
    111.         memcpy(pTagImage +nChannels*i*nTagWidth, ImageInfo_Tmp2.pRGBData+ nChannels*i*nTagWidth, nChannels*nTagWidth);  
    112.     }  
    113.   
    114.   
    115.     //【释放堆内存】  
    116.     if (pIntValueTmp_nHeight)  
    117.     {  
    118.         free(pIntValueTmp_nHeight);  
    119.         pIntValueTmp_nHeight = NULL;  
    120.     }  
    121.   
    122.     if (pByteValueTmp_nHeight)  
    123.     {  
    124.         free(pByteValueTmp_nHeight);  
    125.         pByteValueTmp_nHeight = NULL;  
    126.     }  
    127.   
    128.     if (pIntValueTmp_nWidth)  
    129.     {  
    130.         free(pIntValueTmp_nWidth);  
    131.         pIntValueTmp_nWidth = NULL;  
    132.     }  
    133.   
    134.     if (pByteValueTmp_nWidth)  
    135.     {  
    136.         free(pByteValueTmp_nWidth);  
    137.         pByteValueTmp_nWidth = NULL;  
    138.     }  
    139.   
    140.     if (ImageInfo_Tmp1.pRGBData)  
    141.     {  
    142.         free(ImageInfo_Tmp1.pRGBData);  
    143.         ImageInfo_Tmp1.pRGBData = NULL;  
    144.     }  
    145.   
    146.     if (ImageInfo_Tmp2.pRGBData)  
    147.     {  
    148.         free(ImageInfo_Tmp2.pRGBData);  
    149.         ImageInfo_Tmp2.pRGBData = NULL;  
    150.     }  
    151.   
    152. }  
    153.   
    154. bool ImageScale::DstInSrcIndex(int large_len, int little_len,  int* a3_pIntValue, byte* a4_pByteValue)  
    155. {  
    156.     int nValueTmp3 =  (little_len << 7) - 128;  
    157.   
    158.     for (int index = 0;  index<large_len;  ++index)  
    159.     {  
    160.         float doubleValueTmp3 = ((float)index + 0.5) / ((float)large_len);  
    161.         int nValueTmp4 = (int)(doubleValueTmp3 * (little_len - 0.5f) * 128.0+0.5f);  
    162.         int nValueTmp1= nValueTmp3;  
    163.         if(!(nValueTmp3<nValueTmp4))  
    164.              nValueTmp1= nValueTmp4;  
    165.         a3_pIntValue[index] = nValueTmp1 >> 7;  
    166.         a4_pByteValue[index] = nValueTmp1 & 0x7F;  
    167.     }  
    168.     return true;  
    169. }  
    170.   
    171. BOOL ImageScale::HorizontalFill(IN ImageInfo& SrcImageInfo, IN int nTagHeight, IN int nTagWidth, IN int nTagStepValue, IN int bFlag, IN int* pIntValue, IN byte* pByteValue, OUT ImageInfo& DstImageInfo,int nChannels)  
    172. {  
    173.     int nHeightTmp1 = 0;  
    174.     if (bFlag)  
    175.     {  
    176.         nHeightTmp1 = SrcImageInfo.nHeight;  
    177.     }   
    178.     else  
    179.     {  
    180.         nHeightTmp1 = nTagHeight;  
    181.     }  
    182.   
    183.     //申请额外的空间保证内存对齐  
    184.     int StepValueTmp=(SrcImageInfo.nStepValue+15) & ~15;  
    185.     byte *pSrcImageTmp=(byte*)malloc(nChannels * StepValueTmp * nHeightTmp1);  
    186.     memset(pSrcImageTmp,0,nChannels * StepValueTmp * nHeightTmp1);  
    187.     int SumTmp1=nChannels * StepValueTmp,SumTmp2=nChannels * SrcImageInfo.nWidth;  
    188.     for(int i=0;i<nHeightTmp1;i++)  
    189.     {  
    190.         memcpy(pSrcImageTmp+i*SumTmp1,SrcImageInfo.pRGBData+i*SumTmp2,SumTmp2);  
    191.     }  
    192. //  ImageInfo SrcImageInfo(pSrcImageTmp,SrcImageInfo.nHeight,StepValueTmp,SrcImageInfo.nWidth);  
    193.     //调用HorizontalScale进行水平延伸,结果保存到DstImageInfo中  
    194.     DstImageInfo.nHeight = nHeightTmp1;  
    195.     DstImageInfo.nWidth = nTagWidth;  
    196.     DstImageInfo.nStepValue = nTagStepValue;  
    197.     DstImageInfo.pRGBData = (byte*)malloc(nChannels * DstImageInfo.nHeight * DstImageInfo.nStepValue);  
    198.     byte* pDataSrc = SrcImageInfo.pRGBData;  
    199.     byte* pDataDst = DstImageInfo.pRGBData;  
    200.     HorizontalScale(pSrcImageTmp, pDataDst, DstImageInfo.nHeight, DstImageInfo.nWidth, pIntValue, pByteValue,   
    201.         SrcImageInfo.nStepValue, DstImageInfo.nStepValue, g_pHSDataByte,nChannels);  
    202.   
    203.     if (pSrcImageTmp)  
    204.     {  
    205.         free(pSrcImageTmp);  
    206.         pSrcImageTmp=NULL;  
    207.     }  
    208.     return TRUE;  
    209. }  
    210.   
    211. BOOL ImageScale::VerticalFill(IN ImageInfo& SrcImageInfo, IN int nTagHeight, IN int nTagWidth, IN int nTagStepValue, IN int bFlag, IN int* pIntValue, IN byte* pByteValue, OUT ImageInfo& DstImageInfo,int nChannels)  
    212. {  
    213.     int nWidthTmp1 = 0;  
    214.     int nStepValueTmp1 = 0;  
    215.     if (bFlag)  
    216.     {  
    217.         nWidthTmp1 = nTagWidth;  
    218.         nStepValueTmp1 = nTagStepValue;  
    219.     }  
    220.     else  
    221.     {  
    222.         nWidthTmp1 = SrcImageInfo.nWidth;  
    223.         nStepValueTmp1 = SrcImageInfo.nStepValue;  
    224.     }  
    225.   
    226.     //申请额外的空间保证内存对齐  
    227.     int StepValueTmp=(SrcImageInfo.nStepValue+15) & ~15;  
    228.     byte *pSrcImageTmp=(byte*)malloc(nChannels * StepValueTmp *( SrcImageInfo.nHeight+1));// 多申请一层来保证内存不会泄露  
    229.     memset(pSrcImageTmp,0,nChannels * StepValueTmp * (SrcImageInfo.nHeight+1));  
    230.     int SumTmp1=nChannels * StepValueTmp,SumTmp2=nChannels * SrcImageInfo.nWidth,SumTmp3=nChannels * SrcImageInfo.nStepValue;  
    231.     for(int i=0;i<SrcImageInfo.nHeight;i++)  
    232.     {  
    233.         memcpy(pSrcImageTmp+i*SumTmp1,SrcImageInfo.pRGBData+i*SumTmp3,SumTmp2);  
    234.     }  
    235.     // 最后一层用上一层填充  
    236.     memcpy(pSrcImageTmp+SrcImageInfo.nHeight*SumTmp1,SrcImageInfo.pRGBData+(SrcImageInfo.nHeight-1)*SumTmp3,SumTmp2);  
    237.     DstImageInfo.nHeight = nTagHeight;  
    238.     DstImageInfo.nWidth = nWidthTmp1;  
    239.     DstImageInfo.nStepValue = nStepValueTmp1;  
    240.     DstImageInfo.pRGBData = (byte*)malloc( nChannels * DstImageInfo.nHeight*DstImageInfo.nStepValue);  
    241.     memset(DstImageInfo.pRGBData, 0,nChannels * DstImageInfo.nHeight*DstImageInfo.nStepValue);  
    242.   
    243.     VerticalScale(pSrcImageTmp, DstImageInfo.pRGBData, DstImageInfo.nHeight, DstImageInfo.nWidth,  
    244.         pIntValue, pByteValue, StepValueTmp, DstImageInfo.nStepValue, g_pHSDataByte,nChannels);  
    245.     if (pSrcImageTmp)  
    246.     {  
    247.         free(pSrcImageTmp);  
    248.         pSrcImageTmp=NULL;  
    249.     }  
    250.     return TRUE;  
    251. }  
    252. void ImageScale::HorizontalScale(byte *a1_pData_Src, byte *a2_pData_Dst, int nHeight, int nWidth, int *a5_pData_Unknow, byte *a6_pData_Unknow, int srcStepValue, int dstStepValue,  short *a10_pData_Unknow,int nChannels)  
    253. {  
    254.     int v17,v18,v19,v20;  
    255.     int srcstep,dststep,index1,index2,index3;  
    256.     if(nChannels==4)  
    257.     {  
    258.         srcstep=( dstStepValue<<2);  
    259.         dststep=(srcStepValue<<2);  
    260.         for (int i=0;i<nHeight;i++)  
    261.         {  
    262.             for(int j=0;j<nWidth;j++)  
    263.             {  
    264.                 v17 = a5_pData_Unknow[j];   // 遍历,依次获得int表数据  
    265.                 v18 = ( a6_pData_Unknow[j]<<1);  
    266.                 index1=((v17+1)<<2);  
    267.                 index2=(v17<<2);  
    268.                 index3=(j<<2);  
    269.                 //blue通道  
    270.                 v19 = a1_pData_Src[index1+MT_BLUE] * a10_pData_Unknow[v18 + 1];   // 加上小数位的精度  
    271.                 v20 = (v19 + a10_pData_Unknow[v18] * a1_pData_Src[index2+MT_BLUE] + 0x2000) >> 14; //0x2000右移14位为0.5,这里是为了四舍五入;  
    272.                 a2_pData_Dst[index3+MT_BLUE] =v20&0xff;  
    273.                 //green通道  
    274.                 v19 = a1_pData_Src[index1+MT_GREEN] * a10_pData_Unknow[v18 + 1];     
    275.                 v20 = (v19 + a10_pData_Unknow[v18] * a1_pData_Src[index2+MT_GREEN] + 0x2000) >> 14;   
    276.                 a2_pData_Dst[index3+MT_GREEN] =v20&0xff;  
    277.                 //red通道  
    278.                 v19 = a1_pData_Src[index1+MT_RED] * a10_pData_Unknow[v18 + 1];    
    279.                 v20 = (v19 + a10_pData_Unknow[v18] * a1_pData_Src[index2+MT_RED] + 0x2000) >> 14;   
    280.                 a2_pData_Dst[index3+MT_RED] =v20&0xff;  
    281.                 a2_pData_Dst[index3+MT_ALPHA] =255;  
    282.         }  
    283.         a2_pData_Dst +=srcstep;  
    284.         a1_pData_Src +=dststep ;  
    285.      }  
    286.     }  
    287.     else  
    288.     {  
    289.         for (int i=0;i<nHeight;i++)  
    290.         {  
    291.             for(int j=0;j<nWidth;j++)  
    292.             {  
    293.                 v17 = a5_pData_Unknow[j];   // 遍历,依次获得int表数据  
    294.                 v18 = ( a6_pData_Unknow[j]<<1);  
    295.                 v19 = a1_pData_Src[v17+1] * a10_pData_Unknow[v18 + 1];   // 加上小数位的精度  
    296.                 v20 = (v19 + a10_pData_Unknow[v18] * a1_pData_Src[v17] + 0x2000) >> 14; //0x2000右移14位为0.5,这里是为了四舍五入;  
    297.                 a2_pData_Dst[j] = v20&0xff;;  
    298.         }  
    299.         a2_pData_Dst += dstStepValue;  
    300.         a1_pData_Src += srcStepValue;  
    301.     }  
    302.     }  
    303.   
    304. }  
    305. void ImageScale::VerticalScale(byte *a1_pData_Src, byte *a2_pData_Dst, int a3_nHeight, int a4_nWidth, int *a5_pData_Unknow, byte *a6_pData_Unknow, int a7_nWidth, int a8_nWidthScrible, short *a10_pData_Unknow,int nChannels)  
    306. {  
    307.     byte * pbTmp1;  
    308.     int nTmp2,nTmp3,nTmp4;  
    309.     int step,index1,index2,index3;  
    310.     if(nChannels==4)  
    311.     {  
    312.         step=(a8_nWidthScrible<<2);  
    313.         index1=nChannels*a7_nWidth;  
    314.         for (int i=0;i<a3_nHeight;i++)  
    315.         {  
    316.             pbTmp1= &a1_pData_Src[index1*a5_pData_Unknow[i]];  
    317.             nTmp2 = a10_pData_Unknow[a6_pData_Unknow[i]<<1];  
    318.             nTmp3 = a10_pData_Unknow[(a6_pData_Unknow[i]<<1) + 1];  
    319.             for (int j=0;j<a4_nWidth;j++)  
    320.             {  
    321.                index2=((a7_nWidth+j)<<2);  
    322.                index3=(j<<2);  
    323.                //blue通道  
    324.                nTmp4 = (nTmp3 * pbTmp1[index2+MT_BLUE] +nTmp2 * pbTmp1[index3+MT_BLUE] + 0x2000)>>14;  
    325.                a2_pData_Dst[index3+MT_BLUE] = nTmp4&0xff;  
    326.                //green通道  
    327.                nTmp4 = (nTmp3 * pbTmp1[index2+MT_GREEN] +nTmp2 * pbTmp1[index3+MT_GREEN] + 0x2000)>>14;  
    328.                a2_pData_Dst[index3+MT_GREEN] = nTmp4&0xff;  
    329.                //red通道  
    330.                nTmp4 = (nTmp3 * pbTmp1[index2+MT_RED] +nTmp2 * pbTmp1[index3+MT_RED] + 0x2000)>>14;  
    331.                a2_pData_Dst[index3+MT_RED] = nTmp4&0xff;  
    332.                a2_pData_Dst[index3+MT_ALPHA] = 255;  
    333.   
    334.             }  
    335.             a2_pData_Dst += step;  
    336.         }  
    337.           
    338.     }  
    339.     else  
    340.     {  
    341.         for (int i=0;i<a3_nHeight;i++)  
    342.         {  
    343.             pbTmp1= &a1_pData_Src[a7_nWidth*a5_pData_Unknow[i]];  
    344.             nTmp2 = a10_pData_Unknow[a6_pData_Unknow[i]<<1];  
    345.             nTmp3 = a10_pData_Unknow[(a6_pData_Unknow[i]<<1) + 1];  
    346.             for (int j=0;j<a4_nWidth;j++)  
    347.             {  
    348.                nTmp4 = (nTmp3 * pbTmp1[a7_nWidth+j] +nTmp2 * pbTmp1[j] + 0x2000)>>14;  
    349.               a2_pData_Dst[j] = nTmp4&0xff;  
    350.              }  
    351.             a2_pData_Dst += a8_nWidthScrible;  
    352.   
    353.          }  
    354.     }  
    355.   

图像放大快速算法