idct.c
上传用户:dzbeite
上传日期:2022-08-01
资源大小:4k
文件大小:18k
源码类别:

数学计算

开发平台:

C++ Builder

  1. /* idct.c, inverse fast discrete cosine transform                           */
  2. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  3. /*
  4.  * Disclaimer of Warranty
  5.  *
  6.  * These software programs are available to the user without any license fee or
  7.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  8.  * any and all warranties, whether express, implied, or statuary, including any
  9.  * implied warranties or merchantability or of fitness for a particular
  10.  * purpose.  In no event shall the copyright-holder be liable for any
  11.  * incidental, punitive, or consequential damages of any kind whatsoever
  12.  * arising from the use of these programs.
  13.  *
  14.  * This disclaimer of warranty extends to the user of these programs and user's
  15.  * customers, employees, agents, transferees, successors, and assigns.
  16.  *
  17.  * The MPEG Software Simulation Group does not represent or warrant that the
  18.  * programs furnished hereunder are free of infringement of any third-party
  19.  * patents.
  20.  *
  21.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  22.  * are subject to royalty fees to patent holders.  Many of these patents are
  23.  * general enough such that they are unavoidable regardless of implementation
  24.  * design.
  25.  *
  26.  */
  27. /**********************************************************/
  28. /* inverse two dimensional DCT, Chen-Wang algorithm       */
  29. /* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984)             */
  30. /* 32-bit integer arithmetic (8 bit coefficients)         */
  31. /* 11 mults, 29 adds per DCT                              */
  32. /*                                      sE, 18.8.91       */
  33. /**********************************************************/
  34. /* coefficients extended to 12 bit for IEEE1180-1990      */
  35. /* compliance                           sE,  2.1.94       */
  36. /**********************************************************/
  37. /* floating point conversion by Miha Peternel             */
  38. /*                                      27-29.11.2000     */
  39. /**********************************************************/
  40. //#define ModelX 123 // enable old code
  41. //#define DoTest 123 // enable error logging to idct_log.txt
  42. #ifdef DoTest
  43. #include <stdio.h>
  44. static FILE *logf; /* log file */
  45. static int iter = 0;
  46. static int isum = 0;
  47. static int imax = 0;
  48. static double fsum = 0;
  49. static double fmax = 0;
  50. static double c[8][8]; /* cosine transform matrix for 8x1 IDCT */
  51. extern void idct_mmx_32( short *blk );
  52. #include <math.h>
  53. #ifndef PI
  54. # ifdef M_PI
  55. #  define PI M_PI
  56. # else
  57. #  define PI 3.14159265358979323846
  58. # endif
  59. #endif
  60. #endif
  61. #ifdef ModelX
  62. /////////////////////////////////////////////////////
  63. //
  64. // old integer stuff is disabled... scroll down !!!
  65. //
  66. /////////////////////////////////////////////////////
  67. /* this code assumes >> to be a two's-complement arithmetic */
  68. /* right shift: (-2)>>1 == -1 , (-3)>>1 == -2               */
  69. #include "config.h"
  70. #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
  71. #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
  72. #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
  73. #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
  74. #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
  75. #define W7 565  /* 2048*sqrt(2)*cos(7*pi/16) */
  76. /* global declarations */
  77. void Initialize_Fast_IDCT _ANSI_ARGS_((void));
  78. void Fast_IDCT _ANSI_ARGS_((short *block));
  79. /* private data */
  80. static short iclip[1024]; /* clipping table */
  81. static short *iclp;
  82. /* private prototypes */
  83. static void idctrow _ANSI_ARGS_((short *blk));
  84. static void idctcol _ANSI_ARGS_((short *blk));
  85. /* row (horizontal) IDCT
  86.  *
  87.  *           7                       pi         1
  88.  * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
  89.  *          l=0                      8          2
  90.  *
  91.  * where: c[0]    = 128
  92.  *        c[1..7] = 128*sqrt(2)
  93.  */
  94. static void idctrow(blk)
  95. short *blk;
  96. {
  97.   int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  98.   /* shortcut */
  99.   if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
  100.         (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
  101.   {
  102.     blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
  103.     return;
  104.   }
  105.   x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
  106.   /* first stage */
  107.   x8 = W7*(x4+x5);
  108.   x4 = x8 + (W1-W7)*x4;
  109.   x5 = x8 - (W1+W7)*x5;
  110.   x8 = W3*(x6+x7);
  111.   x6 = x8 - (W3-W5)*x6;
  112.   x7 = x8 - (W3+W5)*x7;
  113.   
  114.   /* second stage */
  115.   x8 = x0 + x1;
  116.   x0 -= x1;
  117.   x1 = W6*(x3+x2);
  118.   x2 = x1 - (W2+W6)*x2;
  119.   x3 = x1 + (W2-W6)*x3;
  120.   x1 = x4 + x6;
  121.   x4 -= x6;
  122.   x6 = x5 + x7;
  123.   x5 -= x7;
  124.   
  125.   /* third stage */
  126.   x7 = x8 + x3;
  127.   x8 -= x3;
  128.   x3 = x0 + x2;
  129.   x0 -= x2;
  130.   x2 = (181*(x4+x5)+128)>>8;
  131.   x4 = (181*(x4-x5)+128)>>8;
  132.   
  133.   /* fourth stage */
  134.   blk[0] = (x7+x1)>>8;
  135.   blk[1] = (x3+x2)>>8;
  136.   blk[2] = (x0+x4)>>8;
  137.   blk[3] = (x8+x6)>>8;
  138.   blk[4] = (x8-x6)>>8;
  139.   blk[5] = (x0-x4)>>8;
  140.   blk[6] = (x3-x2)>>8;
  141.   blk[7] = (x7-x1)>>8;
  142. }
  143. /* column (vertical) IDCT
  144.  *
  145.  *             7                         pi         1
  146.  * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
  147.  *            l=0                        8          2
  148.  *
  149.  * where: c[0]    = 1/1024
  150.  *        c[1..7] = (1/1024)*sqrt(2)
  151.  */
  152. static void idctcol(blk)
  153. short *blk;
  154. {
  155.   int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  156.   /* shortcut */
  157.   if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
  158.         (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
  159.   {
  160.     blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
  161.       iclp[(blk[8*0]+32)>>6];
  162.     return;
  163.   }
  164.   x0 = (blk[8*0]<<8) + 8192;
  165.   /* first stage */
  166.   x8 = W7*(x4+x5) + 4;
  167.   x4 = (x8+(W1-W7)*x4)>>3;
  168.   x5 = (x8-(W1+W7)*x5)>>3;
  169.   x8 = W3*(x6+x7) + 4;
  170.   x6 = (x8-(W3-W5)*x6)>>3;
  171.   x7 = (x8-(W3+W5)*x7)>>3;
  172.   
  173.   /* second stage */
  174.   x8 = x0 + x1;
  175.   x0 -= x1;
  176.   x1 = W6*(x3+x2) + 4;
  177.   x2 = (x1-(W2+W6)*x2)>>3;
  178.   x3 = (x1+(W2-W6)*x3)>>3;
  179.   x1 = x4 + x6;
  180.   x4 -= x6;
  181.   x6 = x5 + x7;
  182.   x5 -= x7;
  183.   
  184.   /* third stage */
  185.   x7 = x8 + x3;
  186.   x8 -= x3;
  187.   x3 = x0 + x2;
  188.   x0 -= x2;
  189.   x2 = (181*(x4+x5)+128)>>8;
  190.   x4 = (181*(x4-x5)+128)>>8;
  191.   
  192.   /* fourth stage */
  193.   blk[8*0] = iclp[(x7+x1)>>14];
  194.   blk[8*1] = iclp[(x3+x2)>>14];
  195.   blk[8*2] = iclp[(x0+x4)>>14];
  196.   blk[8*3] = iclp[(x8+x6)>>14];
  197.   blk[8*4] = iclp[(x8-x6)>>14];
  198.   blk[8*5] = iclp[(x0-x4)>>14];
  199.   blk[8*6] = iclp[(x3-x2)>>14];
  200.   blk[8*7] = iclp[(x7-x1)>>14];
  201. }
  202. /* two dimensional inverse discrete cosine transform */
  203. void Fast_IDCT(block)
  204. short *block;
  205. {
  206.   int i;
  207. #ifdef DoTest
  208.   int j, k, v;
  209.   double partial_product;
  210.   double tmp[64];
  211. double hfsum = 0;
  212. double hfmax = 0;
  213. int hisum = 0;
  214. int himax = 0;
  215.   for (i=0; i<8; i++)
  216.     for (j=0; j<8; j++)
  217.     {
  218.       partial_product = 0.0;
  219.       for (k=0; k<8; k++)
  220.         partial_product+= c[k][j]*block[8*i+k];
  221.       tmp[8*i+j] = partial_product;
  222.     }
  223. #endif
  224.   for (i=0; i<8; i++)
  225.     idctrow(block+8*i);
  226.   for (i=0; i<8; i++)
  227.     idctcol(block+i);
  228. #ifdef DoTest
  229.   /* Transpose operation is integrated into address mapping by switching 
  230.      loop order of i and j */
  231.   for (j=0; j<8; j++)
  232.     for (i=0; i<8; i++)
  233.     {
  234.   int ierr;
  235. double ferr;
  236.       partial_product = 0.0;
  237.       for (k=0; k<8; k++)
  238.         partial_product+= c[k][i]*tmp[8*k+j];
  239.       v = (int) floor(partial_product+0.5);
  240.       v = (v<-256) ? -256 : ((v>255) ? 255 : v);
  241.       ierr = abs(v-block[8*i+j]);
  242. //ferr = fabs(partial_product-fblock[8*i+j]);
  243. ferr = fabs(partial_product-block[8*i+j]); // integer test only
  244. block[8*i+j] = v;
  245. hisum += ierr; if( ierr > himax ) himax = ierr;
  246. hfsum += ferr; if( ferr > hfmax ) hfmax = ferr;
  247.     }
  248. iter++;
  249. isum += hisum;
  250. if( himax > imax ) imax = himax;
  251. fsum += hfsum;
  252. if( hfmax > fmax ) fmax = hfmax;
  253. if( himax > 0 || (iter & ((1<<10)-1)) == 0 )
  254. fprintf( logf, "%6d | %lg/%d %lg/%lg | %lg/%d %lg/%lg | %d %lgn",
  255.   iter,
  256.   hisum/64.0, himax,
  257. hfsum/64.0, hfmax,
  258.   isum/(64.0*iter), imax,
  259. fsum/(64.0*iter), fmax,
  260. isum, fsum );
  261. #endif
  262. }
  263. void Initialize_Fast_IDCT()
  264. {
  265.   int i;
  266. #ifdef DoTest
  267.   int freq, time;
  268.   double scale;
  269. #endif
  270.   iclp = iclip+512;
  271.   for (i= -512; i<512; i++)
  272.     iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  273. #ifdef DoTest
  274.   for (freq=0; freq < 8; freq++)
  275.   {
  276.     scale = (freq == 0) ? sqrt(0.125) : 0.5;
  277.     for (time=0; time<8; time++)
  278.       c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5));
  279.   }
  280. logf = fopen( "idct_log.txt", "wt" );
  281. // warning: we'll never close the file !!!!
  282. iter = 0;
  283. isum = 0;
  284. imax = 0;
  285. fsum = 0;
  286. fmax = 0;
  287. #endif
  288. }
  289. //////////////////////////////////////////////////////////////
  290. #else // ModelX
  291. /////////////////////////////////////////////////////
  292. //
  293. // here comes the real thing - 64-bit floating point
  294. // converted from MPEG sources by Miha Peternel
  295. //
  296. // TODO:
  297. // - loops can be easily vectorized for SIMD
  298. //
  299. /////////////////////////////////////////////////////
  300. #include "config.h"
  301. #include <math.h>
  302. #ifndef PI
  303. # ifdef M_PI
  304. #  define PI M_PI
  305. # else
  306. #  define PI 3.14159265358979323846
  307. # endif
  308. #endif
  309. #define FLOAT double
  310. ///*
  311. #define SCALE 1.0 // 2048.0
  312. #define FACT1 1.0
  313. #define FACT2 (1.0/8) // 256.0
  314. /*
  315. #define SCALE 2048.0
  316. #define FACT1 16384.0
  317. #define FACT2 256.0
  318. /**/
  319. const static double RC = 1.0*1024*1024*1024*1024*256*16 + 1024; // magic + clip center
  320. static FLOAT W1; // 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
  321. static FLOAT W2; // 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
  322. static FLOAT W5; // 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
  323. static FLOAT W1_8;
  324. static FLOAT W2_8;
  325. static FLOAT W5_8;
  326. static FLOAT W7; // 565  /* 2048*sqrt(2)*cos(7*pi/16) */
  327. static FLOAT W1mW7; // W1-W7
  328. static FLOAT W1pW7; // W1+W7
  329. static FLOAT W3; // 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
  330. static FLOAT W3mW5; // W3-W5
  331. static FLOAT W3pW5; // W3+W5
  332. static FLOAT W6; // 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
  333. static FLOAT W2mW6; // W2-W6
  334. static FLOAT W2pW6; // W2+W6
  335. static FLOAT S2; // 1/sqrt(2)
  336. static FLOAT D8 = FACT2; // 1.0/8
  337. static FLOAT W7_8;
  338. static FLOAT W1mW7_8;
  339. static FLOAT W1pW7_8;
  340. static FLOAT W3_8;
  341. static FLOAT W3mW5_8;
  342. static FLOAT W3pW5_8;
  343. static FLOAT W6_8;
  344. static FLOAT W2mW6_8;
  345. static FLOAT W2pW6_8;
  346. //static FLOAT fblock[8*8];
  347. /* global declarations */
  348. void Initialize_Fast_IDCT _ANSI_ARGS_((void));
  349. void Fast_IDCT _ANSI_ARGS_((short *block));
  350. /* private data */
  351. static short iclip[1024+1024]; /* clipping table */
  352. static short *iclp;
  353. /* private prototypes */
  354. //static void idctrow _ANSI_ARGS_((short *blk));
  355. //static void idctcol _ANSI_ARGS_((short *blk));
  356. /* row (horizontal) IDCT
  357.  *
  358.  *           7                       pi         1
  359.  * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
  360.  *          l=0                      8          2
  361.  *
  362.  * where: c[0]    = 128
  363.  *        c[1..7] = 128*sqrt(2)
  364.  */
  365. static void idctrow( short *blk, FLOAT *fblk )
  366. {
  367.   FLOAT x0, x1, x2, x3, x4, x5, x6, x7, x8;
  368.   /* shortcut */
  369. ///*
  370. int *i = (int *)blk;
  371.   if( !( blk[1] | i[1] | i[2] | i[3] ))
  372.   {
  373.     fblk[0]=fblk[1]=fblk[2]=fblk[3]=fblk[4]=fblk[5]=fblk[6]=fblk[7]= blk[0]*SCALE;//*8.0; //8=SCALE/FACT2
  374.     return;
  375.   }
  376. //*/
  377.   /* shortcut */
  378. /*
  379.   if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
  380.         (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
  381.   {
  382.     blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
  383.     return;
  384.   }
  385. */
  386. x1 = blk[4]*SCALE;//*2048;
  387. x2 = blk[6];
  388. x3 = blk[2];
  389.   x4 = blk[1];
  390. x5 = blk[7];
  391. x6 = blk[5];
  392. x7 = blk[3];
  393.   //x0 = (blk[0]*SCALE) + 128; /* for proper rounding in the fourth stage */
  394.   x0 = blk[0]*SCALE;//*2048;
  395.   /* first stage */
  396.   x8 = W7*(x4+x5);
  397.   x4 = x8 + (W1mW7)*x4;
  398.   x5 = x8 - (W1pW7)*x5;
  399.   x8 = W3*(x6+x7);
  400.   x6 = x8 - (W3mW5)*x6;
  401.   x7 = x8 - (W3pW5)*x7;
  402.   
  403.   /* second stage */
  404.   x8 = x0 + x1;
  405.   x0 -= x1;
  406.   x1 = W6*(x3+x2);
  407.   x2 = x1 - (W2pW6)*x2;
  408.   x3 = x1 + (W2mW6)*x3;
  409.   x1 = x4 + x6;
  410.   x4 -= x6;
  411.   x6 = x5 + x7;
  412.   x5 -= x7;
  413.   
  414.   /* third stage */
  415.   x7 = x8 + x3;
  416.   x8 -= x3;
  417.   x3 = x0 + x2;
  418.   x0 -= x2;
  419.   x2 = S2*(x4+x5);
  420.   x4 = S2*(x4-x5);
  421.   
  422.   /* fourth stage */
  423.   fblk[0] = (x7+x1); //*(1.0/256);
  424.   fblk[7] = (x7-x1); //*(1.0/256);
  425.   fblk[3] = (x8+x6); //*(1.0/256);
  426.   fblk[4] = (x8-x6); //*(1.0/256);
  427.   fblk[1] = (x3+x2); //*(1.0/256);
  428.   fblk[6] = (x3-x2); //*(1.0/256);
  429.   fblk[2] = (x0+x4); //*(1.0/256);
  430.   fblk[5] = (x0-x4); //*(1.0/256);
  431. }
  432. /* column (vertical) IDCT
  433.  *
  434.  *             7                         pi         1
  435.  * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
  436.  *            l=0                        8          2
  437.  *
  438.  * where: c[0]    = 1/1024
  439.  *        c[1..7] = (1/1024)*sqrt(2)
  440.  */
  441. static void idctcol( short *blk, FLOAT *fblk )
  442. {
  443.   double rc[8];
  444.   FLOAT x0, x1, x2, x3, x4, x5, x6, x7, x8;
  445.   /* shortcut */
  446. /*
  447.   if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
  448.         (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
  449.   {
  450.     blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
  451.       iclp[(blk[8*0]+32)>>6];
  452.     return;
  453.   }
  454. */
  455. x1 = fblk[8*4]*D8;
  456. x2 = fblk[8*6];
  457. x3 = fblk[8*2];
  458. x4 = fblk[8*1];
  459. x5 = fblk[8*7];
  460. x6 = fblk[8*5];
  461. x7 = fblk[8*3];
  462.   x0 = fblk[8*0]*D8;
  463.   /* first stage */
  464.   x8 = W7_8*(x4+x5);
  465.   x4 = (x8+(W1mW7_8)*x4);
  466.   x5 = (x8-(W1pW7_8)*x5);
  467.   x8 = W3_8*(x6+x7);
  468.   x6 = (x8-(W3mW5_8)*x6);
  469.   x7 = (x8-(W3pW5_8)*x7);
  470.   
  471.   /* second stage */
  472.   x8 = x0 + x1;
  473.   x0 -= x1;
  474.   x1 = W6_8*(x3+x2);
  475.   x2 = (x1-(W2pW6_8)*x2);
  476.   x3 = (x1+(W2mW6_8)*x3);
  477.   x1 = x4 + x6;
  478.   x4 -= x6;
  479.   x6 = x5 + x7;
  480.   x5 -= x7;
  481.   
  482.   /* third stage */
  483.   x7 = x8 + x3;
  484.   x8 -= x3;
  485.   x3 = x0 + x2;
  486.   x0 -= x2;
  487.   x2 = S2*(x4+x5);
  488.   x4 = S2*(x4-x5);
  489.   
  490.   /* fourth stage */
  491.   //blk[8*0] = iclp[(int)((x7+x1)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  492.   //blk[8*7] = iclp[(int)((x7-x1)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  493.   //blk[8*3] = iclp[(int)((x8+x6)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  494.   //blk[8*4] = iclp[(int)((x8-x6)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  495.   //blk[8*1] = iclp[(int)((x3+x2)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  496.   //blk[8*6] = iclp[(int)((x3-x2)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  497.   //blk[8*2] = iclp[(int)((x0+x4)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  498.   //blk[8*5] = iclp[(int)((x0-x4)*(1.0/FACT1/FACT2)+0.5)];//*(1.0/16384/256)];
  499. #ifdef DoTest
  500.   fblk[8*0] = (x7+x1);//*(1.0/16384/256)];
  501.   fblk[8*7] = (x7-x1);//*(1.0/16384/256)];
  502.   fblk[8*3] = (x8+x6);//*(1.0/16384/256)];
  503.   fblk[8*4] = (x8-x6);//*(1.0/16384/256)];
  504.   fblk[8*1] = (x3+x2);//*(1.0/16384/256)];
  505.   fblk[8*6] = (x3-x2);//*(1.0/16384/256)];
  506.   fblk[8*2] = (x0+x4);//*(1.0/16384/256)];
  507.   fblk[8*5] = (x0-x4);//*(1.0/16384/256)];
  508. #endif
  509.   rc[0] = (x7+x1)+RC;
  510.   rc[7] = (x7-x1)+RC;
  511.   rc[3] = (x8+x6)+RC;
  512.   rc[4] = (x8-x6)+RC;
  513.   rc[1] = (x3+x2)+RC;
  514.   rc[6] = (x3-x2)+RC;
  515.   rc[2] = (x0+x4)+RC;
  516.   rc[5] = (x0-x4)+RC;
  517. blk[8*0] = iclip[*((int*)(&rc[0]))];
  518. blk[8*7] = iclip[*((int*)(&rc[7]))];
  519. blk[8*3] = iclip[*((int*)(&rc[3]))];
  520. blk[8*4] = iclip[*((int*)(&rc[4]))];
  521. blk[8*1] = iclip[*((int*)(&rc[1]))];
  522. blk[8*6] = iclip[*((int*)(&rc[6]))];
  523. blk[8*2] = iclip[*((int*)(&rc[2]))];
  524. blk[8*5] = iclip[*((int*)(&rc[5]))];
  525. }
  526. /* two dimensional inverse discrete cosine transform */
  527. static FLOAT fblock[8*8];
  528. void Fast_IDCT(block)
  529. short *block;
  530. {
  531.   int i;
  532.   //FLOAT fblock[8*8];
  533. #ifdef DoTest
  534.   int j, k, v;
  535.   double partial_product;
  536.   double tmp[64];
  537. double hfsum = 0;
  538. double hfmax = 0;
  539. int hisum = 0;
  540. int himax = 0;
  541.   for (i=0; i<8; i++)
  542.     for (j=0; j<8; j++)
  543.     {
  544.       partial_product = 0.0;
  545.       for (k=0; k<8; k++)
  546.         partial_product+= c[k][j]*block[8*i+k];
  547.       tmp[8*i+j] = partial_product;
  548.     }
  549. #endif
  550.   for (i=0; i<8; i++)
  551.     idctrow(block+8*i,fblock+8*i);
  552.   for (i=0; i<8; i++)
  553.     idctcol(block+i,fblock+i);
  554.   //idct_mmx_32( block ); // test only
  555. #ifdef DoTest
  556.   /* Transpose operation is integrated into address mapping by switching 
  557.      loop order of i and j */
  558.   for (j=0; j<8; j++)
  559.     for (i=0; i<8; i++)
  560.     {
  561.   int ierr;
  562. double ferr;
  563.       partial_product = 0.0;
  564.       for (k=0; k<8; k++)
  565.         partial_product+= c[k][i]*tmp[8*k+j];
  566.       v = (int) floor(partial_product+0.5);
  567.       v = (v<-256) ? -256 : ((v>255) ? 255 : v);
  568.       ierr = abs(v-block[8*i+j]);
  569. ferr = fabs(partial_product-fblock[8*i+j]);
  570. //ferr = fabs(partial_product-block[8*i+j]); // integer test only
  571. block[8*i+j] = v;
  572. hisum += ierr; if( ierr > himax ) himax = ierr;
  573. hfsum += ferr; if( ferr > hfmax ) hfmax = ferr;
  574.     }
  575. iter++;
  576. isum += hisum;
  577. if( himax > imax ) imax = himax;
  578. fsum += hfsum;
  579. if( hfmax > fmax ) fmax = hfmax;
  580. if( himax > 0 || (iter & ((1<<10)-1)) == 0 )
  581. fprintf( logf, "%6d | %lg/%d %lg/%lg | %lg/%d %lg/%lg | %d %lgn",
  582.   iter,
  583.   hisum/64.0, himax,
  584. hfsum/64.0, hfmax,
  585.   isum/(64.0*iter), imax,
  586. fsum/(64.0*iter), fmax,
  587. isum, fsum );
  588. #endif
  589. }
  590. void Initialize_Fast_IDCT()
  591. {
  592.   int i;
  593. #ifdef DoTest
  594.   int freq, time;
  595.   double scale;
  596. #endif
  597.   S2 = sqrt(0.5); // 1.0/sqrt(2);
  598.   W1 = SCALE*sqrt(2)*cos(PI*(1.0/16)); 
  599. W1_8 = W1/8;
  600.   W2 = SCALE*sqrt(2)*cos(PI*(2.0/16)); 
  601. W2_8 = W2/8;
  602.   W3 = SCALE*sqrt(2)*cos(PI*(3.0/16)); 
  603. W3_8 = W3/8;
  604.   W5 = SCALE*sqrt(2)*cos(PI*(5.0/16)); 
  605. W5_8 = W5/8;
  606.   W6 = SCALE*sqrt(2)*cos(PI*(6.0/16)); 
  607. W6_8 = W6/8;
  608.   W7 = SCALE*sqrt(2)*cos(PI*(7.0/16));
  609. W7_8 = W7/8;
  610.   //W1 = 16*sqrt(2)*cos(PI*(1.0/16)); 
  611.   //W2 = 16*sqrt(2)*cos(PI*(2.0/16)); 
  612.   //W3 = 16*sqrt(2)*cos(PI*(3.0/16)); 
  613.   //W5 = 16*sqrt(2)*cos(PI*(5.0/16)); 
  614.   //W6 = 16*sqrt(2)*cos(PI*(6.0/16)); 
  615.   //W7 = 16*sqrt(2)*cos(PI*(7.0/16));
  616.   W1mW7 = W1-W7;  W1mW7_8 = W1mW7/8;
  617.   W1pW7 = W1+W7;  W1pW7_8 = W1pW7/8;
  618.   W3mW5 = W3-W5;  W3mW5_8 = W3mW5/8;
  619.   W3pW5 = W3+W5;  W3pW5_8 = W3pW5/8;
  620.   W2mW6 = W2-W6;  W2mW6_8 = W2mW6/8;
  621.   W2pW6 = W2+W6;  W2pW6_8 = W2pW6/8;
  622.   iclp = iclip+1024;
  623.   for (i= -1024; i<1024; i++)
  624.     iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  625. #ifdef DoTest
  626.   for (freq=0; freq < 8; freq++)
  627.   {
  628.     scale = (freq == 0) ? sqrt(0.125) : 0.5;
  629.     for (time=0; time<8; time++)
  630.       c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5));
  631.   }
  632. logf = fopen( "idct_log.txt", "wt" );
  633. // warning: we'll never close the file !!!!
  634. iter = 0;
  635. isum = 0;
  636. imax = 0;
  637. fsum = 0;
  638. fmax = 0;
  639. #endif
  640. }
  641. #endif // ModelX