idctfpu.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. /* idct.c, inverse fast discrete cosine transform                           */
  3. /*************************************************************/
  4. /* inverse two dimensional DCT, Chen-Wang algorithm          */
  5. /* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984)                */
  6. /*                                                           */
  7. /* floating point conversion by Miha Peternel                */
  8. /* x87 hand-optimized assembly by Miha Peternel              */
  9. /*                                    27.11. - 11.12.2000    */
  10. /*                                                           */
  11. /* You are free to use this code in your project if:         */
  12. /* - no changes are made to this message                     */
  13. /* - any changes to this code are publicly available         */
  14. /* - your project documentation contains the following text: */
  15. /*   "This software contains fast high-quality IDCT decoder  */
  16. /*    by Miha Peternel."                                     */
  17. /*                                                           */
  18. /*************************************************************/
  19. /////////////////////////////////////////////////////
  20. //
  21. // TODO:
  22. // - loops can be easily vectorized for SIMD
  23. //
  24. /////////////////////////////////////////////////////
  25. #include <math.h>
  26. #  define PI 3.1415926535897932384626433832795
  27. #define FLOAT double
  28. const static double RC = 1.0*1024*1024*1024*1024*256*16 + 1024; // magic + clip center
  29. static FLOAT W1; // /* sqrt(2)*cos(1*pi/16) */
  30. static FLOAT W2; // /* sqrt(2)*cos(2*pi/16) */
  31. static FLOAT W5; // /* sqrt(2)*cos(5*pi/16) */
  32. static FLOAT W1_8;
  33. static FLOAT W2_8;
  34. static FLOAT W5_8;
  35. static FLOAT W7; // /* sqrt(2)*cos(7*pi/16) */
  36. static FLOAT W1mW7; // W1-W7
  37. static FLOAT W1pW7; // W1+W7
  38. static FLOAT W3; // /* sqrt(2)*cos(3*pi/16) */
  39. static FLOAT W3mW5; // W3-W5
  40. static FLOAT W3pW5; // W3+W5
  41. static FLOAT W6; // /* sqrt(2)*cos(6*pi/16) */
  42. static FLOAT W2mW6; // W2-W6
  43. static FLOAT W2pW6; // W2+W6
  44. static FLOAT S2; // 1/sqrt(2)
  45. static FLOAT D8 = 1.0/8;
  46. static FLOAT W7_8;
  47. static FLOAT W1mW7_8;
  48. static FLOAT W1pW7_8;
  49. static FLOAT W3_8;
  50. static FLOAT W3mW5_8;
  51. static FLOAT W3pW5_8;
  52. static FLOAT W6_8;
  53. static FLOAT W2mW6_8;
  54. static FLOAT W2pW6_8;
  55. /* global declarations */
  56. /* private data */
  57. static short iclip[1024+1024]; /* clipping table */
  58. static short *iclp;
  59. void Initialize_FPU_IDCT()
  60. {
  61.   int i;
  62.   S2 = sqrt(0.5); // 1.0/sqrt(2);
  63.   W1 = sqrt(2.0)*cos(PI*(1.0/16)); 
  64. W1_8 = W1/8;
  65.   W2 = sqrt(2.0)*cos(PI*(2.0/16)); 
  66. W2_8 = W2/8;
  67.   W3 = sqrt(2.0)*cos(PI*(3.0/16)); 
  68. W3_8 = W3/8;
  69.   W5 = sqrt(2.0)*cos(PI*(5.0/16)); 
  70. W5_8 = W5/8;
  71.   W6 = sqrt(2.0)*cos(PI*(6.0/16)); 
  72. W6_8 = W6/8;
  73.   W7 = sqrt(2.0)*cos(PI*(7.0/16));
  74. W7_8 = W7/8;
  75.   W1mW7 = W1-W7;  W1mW7_8 = W1mW7/8;
  76.   W1pW7 = W1+W7;  W1pW7_8 = W1pW7/8;
  77.   W3mW5 = W3-W5;  W3mW5_8 = W3mW5/8;
  78.   W3pW5 = W3+W5;  W3pW5_8 = W3pW5/8;
  79.   W2mW6 = W2-W6;  W2mW6_8 = W2mW6/8;
  80.   W2pW6 = W2+W6;  W2pW6_8 = W2pW6/8;
  81.   iclp = iclip+1024;
  82.   for (i= -1024; i<1024; i++)
  83.     iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  84. }
  85. void FPU_IDCT(short *block)
  86. {
  87. int *b = (int *) block;
  88.   if( b[0]==0 && (b[31]==0x10000 || b[31]==0) )
  89. {
  90.   if( b[ 1]|b[ 2]|b[ 3]|b[ 4]|b[ 5] )
  91.   goto normal;
  92.   if( b[ 6]|b[ 7]|b[ 8]|b[ 9]|b[10] )
  93.   goto normal;
  94.   if( b[11]|b[12]|b[13]|b[14]|b[15] )
  95.   goto normal;
  96.   if( b[16]|b[17]|b[18]|b[19]|b[20] )
  97.   goto normal;
  98.   if( b[21]|b[22]|b[23]|b[24]|b[25] )
  99.   goto normal;
  100.   if( b[26]|b[27]|b[28]|b[29]|b[30] )
  101.   goto normal;
  102. b[31]=0;
  103. ////empty++;
  104. return;
  105. }
  106. normal:
  107. #define tmp  ebx
  108. #define tmp1 ebx-1*8
  109. #define tmp2 ebx-2*8
  110. #define tmp3 ebx-3*8
  111. #define int0 ebx-3*8-1*4
  112. #define int1 ebx-3*8-2*4
  113. #define int2 ebx-3*8-3*4
  114. #define int3 ebx-3*8-4*4
  115. #define int4 ebx-3*8-5*4
  116. #define int5 ebx-3*8-6*4
  117. #define int6 ebx-3*8-7*4
  118. #define int7 ebx-3*8-8*4
  119. #define SIZE 8*8*8+3*8+8*4+16 // locals + 16-byte alignment area
  120. __asm
  121. {
  122.   lea ebx,[esp-8*8*8]
  123. sub esp,SIZE
  124. and ebx,-16 // force 16-byte alignment of locals
  125. // rows
  126. mov esi,[block]
  127. lea edi,[tmp]
  128. mov ecx,8
  129. align 16
  130. Lrows:
  131.     movsx eax,word ptr [esi+2]
  132. or    eax,         [esi+4]
  133. or    eax,         [esi+8]
  134. or    eax,         [esi+12]
  135. jnz L1
  136. fild word ptr [esi+0*2]
  137. fst  qword ptr [edi+7*8]
  138. fst  qword ptr [edi+6*8]
  139. fst  qword ptr [edi+5*8]
  140. fst  qword ptr [edi+4*8]
  141. fst  qword ptr [edi+3*8]
  142. fst  qword ptr [edi+2*8]
  143. fst  qword ptr [edi+1*8]
  144. fstp qword ptr [edi+0*8]
  145. jmp L2
  146. align 16
  147. L1:
  148. fild word ptr [esi+7*2]
  149. fld st(0)
  150. fild word ptr [esi+1*2]
  151. fadd st(1),st(0)
  152. fld qword ptr [W7]
  153. fxch st(1)
  154. fmul qword ptr [W1mW7]
  155. fxch st(1)
  156. fmulp st(2),st(0)
  157. fadd st(0),st(1)
  158. fstp qword ptr [tmp1]
  159. fild word ptr [esi+3*2]
  160. fld st(0)
  161. fxch st(3)
  162. fmul qword ptr [W1pW7]
  163. fild word ptr [esi+5*2]
  164. fadd st(4),st(0)
  165. fmul qword ptr [W3mW5]
  166. fxch st(1)
  167. fsubp st(3),st(0)//fsubrp
  168. fld qword ptr [W3]
  169. fmulp st(4),st(0)
  170. fsubr st(0),st(3)
  171. fstp qword ptr [tmp2]
  172. fmul qword ptr [W3pW5]
  173. fsubp st(2),st(0)//fsubrp
  174. fxch st(1)
  175. fstp qword ptr [tmp3]
  176. fild word ptr [esi+0*2]
  177. fild word ptr [esi+4*2]
  178. fild word ptr [esi+2*2]
  179. fld st(0)
  180. fmul qword ptr [W2mW6]
  181. fld st(3)
  182. fild word ptr [esi+6*2]
  183. fxch st(5)
  184. fsub st(0),st(4)
  185. fxch st(3)
  186. fadd st(0),st(5)
  187. fxch st(1)
  188. faddp st(4),st(0)
  189. fld qword ptr [W6]
  190. fmulp st(1),st(0)
  191. fxch st(4)
  192. fmul qword ptr [W2pW6]
  193. fld qword ptr [tmp1]
  194. fsub qword ptr [tmp2]
  195. fld st(5)
  196. fxch st(3)
  197. faddp st(6),st(0)
  198. fld qword ptr [tmp1]
  199. fxch st(1)
  200. fstp qword ptr [tmp1]
  201. fld st(6)
  202. fadd qword ptr [tmp3]
  203. fxch st(1)
  204. fadd qword ptr [tmp2]
  205. fxch st(7)
  206. fsub qword ptr [tmp3]
  207. fxch st(1)
  208. fstp qword ptr [tmp2]
  209. fld st(4)
  210. fxch st(3)
  211. fsubrp st(2),st(0)//fsubp
  212. fxch st(4)
  213. fsub st(0),st(5)
  214. fxch st(2)
  215. faddp st(5),st(0)
  216. fld st(2)
  217. fsub st(0),st(1)
  218. fxch st(5)
  219. fstp qword ptr [tmp3]
  220. fld qword ptr [tmp1]
  221. fld qword ptr [S2]
  222. fxch st(4)
  223. faddp st(2),st(0)
  224. fld st(3)
  225. fxch st(1)
  226. fadd st(0),st(5)
  227. fmulp st(1),st(0)
  228. fld qword ptr [tmp3]
  229. fadd st(0),st(7)
  230. fxch st(5)
  231. fsubr qword ptr [tmp1]
  232. fxch st(5)
  233. fstp qword ptr [edi+0*8]
  234. fxch st(6)
  235. fsubr qword ptr [tmp3]
  236. fld st(2)
  237. fxch st(1)
  238. fstp qword ptr [edi+7*8]
  239. fadd qword ptr [tmp2]
  240. fxch st(3)
  241. fmulp st(4),st(0)
  242. fxch st(2)
  243. fstp qword ptr [edi+3*8]
  244. fld st(1)
  245. fadd st(0),st(5)
  246. fxch st(1)
  247. fsub qword ptr [tmp2]
  248. fxch st(2)
  249. fsubrp st(5),st(0)//fsubp
  250. fstp qword ptr [edi+1*8]
  251. fld st(2)
  252. fxch st(1)
  253. fstp qword ptr [edi+4*8]
  254. fxch st(2)
  255. fsub st(0),st(1)
  256. fxch st(2)
  257. faddp st(1),st(0)
  258. fxch st(2)
  259. fstp qword ptr [edi+6*8]
  260. fstp qword ptr [edi+5*8]
  261. fstp qword ptr [edi+2*8]
  262. L2:
  263.   add esi,8*2
  264. add edi,8*8
  265. dec ecx
  266. jnz Lrows
  267. // columns
  268.     lea esi,[tmp]
  269. mov edi,[block]
  270. lea edx,[iclip+1024*2]
  271. mov ecx,8
  272.     align 16
  273. Lcols:
  274. fld qword ptr [esi+7*8*8]
  275. fld st(0)
  276. fld qword ptr [esi+1*8*8]
  277. fadd st(1),st(0)
  278. fld qword ptr [W7_8]
  279. fxch st(1)
  280. fmul qword ptr [W1mW7_8]
  281. fxch st(1)
  282. fmulp st(2),st(0)
  283. fadd st(0),st(1)
  284. fstp qword ptr [tmp2]
  285. fld qword ptr [esi+3*8*8]
  286. fld st(0)
  287. fxch st(3)
  288. fmul qword ptr [W1pW7_8]
  289. fld qword ptr [esi+5*8*8]
  290. fadd st(4),st(0)
  291. fmul qword ptr [W3mW5_8]
  292. fxch st(1)
  293. fsubp st(3),st(0)//fsubrp
  294. fld qword ptr [W3_8]
  295. fmulp st(4),st(0)
  296. fsubr st(0),st(3)
  297. fstp qword ptr [tmp3]
  298. fld qword ptr [D8]
  299. fld qword ptr [esi+0*8*8]
  300. fmul st(0),st(1)
  301. fxch st(2)
  302. fmul qword ptr [W3pW5_8]
  303. fld qword ptr [esi+4*8*8]
  304. fmulp st(2),st(0)
  305. fld qword ptr [esi+6*8*8]
  306. fld st(3)
  307. fxch st(6)
  308. fsubrp st(2),st(0)//fsubp
  309. fld qword ptr [esi+2*8*8]
  310. fld st(0)
  311. fxch st(5)
  312. fsub st(0),st(4)
  313. fxch st(7)
  314. faddp st(4),st(0)
  315. fxch st(4)
  316. fadd st(0),st(1)
  317. fld qword ptr [W6_8]
  318. fxch st(2)
  319. fmul qword ptr [W2pW6_8]
  320. fxch st(2)
  321. fmulp st(1),st(0)
  322. fxch st(4)
  323. fmul qword ptr [W2mW6_8]
  324. fld qword ptr [tmp2]
  325. fsub qword ptr [tmp3]
  326. fxch st(2)
  327. fsubr st(0),st(5)
  328. fxch st(1)
  329. faddp st(5),st(0)
  330. fld qword ptr [tmp2]
  331. fxch st(2)
  332. fstp qword ptr [tmp2]
  333. fld st(5)
  334. fxch st(2)
  335. fadd qword ptr [tmp3]
  336. fxch st(6)
  337. fsub st(0),st(3)
  338. fxch st(2)
  339. faddp st(3),st(0)
  340. fld st(3)
  341. fsub st(0),st(5)
  342. fxch st(3)
  343. fstp qword ptr [tmp3]
  344. fxch st(3)
  345. faddp st(4),st(0)
  346. fld st(5)
  347. fld qword ptr [tmp2]
  348. fxch st(7)
  349. fsub st(0),st(4)
  350. fxch st(7)
  351. fadd st(0),st(2)
  352. fxch st(1)
  353. faddp st(4),st(0)
  354. fld qword ptr [S2]
  355. fmul st(1),st(0)
  356. fxch st(1)
  357. fstp qword ptr [tmp1]
  358. fld st(4)
  359. fadd st(0),st(6)
  360. fxch st(2)
  361. fsubr qword ptr [tmp2]
  362. fxch st(5)
  363. fsubrp st(6),st(0)//fsubp
  364. fxch st(1)
  365. fistp dword ptr [int0]
  366. fxch st(4)
  367. mov eax,[int0]
  368. movsx eax,word ptr [edx+2*eax]
  369. mov [edi+0*8*2],ax
  370. fistp dword ptr [int7]
  371. mov eax,[int7]
  372. fld st(0)
  373. movsx eax,word ptr [edx+2*eax]
  374. mov [edi+7*8*2],ax
  375. fadd qword ptr [tmp3]
  376. fistp dword ptr [int3]
  377. mov eax,[int3]
  378. movsx eax,word ptr [edx+2*eax]
  379. mov [edi+3*8*2],ax
  380. fsub qword ptr [tmp3]
  381. fld st(1)
  382. fxch st(1)
  383. fistp dword ptr [int4]
  384. mov eax,[int4]
  385. movsx eax,word ptr [edx+2*eax]
  386. mov [edi+4*8*2],ax
  387. fadd qword ptr [tmp1]
  388. fxch st(3)
  389. fmulp st(2),st(0)
  390. fxch st(2)
  391. fistp dword ptr [int1]
  392. fxch st(1)
  393. mov eax,[int1]
  394. movsx eax,word ptr [edx+2*eax]
  395. mov [edi+1*8*2],ax
  396. fsub qword ptr [tmp1]
  397. fld st(2)
  398. fsub st(0),st(2)
  399. fxch st(1)
  400. fistp dword ptr [int6]
  401. fxch st(2)
  402. mov eax,[int6]
  403. faddp st(1),st(0)
  404. movsx eax,word ptr [edx+2*eax]
  405. mov [edi+6*8*2],ax
  406. fistp dword ptr [int2]
  407. mov eax,[int2]
  408. movsx eax,word ptr [edx+2*eax]
  409. mov [edi+2*8*2],ax
  410. fistp dword ptr [int5]
  411. mov eax,[int5]
  412. movsx eax,word ptr [edx+2*eax]
  413. mov [edi+5*8*2],ax
  414.   add esi,8
  415. add edi,2
  416. dec ecx
  417. jnz Lcols
  418. add esp,SIZE
  419.   }
  420. }