Idct.cpp
上传用户:szklck
上传日期:2007-01-22
资源大小:925k
文件大小:5k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. // Idct.cpp: implementation of the CIdct class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "视频编解码器.h"
  6. #include "Idct.h"
  7. #include <math.h>
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
  17. #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
  18. #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
  19. #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
  20. #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
  21. #define W7 565  /* 2048*sqrt(2)*cos(7*pi/16) */
  22. # ifndef PI
  23. # ifdef M_PI
  24. #  define PI M_PI
  25. # else
  26. #  define PI 3.14159265358979323846
  27. # endif
  28. # endif
  29. // cosine transform matrix for 8x1 IDCT 
  30. static double c[8][8];
  31. static short iclip[1024]; // clipping table 
  32. static short *iclp;
  33. CIdct::CIdct()
  34. {
  35. }
  36. CIdct::~CIdct()
  37. {
  38. }
  39. void CIdct::idct(short *block)
  40. {
  41.   int i;
  42.   //行IDCT
  43.   for (i=0; i<8; i++)
  44.    idctrow(block+8*i);
  45.   //列IDCT
  46.   for (i=0; i<8; i++)
  47.     idctcol(block+i);
  48. }
  49. void CIdct::init_idct()
  50. {
  51.   int i;
  52.   iclp = iclip+512;
  53.   for (i= -512; i<512; i++)//iclp的取间是[-256 255]
  54.     iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  55. }
  56. //根据公式的变换DCT
  57. //初始化系数
  58. void CIdct::init_idctref()
  59. {
  60.   int freq, time;
  61.   double scale;
  62.   for (freq=0; freq < 8; freq++)
  63.   {
  64.     scale = (freq == 0) ? sqrt(0.125) : 0.5;
  65.     for (time=0; time<8; time++)
  66.       c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5));
  67.   }
  68. }
  69. //直接变换DCT
  70. void CIdct::idctref(short *block)
  71. {
  72.  int i, j, k, v;
  73.   double partial_product;
  74.   double tmp[64];
  75.   for (i=0; i<8; i++)
  76.     for (j=0; j<8; j++)
  77.     {
  78.       partial_product = 0.0;
  79.       for (k=0; k<8; k++)
  80.         partial_product+= c[k][j]*block[8*i+k];
  81.       tmp[8*i+j] = partial_product;
  82.     }
  83.   // Transpose operation is integrated into address mapping 
  84.   //  by switching loop order of i and j 
  85.   for (j=0; j<8; j++)
  86.     for (i=0; i<8; i++)
  87.     {
  88.       partial_product = 0.0;
  89.       for (k=0; k<8; k++)
  90.         partial_product+= c[k][i]*tmp[8*k+j];
  91.       v =(int) floor(partial_product+0.5);
  92.       block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v);
  93. }
  94. }
  95. /* row (horizontal) IDCT
  96.  *
  97.  *           7                       pi         1
  98.  * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
  99.  *          l=0                      8          2
  100.  *
  101.  * where: c[0]    = 128
  102.  *        c[1..7] = 128*sqrt(2)
  103.  */
  104. // 
  105. void CIdct::idctrow(short *blk)
  106. {
  107.  int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  108.   /* shortcut */
  109.   if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
  110.         (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
  111.   {
  112.     blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
  113.     return;
  114.   }
  115.   x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
  116.   /* first stage */
  117.   x8 = W7*(x4+x5);
  118.   x4 = x8 + (W1-W7)*x4;
  119.   x5 = x8 - (W1+W7)*x5;
  120.   x8 = W3*(x6+x7);
  121.   x6 = x8 - (W3-W5)*x6;
  122.   x7 = x8 - (W3+W5)*x7;
  123.   
  124.   /* second stage */
  125.   x8 = x0 + x1;
  126.   x0 -= x1;
  127.   x1 = W6*(x3+x2);
  128.   x2 = x1 - (W2+W6)*x2;
  129.   x3 = x1 + (W2-W6)*x3;
  130.   x1 = x4 + x6;
  131.   x4 -= x6;
  132.   x6 = x5 + x7;
  133.   x5 -= x7;
  134.   
  135.   /* third stage */
  136.   x7 = x8 + x3;
  137.   x8 -= x3;
  138.   x3 = x0 + x2;
  139.   x0 -= x2;
  140.   x2 = (181*(x4+x5)+128)>>8;
  141.   x4 = (181*(x4-x5)+128)>>8;
  142.   
  143.   /* fourth stage */
  144.   blk[0] = (x7+x1)>>8;
  145.   blk[1] = (x3+x2)>>8;
  146.   blk[2] = (x0+x4)>>8;
  147.   blk[3] = (x8+x6)>>8;
  148.   blk[4] = (x8-x6)>>8;
  149.   blk[5] = (x0-x4)>>8;
  150.   blk[6] = (x3-x2)>>8;
  151.   blk[7] = (x7-x1)>>8;
  152. }
  153. /* column (vertical) IDCT
  154.  *
  155.  *             7                         pi         1
  156.  * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
  157.  *            l=0                        8          2
  158.  *
  159.  * where: c[0]    = 1/1024
  160.  *        c[1..7] = (1/1024)*sqrt(2)
  161.  */
  162. void CIdct::idctcol(short *blk)
  163. {
  164.   int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  165.   /* shortcut */
  166.   if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
  167.         (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
  168.   {
  169.     blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
  170.       iclp[(blk[8*0]+32)>>6];
  171.     return;
  172.   }
  173.   x0 = (blk[8*0]<<8) + 8192;
  174.   /* first stage */
  175.   x8 = W7*(x4+x5) + 4;
  176.   x4 = (x8+(W1-W7)*x4)>>3;
  177.   x5 = (x8-(W1+W7)*x5)>>3;
  178.   x8 = W3*(x6+x7) + 4;
  179.   x6 = (x8-(W3-W5)*x6)>>3;
  180.   x7 = (x8-(W3+W5)*x7)>>3;
  181.   
  182.   /* second stage */
  183.   x8 = x0 + x1;
  184.   x0 -= x1;
  185.   x1 = W6*(x3+x2) + 4;
  186.   x2 = (x1-(W2+W6)*x2)>>3;
  187.   x3 = (x1+(W2-W6)*x3)>>3;
  188.   x1 = x4 + x6;
  189.   x4 -= x6;
  190.   x6 = x5 + x7;
  191.   x5 -= x7;
  192.   
  193.   /* third stage */
  194.   x7 = x8 + x3;
  195.   x8 -= x3;
  196.   x3 = x0 + x2;
  197.   x0 -= x2;
  198.   x2 = (181*(x4+x5)+128)>>8;
  199.   x4 = (181*(x4-x5)+128)>>8;
  200.   
  201.   /* fourth stage */
  202.   blk[8*0] = iclp[(x7+x1)>>14];//截取
  203.   blk[8*1] = iclp[(x3+x2)>>14];
  204.   blk[8*2] = iclp[(x0+x4)>>14];
  205.   blk[8*3] = iclp[(x8+x6)>>14];
  206.   blk[8*4] = iclp[(x8-x6)>>14];
  207.   blk[8*5] = iclp[(x0-x4)>>14];
  208.   blk[8*6] = iclp[(x3-x2)>>14];
  209.   blk[8*7] = iclp[(x7-x1)>>14];
  210. }