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

DirextX编程

开发平台:

Visual C++

  1. /* idctref_miha.c, Inverse Discrete Fourier Transform, double precision */ /*************************************************************/
  2. /*                                                           */
  3. /* x87 hand-optimized assembly by Miha Peternel              */
  4. /*                                     27.11. - 20.1.2001    */
  5. /*                                                           */
  6. /* You are free to use this code in your project if:         */
  7. /* - no changes are made to this message                     */
  8. /* - any changes to this code are publicly available         */
  9. /* - your project documentation contains the following text: */
  10. /*   "This software contains fast high-quality IDCT decoder  */
  11. /*    by Miha Peternel."                                     */
  12. /*                                                           */
  13. /*************************************************************/
  14. /*  Perform IEEE 1180 reference (64-bit floating point, separable 8x1  *  direct matrix multiply) Inverse Discrete Cosine Transform */
  15. #define ModelX 123 // enable C-level optimizations by Miha Peternel /* Here we use math.h to generate constants.  Compiler results may    vary a little */ #include <math.h> #define M_PI 3.1415926535897932384626433832795 const static double HALF = 0.5;
  16. /* private data */
  17. static short iclip[1024+1024]; /* clipping table */
  18. static short *iclp;
  19. /* cosine transform matrix for 8x1 IDCT */ static double c[8][8]; /* initialize DCT coefficient matrix */ void Initialize_REF_IDCT() {   int freq, time, i;   double scale;   for (freq=0; freq < 8; freq++)   {     scale = (freq == 0) ? sqrt(0.125) : 0.5;     for (time=0; time<8; time++)       c[freq][time] = scale*cos((M_PI/8.0)*freq*(time + 0.5));   }
  20. #ifdef ModelX   iclp = iclip+1024;
  21.   for (i= -1024; i<1024; i++)
  22.     iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  23. #endif
  24. }
  25. void REF_IDCT(short *block) { double tmp[64];
  26. double rnd[64];
  27. int int0, int1, int2, int3, int4, int5, int6, int7;
  28. unsigned short fpold;
  29. unsigned short fpnew;
  30. int *b = (int *) block;
  31.   //if( b[0]==0 && (b[31]==0x10000 || b[31]==0) )
  32.   //if( b[0]==0 && ((b[31]&~0x10000)==0) )
  33.   if( !(b[0]|(b[31]&~0x10000)) )
  34. {
  35.   if( b[ 1]|b[ 2]|b[ 3]|b[ 4]|b[ 5]|b[ 6] )
  36.   goto normal;
  37.   if( b[ 7]|b[ 8]|b[ 9]|b[10]|b[11]|b[12] )
  38.   goto normal;
  39.   if( b[13]|b[14]|b[15]|b[16]|b[17]|b[18] )
  40.   goto normal;
  41.   if( b[19]|b[20]|b[21]|b[22]|b[23]|b[24] )
  42.   goto normal;
  43.   if( b[25]|b[26]|b[27]|b[28]|b[29]|b[30] )
  44.   goto normal;
  45. b[31]=0;
  46. return;
  47. }
  48. normal:
  49. __asm
  50. {
  51. // do the IDCT
  52. mov esi,[block]
  53. lea eax,[c]
  54. lea edi,[tmp]
  55. //mov ebx,8
  56. mov ebx,8 // 0x77000000 // 8
  57. align 16
  58. __col1:
  59.     movzx edx,[esi+1*2]
  60. mov   ecx,[esi+2*2]
  61. or    edx,[esi+4*2]
  62. or    ecx,[esi+6*2]
  63. or edx,ecx
  64. //mov ecx,8
  65. mov ecx,8/2 // 0x77000000 // 8
  66. //fild  word ptr [esi+0*2]
  67. //fmul qword ptr [eax+0*8*8]
  68. jnz __row1
  69. fild  word ptr [esi+0*2]
  70. fmul qword ptr [eax+0*8*8]
  71. fst  qword ptr [edi+0*8]
  72. fst  qword ptr [edi+1*8]
  73. fst  qword ptr [edi+2*8]
  74. fst  qword ptr [edi+3*8]
  75. fst  qword ptr [edi+4*8]
  76. fst  qword ptr [edi+5*8]
  77. fst  qword ptr [edi+6*8]
  78. fstp qword ptr [edi+7*8]
  79. add edi,8*8
  80. jmp __next1
  81. align 16
  82. __row1:
  83. fild  word ptr [esi+0*2]
  84. fmul qword ptr [eax+0*8*8]
  85. fild  word ptr [esi+1*2]
  86. fmul qword ptr [eax+1*8*8]
  87. fadd
  88. fild  word ptr [esi+2*2]
  89. fmul qword ptr [eax+2*8*8]
  90. fadd
  91. fild  word ptr [esi+3*2]
  92. fmul qword ptr [eax+3*8*8]
  93. fadd
  94. fild  word ptr [esi+4*2]
  95. fmul qword ptr [eax+4*8*8]
  96. fadd
  97. fild  word ptr [esi+5*2]
  98. fmul qword ptr [eax+5*8*8]
  99. fadd
  100. fild  word ptr [esi+6*2]
  101. fmul qword ptr [eax+6*8*8]
  102. fadd
  103. fild  word ptr [esi+7*2]
  104. fmul qword ptr [eax+7*8*8]
  105. fadd
  106. //add eax,8
  107. //fstp qword ptr [edi]
  108. //add edi,8
  109. //
  110. fild  word ptr [esi+0*2]
  111. fmul qword ptr [eax+0*8*8+8]
  112. fild  word ptr [esi+1*2]
  113. fmul qword ptr [eax+1*8*8+8]
  114. fadd
  115. fild  word ptr [esi+2*2]
  116. fmul qword ptr [eax+2*8*8+8]
  117. fadd
  118. fild  word ptr [esi+3*2]
  119. fmul qword ptr [eax+3*8*8+8]
  120. fadd
  121. fild  word ptr [esi+4*2]
  122. fmul qword ptr [eax+4*8*8+8]
  123. fadd
  124. fild  word ptr [esi+5*2]
  125. fmul qword ptr [eax+5*8*8+8]
  126. fadd
  127. fild  word ptr [esi+6*2]
  128. fmul qword ptr [eax+6*8*8+8]
  129. fadd
  130. fild  word ptr [esi+7*2]
  131. fmul qword ptr [eax+7*8*8+8]
  132. fadd
  133. add eax,8*2
  134. fxch st(1)
  135. fstp qword ptr [edi]//
  136. fstp qword ptr [edi+8]
  137. add edi,8*2
  138. dec ecx
  139. // sub ecx,0x80000001 // add ecx,ecx 
  140. // js  __row1
  141.   //align 16
  142. //   test ecx,ecx // align jump &| redo flags
  143. jnz __row1
  144. add eax,-8*8
  145.   //align 16
  146. __next1:
  147. add esi,+8*2
  148. //dec ebx
  149. sub ebx,0x80000001 // add ebx,ebx 
  150. js  __col1
  151. //align 16
  152. test ebx,ebx // align jump &| redo flags
  153. jnz __col1
  154. lea esi,[tmp]
  155. lea eax,[c]
  156. lea edi,[rnd]
  157. //mov edi,[block]
  158.     fld qword ptr [HALF]
  159. mov ebx,8
  160. __row2:
  161. mov ecx,8/2
  162. align 16
  163. __col2:
  164. fld  qword ptr [esi+0*8*8]
  165. fmul qword ptr [eax+0*8*8]
  166. fld  qword ptr [esi+1*8*8]
  167. fmul qword ptr [eax+1*8*8]
  168. fadd
  169. fld  qword ptr [esi+2*8*8]
  170. fmul qword ptr [eax+2*8*8]
  171. fadd
  172. fld  qword ptr [esi+3*8*8]
  173. fmul qword ptr [eax+3*8*8]
  174. fadd
  175. fld  qword ptr [esi+4*8*8]
  176. fmul qword ptr [eax+4*8*8]
  177. fadd
  178. fld  qword ptr [esi+5*8*8]
  179. fmul qword ptr [eax+5*8*8]
  180. fadd
  181. fld  qword ptr [esi+6*8*8]
  182. fmul qword ptr [eax+6*8*8]
  183. fadd
  184. fld  qword ptr [esi+7*8*8]
  185. fmul qword ptr [eax+7*8*8]
  186. fadd
  187. fadd st(0),st(1)
  188. //add eax,8
  189. //fstp qword ptr [edi]
  190. //add edi,8*8
  191. fxch st(1)
  192. //
  193. fld  qword ptr [esi+0*8*8]
  194. fmul qword ptr [eax+0*8*8+8]
  195. fld  qword ptr [esi+1*8*8]
  196. fmul qword ptr [eax+1*8*8+8]
  197. fadd
  198. fld  qword ptr [esi+2*8*8]
  199. fmul qword ptr [eax+2*8*8+8]
  200. fadd
  201. fld  qword ptr [esi+3*8*8]
  202. fmul qword ptr [eax+3*8*8+8]
  203. fadd
  204. fld  qword ptr [esi+4*8*8]
  205. fmul qword ptr [eax+4*8*8+8]
  206. fadd
  207. fld  qword ptr [esi+5*8*8]
  208. fmul qword ptr [eax+5*8*8+8]
  209. fadd
  210. fld  qword ptr [esi+6*8*8]
  211. fmul qword ptr [eax+6*8*8+8]
  212. fadd
  213. fld  qword ptr [esi+7*8*8]
  214. fmul qword ptr [eax+7*8*8+8]
  215. fadd
  216. fadd st(0),st(1)
  217. add eax,8*2
  218. fxch st(2)
  219. fstp qword ptr [edi]
  220. fxch st(1)
  221. fstp qword ptr [edi+8*8]
  222. add edi,8*8*2
  223. /*
  224. fistp dword ptr [int0]
  225. mov edx,dword ptr [int0]
  226. mov dx,word ptr [iclip+2*1024+2*edx]
  227. mov word ptr [edi],dx
  228. add edi,8*2
  229. */
  230. dec ecx
  231. // sub ecx,0x80000001
  232. // js  __col2
  233.   //align 16
  234. // test ecx,ecx // align jump &| redo flags
  235. jnz __col2
  236. add eax,-8*8
  237. add esi,+8
  238. add edi,8-8*8*8
  239. //add edi,2-8*8*2
  240. //dec ebx
  241. sub ebx,0x80000001
  242. js  __row2
  243.   //align 16
  244. test ebx,ebx // align jump &| redo flags
  245. jnz __row2
  246. ffree st(0) // bye bye 0.5
  247.   // set x87 to floor mode
  248. fstcw [fpold]
  249. movzx eax, [fpold]
  250. //or ax, 0x0C00 // 3072
  251. //or ax, 0x0800 // round up
  252. or eax, 0x0400 // round down - floor
  253. mov [fpnew], ax
  254. fldcw [fpnew]
  255. // now floor the damn array
  256. lea esi, [rnd]
  257. mov edi, [block]
  258. mov ebx, -256 // clip min
  259. mov edx, +255 // clip max
  260. mov ecx, 8
  261. align 16
  262. __floor:
  263.   fld   qword ptr [esi+0*8]
  264. fistp dword ptr [int0]
  265.   mov eax,[int0]
  266. cmp   eax,ebx
  267. cmovl eax,ebx
  268. cmp   eax,edx
  269. cmovg eax,edx
  270.   fld   qword ptr [esi+1*8]
  271. fistp dword ptr [int1]
  272. mov word ptr [edi+0*2],ax
  273.   mov eax,[int1]
  274. cmp   eax,ebx
  275. cmovl eax,ebx
  276. cmp   eax,edx
  277. cmovg eax,edx
  278.   fld   qword ptr [esi+2*8]
  279. fistp dword ptr [int2]
  280. mov word ptr [edi+1*2],ax
  281.   mov eax,[int2]
  282. cmp   eax,ebx
  283. cmovl eax,ebx
  284. cmp   eax,edx
  285. cmovg eax,edx
  286.   fld   qword ptr [esi+3*8]
  287. fistp dword ptr [int3]
  288. mov word ptr [edi+2*2],ax
  289.   mov eax,[int3]
  290. cmp   eax,ebx
  291. cmovl eax,ebx
  292. cmp   eax,edx
  293. cmovg eax,edx
  294.   fld   qword ptr [esi+4*8]
  295. fistp dword ptr [int4]
  296. mov word ptr [edi+3*2],ax
  297.   mov eax,[int4]
  298. cmp   eax,ebx
  299. cmovl eax,ebx
  300. cmp   eax,edx
  301. cmovg eax,edx
  302.   fld   qword ptr [esi+5*8]
  303. fistp dword ptr [int5]
  304. mov word ptr [edi+4*2],ax
  305.   mov eax,[int5]
  306. cmp   eax,ebx
  307. cmovl eax,ebx
  308. cmp   eax,edx
  309. cmovg eax,edx
  310.   fld   qword ptr [esi+6*8]
  311. fistp dword ptr [int6]
  312. mov word ptr [edi+5*2],ax
  313.   mov eax,[int6]
  314. cmp   eax,ebx
  315. cmovl eax,ebx
  316. cmp   eax,edx
  317. cmovg eax,edx
  318.   fld   qword ptr [esi+7*8]
  319. fistp dword ptr [int7]
  320. mov word ptr [edi+6*2],ax
  321.   mov eax,[int7]
  322. cmp   eax,ebx
  323. cmovl eax,ebx
  324. cmp   eax,edx
  325. cmovg eax,edx
  326. mov word ptr [edi+7*2],ax
  327. add esi, 8*8
  328. add edi, 8*2
  329. //dec ecx
  330. sub ecx,0x80000001
  331. js  __floor
  332.   //align 16
  333. test ecx,ecx // align jump &| redo flags
  334. jnz __floor
  335. // set x87 to default mode
  336. fldcw [fpold]
  337. };
  338. }