版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 绿色蓝色一年之计在于春小清新工作总结计划模板
- 质量管理负责人岗位职责培训
- 2025《谏太宗十思疏》治国理念课件
- 第8课 欧洲的思想解放运动 学案
- 2026年废弃电子产品处理协议
- 高一上学期期末考试语文模拟试题及答案
- 安全设施、用品及材料供应单位管理办法培训
- 光伏电站员工安全职责培训
- 2026年广东省惠州市单招职业适应性考试题库附参考答案详解(模拟题)
- 2026年广州城建职业学院单招职业技能考试题库含答案详解(能力提升)
- 林业项目监理工作总结与报告
- 化工造粒工安全教育考核试卷含答案
- 水利三防培训课件
- 制冷基础知识课件
- 锅炉满水培训课件
- 放射科质控管理(技师组)
- 2026年江西单招新能源汽车技术专业基础经典题详解
- 手键拍发课件
- 2026春教科版(新教材)小学科学一年级下册(全册)教学设计(附教材目录)
- 管理研究方法:逻辑、软件与案例 课件 第6章:社会网络分析及应用
- DB32∕T 5274-2025 聚氨酯硬泡体防水保温工程技术规程
评论
0/150
提交评论