图形图像处理-之-高质量的快速的图像缩放 补充 使用SSE2优化_第1页
图形图像处理-之-高质量的快速的图像缩放 补充 使用SSE2优化_第2页
图形图像处理-之-高质量的快速的图像缩放 补充 使用SSE2优化_第3页
图形图像处理-之-高质量的快速的图像缩放 补充 使用SSE2优化_第4页
图形图像处理-之-高质量的快速的图像缩放 补充 使用SSE2优化_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、.图形图像处理之高质量的快速的图像缩放 补充 使用SSE2优化                           HouSisongGM    2011.04.12 tag: 图像缩放,速度优化,线性插值,三次卷积插值,SSE2,scale,bilinear,bicubic,S

2、tretchBlt 摘要:   本文章对线性插值和三次卷积插值(bicubic)的实现做了一些新的优化尝试;使用了SSE2的128bit寄存器及相关指令;并预先建立SSE2用到的缩放系数表; 实现的结果在我的i7电脑上比以前的版本分别快出145%和75%!线性插值的速度是StretchBlt的13倍! 正文: (请先看看我的blog里<高质量的快速的图像缩放>的前3篇文章!)支持SSE2指令集的CPU越来越多,CPU的SSE2实现性能也好了很多(以前不比MMX好多少),而且软件在64位模式的时候不再支持MMX,所以尝试了S

3、SE2的缩放优化,效果不错! 速度测试说明:   只测试内存数据到内存数据的缩放  测试图片都是800*600缩放到1024*768,单线程;fps表示每秒钟的帧数,值越大表示函数越快. 速度测试对比: (CPU:i7 920 内存:DDR3 1333 3通道) (windows)StretchBlt  近邻取样           869.09 fpsStretchBlt  线性插值  

4、;          44.46 fps /SetStretchBltMode(dc,4);? PicZoom0:                       95.69 fpsPicZoom1:       

5、               158.35 fpsPicZoom2:                      332.78 fpsPicZoom3:        &#

6、160;            1172.79 fpsPicZoom3_float:                874.13 fpsPicZoom3_Table:               11

7、58.30 fpsPicZoom3_SSE:                 1908.40 fpsPicZoom_Bilinear0:              28.80 fpsPicZoom_Bilinear1:       

8、0;      56.09 fpsPicZoom_Bilinear2:              97.09 fpsPicZoom_Bilinear_Common:       119.83 fpsPicZoom_Bilinear_MMX:          180.1

9、2 fpsPicZoom_Bilinear_MMX_Ex:       237.34 fpsPicZoom_ftBilinear_Common:     118.67 fpsPicZoom_ftBilinear_MMX:        213.68 fpsPicZoom_ThreeOrder0:           &

10、#160; 6.11 fpsPicZoom_ThreeOrder_Common:      25.38 fpsPicZoom_ThreeOrder_MMX:         52.32 fps (SSE2的实现)PicZoom_ftBilinearTable_SSE2:  588.24 fpsPicZoom_ThreeOrderTable_SSE2:   93.24 fps  PicZoom_ftBilin

11、earTable_SSE2实现代码如下:view plain1.     typedef UInt64 TMMXData64;  2.     /ftBilinearTable_SSE2(out edi+ebx*4; xmm5=v,xmm6=vr,xmm7=0,ebp=(u,ur),edx=srx_x,esi=PSrcLineColor,ecx=PSrcLineColorNext)  3.     

12、;/void _declspec(naked) ftBilinearTable_SSE2()  4.     #define  ftBilinearTable_SSE2()                     /  5.    

13、0;    asm mov         eax,edx+ebx                   /  6.         asm movq 

14、       xmm0,qword ptresi+eax*4       /  7.         asm movq        xmm1,qword ptrecx+eax*4      

15、; /  8.         asm punpcklbw   xmm0,xmm7                       /  9.      

16、   asm punpcklbw   xmm1,xmm7                       /  10.         asm pmullw   &

17、#160;  xmm0,mm5                        /  11.         asm pmullw      xmm1,mm6 &

18、#160;                      /  12.         asm paddw       xmm0,xmm1     

19、60;                 /  13.         asm pmulhw      xmm0,xmmword ptr ebp+ebx*4 /  14.    &#

20、160;    asm movdqa      xmm1,xmm0                       /  15.         asm 

21、punpckhqdq  xmm0,xmm0                       /  16.         asm paddw       xmm0,xmm1&

22、#160;                      /  17.         asm packuswb    xmm0,xmm7        

23、               /  18.         asm movd  dword ptr  edi+ebx,xmm0             

24、0;19.         /ret /for  _declspec(naked)  20.         /  21.     /  22.     /void _declspec(naked) ftBilinearTable_SSE2_expa

25、nd2()  23.     #define  ftBilinearTable_SSE2_expand2()             /  24.         asm mov        

26、60;eax,edx+ebx                   /  25.         asm movq        xmm0,qword ptresi+eax*4   

27、    /  26.         asm movq        xmm1,qword ptrecx+eax*4       /  27.         asm mov

28、60;        eax,edx+ebx+4                 /  28.         asm movq        xmm2,qwo

29、rd ptresi+eax*4       /  29.         asm movq        xmm3,qword ptrecx+eax*4       /  30.     &

30、#160;   asm punpcklbw   xmm0,xmm7                       /  31.         asm punpcklbw  

31、; xmm1,xmm7                       /  32.         asm punpcklbw   xmm2,xmm7      

32、                 /  33.         asm punpcklbw   xmm3,xmm7              

33、0;        /  34.         asm pmullw      xmm0,mm5                     

34、   /  35.         asm pmullw      xmm1,mm6                        /  3

35、6.         asm pmullw      xmm2,mm5                        /  37.      

36、;   asm pmullw      xmm3,mm6                        /  38.         asm padd

37、w       xmm0,xmm1                       /  39.         asm paddw     &

38、#160; xmm2,xmm3                       /  40.         asm pmulhw      xmm0,xmmword ptr 

39、;ebp+ebx*4 /  41.         asm pmulhw      xmm2,xmmword ptr ebp+ebx*4+16 /  42.         asm movdqa      xmm1,xm

40、m0                       /  43.         asm punpcklqdq  xmm0,xmm2         &

41、#160;             /  44.         asm punpckhqdq  xmm1,xmm2                  

42、0;    /  45.         asm paddw       xmm0,xmm1                       / 

43、; 46.         asm packuswb    xmm0,xmm7                       /  47.       

44、  asm movq  qword ptr  edi+ebx,xmm0             /  48.         /ret /for  _declspec(naked)  49.     

45、    /  50.     /  51.      52. void PicZoom_ftBilinearTable_SSE2(const TPixels32Ref& Dst,const TPixels32Ref& Src)  53.   54.     if (

46、0; (0=Dst.width)|(0=Dst.height)  55.         |(2>Src.width)|(2>Src.height) return;  56.     long xrIntFloat_16=(Src.width-1)<<16)/Dst.width;  57.     long yrI

47、ntFloat_16=(Src.height-1)<<16)/Dst.height;  58.     long dst_width=Dst.width;  59.     UInt8* _bufMem=new UInt8(dst_width*2*sizeof(TMMXData64)+15)+dst_width*sizeof(Int32);  60.     TMMXData

48、64* uList=(TMMXData64*)(ptrdiff_t)_bufMem)+15)>>4<<4); /16byte对齐  61.     Int32* xList=(Int32*)(uList+dst_width*2);  62.     /init u table  63.         l

49、ong srcx_16=0;  64.         for (long x=0;x<dst_width*2;x+=2)  65.             xListx>>1=(srcx_16>>16);  66.      &

50、#160;      unsigned long u=(srcx_16>>8)&0xFF;  67.             unsigned long ur=(256-u)<<1;  68.          

51、60;  u=u<<1;  69.             uListx+0=(ur|(ur<<16);  70.             uListx+0|=uListx+0<<32;  71.     

52、;        uListx+1=u|(u<<16);  72.             uListx+1|=uListx+1<<32;  73.             srcx_16+=xrIntFloat_1

53、6;  74.           75.       76.     Color32* pDstLine=Dst.pdata;  77.     long srcy_16=0;  78.     asm pxor &#

54、160;xmm7,xmm7 /xmm7=0  79.     for (long y=0;y<Dst.height;+y)  80.         unsigned long v=(srcy_16>>8) & 0xFF;  81.        

55、60;unsigned long vr=(256-v)>>1;  82.         v>>=1;  83.         Color32* PSrcLineColor= (Color32*)(UInt8*)(Src.pdata)+Src.byte_width*(srcy_16>>16)  

56、60;84.         Color32* PSrcLineColorNext= (Color32*)(UInt8*)(PSrcLineColor)+Src.byte_width)   85.         asm  86.            

57、60;  movd        xmm5,vr  87.               movd        xmm6,v  88.         

58、0;     punpcklwd   xmm5,xmm5  89.               punpcklwd   xmm6,xmm6  90.              &#

59、160;punpckldq   xmm5,xmm5  91.               punpckldq   xmm6,xmm6  92.               punpcklqdq  xm

60、m5,xmm5  93.               punpcklqdq  xmm6,xmm6  94.              95.           

61、0;   mov       esi,PSrcLineColor  96.               mov       ecx,PSrcLineColorNext  97.       

62、        mov       edx,xList /x  98.               mov       ebx,dst_width  99.   

63、0;           mov       edi,pDstLine  100.               push      ebp  101.   &#

64、160;           mov       ebp,uList  102.               push      ebx  103.   

65、60;            104.               and       ebx,(not 1)  105.          

66、0;    test      ebx,ebx  106.               jle     end_loop2  107.   108.         &#

67、160;     lea       ebx,ebx*4  109.               lea       edi,edi+ebx  110.       &#

68、160;       lea       edx,edx+ebx  111.               lea       ebp,ebp+ebx*4  112.    

69、0;          neg       ebx  113.         loop2_start:  114.               /call f

70、tBilinearTable_SSE2_expand2  115.               ftBilinearTable_SSE2_expand2()  116.               add      &#

71、160;ebx,8  117.               jnz       loop2_start  118.         end_loop2:  119.        

72、     pop    ebx  120.             and    ebx,1   121.             test   eb

73、x,ebx  122.             jle    end_write  123.               lea       ebx,ebx*4  124

74、.               lea       edi,edi+ebx  125.               lea       edx,edx+ebx&

75、#160; 126.               lea       ebp,ebp+ebx*4  127.               neg      &#

76、160;ebx  128.         loop1_start:  129.               /call ftBilinearTable_SSE2  130.            &

77、#160;  ftBilinearTable_SSE2()  131.               add       ebx,4  132.               jnz 

78、      loop1_start  133.         end_write:  134.               pop       ebp  135.   

79、        136.         srcy_16+=yrIntFloat_16;  137.         (UInt8*&)pDstLine)+=Dst.byte_width;  138.       139.   &#

80、160; delete _bufMem;  140.     PicZoom_ThreeOrderTable_SSE2实现代码如下:view plain1.     static TMMXData64 SinXDivX_Table64_MMX(2<<8)+1;  2.     class _CAutoInti_SinXDivX_Table64_MMX  &

81、#160;3.     private:  4.         void _Inti_SinXDivX_Table64_MMX()  5.           6.             for 

82、(long i=0;i<=(2<<8);+i)  7.               8.                 unsigned short t=(unsigned short)(0.5+(1<<14

83、)*SinXDivX(i*(1.0/(256);  9.                 unsigned long tl=t|(unsigned long)t)<<16);  10.               &#

84、160; TMMXData64 tll=tl|(TMMXData64)tl)<<32);  11.                 SinXDivX_Table64_MMXi=tll;  12.               13

85、.           14.     public:  15.         _CAutoInti_SinXDivX_Table64_MMX()  _Inti_SinXDivX_Table64_MMX();   16.       17. 

86、60;   static _CAutoInti_SinXDivX_Table64_MMX _tmp_CAutoInti_SinXDivX_Table64_MMX;  18.     /void _declspec(naked)  _private_ThreeOrderTable_Fast_SSE2_2()  19.     #define  _private_ThreeOrde

87、rTable_Fast_SSE2_2() /  20.         asm movq        xmm0,qword ptr eax        /  21.         asm

88、0;movq        xmm1,qword ptr eax+8      /  22.         asm movq        xmm2,qword ptr eax+edx /  23.

89、         asm movq        xmm3,qword ptr eax+edx+8 /  24.         asm punpcklbw   xmm0,xmm7     / 

90、60;25.         asm punpcklbw   xmm1,xmm7     /  26.         asm punpcklbw   xmm2,xmm7     /  27.   &

91、#160;     asm punpcklbw   xmm3,xmm7     /  28.         asm psllw       xmm0,7      /  29.  

92、0;      asm psllw       xmm1,7      /  30.         asm psllw       xmm2,7      /

93、  31.         asm psllw       xmm3,7      /  32.         asm pmulhw      xmm0,xmmword ptr&

94、#160;ecx  /  33.         asm pmulhw      xmm1,xmmword ptr ecx+16 /  34.         asm pmulhw      xmm2,xmmw

95、ord ptr ecx  /  35.         asm pmulhw      xmm3,xmmword ptr ecx+16 /  36.         asm paddsw     &#

96、160;xmm0,xmm1     /  37.         asm paddsw      xmm2,xmm3     /  38.         asm pmulhw   

97、0;  xmm0,xmmword ptr ebx  /  39.         asm pmulhw      xmm2,xmmword ptr ebx+16 /  40.         asm paddsw 

98、60;    xmm0,xmm2     /  41.         /asm ret /for _declspec(naked)  42.     /  43.     must_inline UInt32 ThreeOrderTabl

99、e_Fast_SSE2(const Color32* pixel,long byte_width,const TMMXData64* v4,const TMMXData64* u4)  44.         asm mov     eax,pixel  45.        &

100、#160;asm mov     edx,byte_width  46.         asm mov     ebx,v4  47.         asm mov     ecx,u4  48.

101、         /asm call _private_ThreeOrderTable_Fast_SSE2_2  49.         _private_ThreeOrderTable_Fast_SSE2_2();  50.         asm movdqa  x

102、mm6,xmm0  51.         asm lea     eax,eax+edx*2  /+pic.byte_width  52.         asm lea     ebx,ebx+32  53.   &

103、#160;     /asm call _private_ThreeOrderTable_Fast_SSE2_2  54.         _private_ThreeOrderTable_Fast_SSE2_2();  55.         asm paddsw    

104、60; xmm6,xmm0  56.         asm movdqa      xmm5,xmm6  57.         asm psrldq      xmm6,8   /srl 8*8 

105、bit!  58.         asm paddsw      xmm5,xmm6  59.         asm psraw       xmm5,3  60.      

106、   asm packuswb    xmm5,xmm7  61.         asm movd        eax,xmm5  62.       63.     must_inline lo

107、ng getSizeBorder(long x,long maxx)  64.   if (x<=0)  65.    return 0;  66.   else if (x>=maxx)  67.    return maxx;  68.   else  69. &

108、#160;  return x;  70.       71.     must_inline UInt32 ThreeOrderTable_Border_SSE2(const TPixels32Ref& pic,const long x0_sub1,const long y0_sub1,const TMMXData64* v4,const

109、 TMMXData64* u4)  72.         Color32 pixel16;  73.         long height_sub_1=pic.height-1;  74.         long width_sub_1=pic

110、.width-1;  75.         Color32* pbuf=pixel;  76.         for (long i=0;i<4;+i,pbuf+=4)  77.             long

111、0;y=getSizeBorder(y0_sub1+i,height_sub_1);  78.             Color32* pLine=pic.getLinePixels(y);  79.             pbuf0=pLinegetSizeBorder(x0_sub1+0,width_

112、sub_1);  80.             pbuf1=pLinegetSizeBorder(x0_sub1+1,width_sub_1);  81.             pbuf2=pLinegetSizeBorder(x0_sub1+2,width_sub_1);  82.  

113、;           pbuf3=pLinegetSizeBorder(x0_sub1+3,width_sub_1);  83.           84.         return ThreeOrderTable_Fast_SSE2(pixel,4*sizeof(Colo

114、r32),v4,u4);  85.       86. void PicZoom_ThreeOrderTable_SSE2(const TPixels32Ref& Dst,const TPixels32Ref& Src)  87.   88.     if (  (0=Dst.width)|(0=Dst.height)  

115、89.         |(0=Src.width)|(0=Src.height) return;  90.     long dst_width=Dst.width;  91.     long dst_height=Dst.height;  92.     long xrIntFloat_16=

116、(Src.width)<<16)/dst_width+1;  93.     long yrIntFloat_16=(Src.height)<<16)/dst_height+1;  94.     const long csDErrorX=-(1<<15)+(xrIntFloat_16>>1);  95.     const lo

117、ng csDErrorY=-(1<<15)+(yrIntFloat_16>>1);  96.     /计算出需要特殊处理的边界  97.     long border_y0=(1<<16)-csDErrorY)/yrIntFloat_16+1;/y0+y*yr>=1; y0=csDErrorY => y>=(1-csDErrorY)/yr  98.

118、    if (border_y0>=dst_height) border_y0=dst_height;  99.     long border_x0=(1<<16)-csDErrorX)/xrIntFloat_16+1;  100.     if (border_x0>=dst_width ) border_x0=dst_width; &#

119、160;101.     long border_y1=(Src.height-3)<<16)-csDErrorY)/yrIntFloat_16+1; /y0+y*yr<=(height-3) => y<=(height-3-csDErrorY)/yr  102.     if (border_y1<border_y0) border_y1=border_y0;  103. 

120、60;   long border_x1=(Src.width-3)<<16)-csDErrorX)/xrIntFloat_16+1;  104.     if (border_x1<border_x0) border_x1=border_x0;  105.     UInt8* _bufMem=new UInt8(dst_width*4*sizeof(TMMXData64)+1

121、5)+dst_width*sizeof(Int32);  106.     TMMXData64* uList=(TMMXData64*)(ptrdiff_t)_bufMem)+15)>>4<<4); /16byte对齐  107.     Int32* xList=(Int32*)(uList+dst_width*4);  108.     /init 

122、;u table  109.         long srcx_16=csDErrorX;  110.         for (long x=0;x<dst_width*4;x+=4)  111.            

123、 xListx>>2=(srcx_16>>16)-1;  112.             long u=(srcx_16>>8)&0xFF;  113.             uListx+0=SinXDivX_Table64_MMX256+u;

124、60; 114.             uListx+1=SinXDivX_Table64_MMXu;  115.             uListx+2=SinXDivX_Table64_MMX256-u;  116.        

125、     uListx+3=SinXDivX_Table64_MMX512-u;  117.             srcx_16+=xrIntFloat_16;  118.           119.       120.

126、    TMMXData64 _v48+2;  121.     TMMXData64* v4=(&_v40); v4=(TMMXData64*)( (ptrdiff_t)v4)+15)>>4<<4);  122.     asm pxor    xmm7,xmm7  123.     Color32* pDstLine=Dst.pdata;  124.     long srcy_16=csDErrorY;  125.     for (long y=0;y<dst_height;+y)  126. 

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论