idctfpu.c
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:12k
源码类别:

DirextX编程

开发平台:

Visual C++

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