1
0

idct.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "idct.h"
  2. #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
  3. #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
  4. #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
  5. #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
  6. #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
  7. #define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
  8. short IDCT::iclip[1024];
  9. short *IDCT::iclp=0;
  10. bool IDCT::initted = false;
  11. /* row (horizontal) IDCT
  12. *
  13. * 7 pi 1
  14. * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
  15. * l=0 8 2
  16. *
  17. * where: c[0] = 128
  18. * c[1..7] = 128*sqrt(2)
  19. */
  20. void IDCT::idctrow(short *blk)
  21. {
  22. int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  23. /* shortcut */
  24. if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
  25. (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
  26. {
  27. blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
  28. return;
  29. }
  30. x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
  31. /* first stage */
  32. x8 = W7*(x4+x5);
  33. x4 = x8 + (W1-W7)*x4;
  34. x5 = x8 - (W1+W7)*x5;
  35. x8 = W3*(x6+x7);
  36. x6 = x8 - (W3-W5)*x6;
  37. x7 = x8 - (W3+W5)*x7;
  38. /* second stage */
  39. x8 = x0 + x1;
  40. x0 -= x1;
  41. x1 = W6*(x3+x2);
  42. x2 = x1 - (W2+W6)*x2;
  43. x3 = x1 + (W2-W6)*x3;
  44. x1 = x4 + x6;
  45. x4 -= x6;
  46. x6 = x5 + x7;
  47. x5 -= x7;
  48. /* third stage */
  49. x7 = x8 + x3;
  50. x8 -= x3;
  51. x3 = x0 + x2;
  52. x0 -= x2;
  53. x2 = (181*(x4+x5)+128)>>8;
  54. x4 = (181*(x4-x5)+128)>>8;
  55. /* fourth stage */
  56. blk[0] = (x7+x1)>>8;
  57. blk[1] = (x3+x2)>>8;
  58. blk[2] = (x0+x4)>>8;
  59. blk[3] = (x8+x6)>>8;
  60. blk[4] = (x8-x6)>>8;
  61. blk[5] = (x0-x4)>>8;
  62. blk[6] = (x3-x2)>>8;
  63. blk[7] = (x7-x1)>>8;
  64. }
  65. /* column (vertical) IDCT
  66. *
  67. * 7 pi 1
  68. * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
  69. * l=0 8 2
  70. *
  71. * where: c[0] = 1/1024
  72. * c[1..7] = (1/1024)*sqrt(2)
  73. */
  74. void IDCT::idctcol(short *blk)
  75. {
  76. int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  77. /* shortcut */
  78. if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
  79. (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
  80. {
  81. blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
  82. iclp[(blk[8*0]+32)>>6];
  83. return;
  84. }
  85. x0 = (blk[8*0]<<8) + 8192;
  86. /* first stage */
  87. x8 = W7*(x4+x5) + 4;
  88. x4 = (x8+(W1-W7)*x4)>>3;
  89. x5 = (x8-(W1+W7)*x5)>>3;
  90. x8 = W3*(x6+x7) + 4;
  91. x6 = (x8-(W3-W5)*x6)>>3;
  92. x7 = (x8-(W3+W5)*x7)>>3;
  93. /* second stage */
  94. x8 = x0 + x1;
  95. x0 -= x1;
  96. x1 = W6*(x3+x2) + 4;
  97. x2 = (x1-(W2+W6)*x2)>>3;
  98. x3 = (x1+(W2-W6)*x3)>>3;
  99. x1 = x4 + x6;
  100. x4 -= x6;
  101. x6 = x5 + x7;
  102. x5 -= x7;
  103. /* third stage */
  104. x7 = x8 + x3;
  105. x8 -= x3;
  106. x3 = x0 + x2;
  107. x0 -= x2;
  108. x2 = (181*(x4+x5)+128)>>8;
  109. x4 = (181*(x4-x5)+128)>>8;
  110. /* fourth stage */
  111. blk[8*0] = iclp[(x7+x1)>>14];
  112. blk[8*1] = iclp[(x3+x2)>>14];
  113. blk[8*2] = iclp[(x0+x4)>>14];
  114. blk[8*3] = iclp[(x8+x6)>>14];
  115. blk[8*4] = iclp[(x8-x6)>>14];
  116. blk[8*5] = iclp[(x0-x4)>>14];
  117. blk[8*6] = iclp[(x3-x2)>>14];
  118. blk[8*7] = iclp[(x7-x1)>>14];
  119. }
  120. /* two dimensional inverse discrete cosine transform */
  121. void IDCT::idct(short *block)
  122. {
  123. int i;
  124. for (i=0; i<8; i++)
  125. idctrow(block+8*i);
  126. for (i=0; i<8; i++)
  127. idctcol(block+i);
  128. }
  129. void IDCT::init()
  130. {
  131. if (!initted)
  132. {
  133. int i;
  134. iclp = iclip+512;
  135. for (i= -512; i<512; i++)
  136. iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  137. initted=true;
  138. }
  139. }