home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Meia / source / idct_reference.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  7.1 KB  |  323 lines

  1. #include <string.h>
  2.  
  3. #include <vd2/Meia/MPEGIDCT.h>
  4. #include "tables.h"
  5.  
  6. using namespace nsVDMPEGTables;
  7.  
  8. template<int stride, bool round, class DT, class ST>
  9. static inline void reference_idct_1D(DT *dst, const ST *src) {
  10.     static const double cosvals[32]={
  11.         0.5*1,
  12.         0.5*0.98078528040323043,
  13.         0.5*0.92387953251128674,
  14.         0.5*0.83146961230254524,
  15.         0.5*0.70710678118654757,
  16.         0.5*0.55557023301960229,
  17.         0.5*0.38268343236508984,
  18.         0.5*0.19509032201612833,
  19.         0.5*6.1230317691118863e-017,
  20.         0.5*-0.19509032201612819,
  21.         0.5*-0.38268343236508973,
  22.         0.5*-0.55557023301960196,
  23.         0.5*-0.70710678118654746,
  24.         0.5*-0.83146961230254535,
  25.         0.5*-0.92387953251128674,
  26.         0.5*-0.98078528040323043,
  27.         0.5*-1,
  28.         0.5*-0.98078528040323043,
  29.         0.5*-0.92387953251128685,
  30.         0.5*-0.83146961230254546,
  31.         0.5*-0.70710678118654768,
  32.         0.5*-0.55557023301960218,
  33.         0.5*-0.38268343236509034,
  34.         0.5*-0.19509032201612866,
  35.         0.5*-1.8369095307335659e-016,
  36.         0.5*0.1950903220161283,
  37.         0.5*0.38268343236509,
  38.         0.5*0.55557023301960184,
  39.         0.5*0.70710678118654735,
  40.         0.5*0.83146961230254524,
  41.         0.5*0.92387953251128652,
  42.     };
  43.  
  44.     static const double coeffs4[4]={
  45.         4.0 * cosvals[1],
  46.         4.0 * cosvals[3],
  47.         4.0 * cosvals[5],
  48.         4.0 * cosvals[7],
  49.     };
  50.  
  51.     static const double coeffs2[2]={
  52.         4.0 * cosvals[2],
  53.         4.0 * cosvals[6],
  54.     };
  55.  
  56.     double t[8];
  57.  
  58.     for(int i=0; i<8; ++i)
  59.         t[i] = src[i*stride];
  60.  
  61.     double s[8], u[8];
  62.  
  63.     s[0] = t[0];
  64.     s[1] = t[4];
  65.     s[2] = t[2];
  66.     s[3] = t[6];
  67.     s[4] = t[1];
  68.     s[5] = t[5];
  69.     s[6] = t[3];
  70.     s[7] = t[7];
  71.  
  72.     s[5] -= s[7];
  73.     s[6] -= s[5];
  74.     s[4] -= s[6];
  75.     s[4] *= 0.70710678118654752440084436210485;
  76.     s[2] -= s[3];
  77.     s[2] *= 0.70710678118654752440084436210485;
  78.     s[6] -= s[7];
  79.     s[6] *= 0.70710678118654752440084436210485;
  80.  
  81.     // begin 2x2's
  82.  
  83.     u[0] = (s[0]+s[1]) * (0.70710678118654752440084436210485 * 0.5);
  84.     u[1] = (s[0]-s[1]) * (0.70710678118654752440084436210485 * 0.5);
  85.     u[2] = (s[2]+s[3]) * (0.70710678118654752440084436210485 * 0.5);
  86.     u[3] = (s[2]-s[3]) * (0.70710678118654752440084436210485 * 0.5);
  87.     u[4] = (s[4]+s[5]) * (0.70710678118654752440084436210485 * 0.5);
  88.     u[5] = (s[4]-s[5]) * (0.70710678118654752440084436210485 * 0.5);
  89.     u[6] = (s[6]+s[7]) * (0.70710678118654752440084436210485 * 0.5);
  90.     u[7] = (s[6]-s[7]) * (0.70710678118654752440084436210485 * 0.5);
  91.  
  92.     // end 2x2's
  93.  
  94.     u[2] *= coeffs2[0];
  95.     u[3] *= coeffs2[1];
  96.     u[6] *= coeffs2[0];
  97.     u[7] *= coeffs2[1];
  98.  
  99.     t[0] = (u[0]+u[2]);
  100.     t[1] = (u[1]+u[3]);
  101.     t[3] = (u[0]-u[2]);
  102.     t[2] = (u[1]-u[3]);
  103.     t[4] = (u[4]+u[6]);
  104.     t[5] = (u[5]+u[7]);
  105.     t[7] = (u[4]-u[6]);
  106.     t[6] = (u[5]-u[7]);
  107.  
  108.     // end 4x4's
  109.  
  110.     t[4] *= coeffs4[0];
  111.     t[5] *= coeffs4[1];
  112.     t[6] *= coeffs4[2];
  113.     t[7] *= coeffs4[3];
  114.  
  115.     s[0] = (t[0]+t[4]);
  116.     s[1] = (t[1]+t[5]);
  117.     s[2] = (t[2]+t[6]);
  118.     s[3] = (t[3]+t[7]);
  119.     s[4] = (t[3]-t[7]);
  120.     s[5] = (t[2]-t[6]);
  121.     s[6] = (t[1]-t[5]);
  122.     s[7] = (t[0]-t[4]);
  123.  
  124.     static const float magic_value = (float)((1<<23) + (1<<22));
  125.  
  126.     if (round) {
  127.         for(int i=0; i<8; ++i) {
  128.             union {
  129.                 float f;
  130.                 int i;
  131.             } converter;
  132.  
  133.             converter.f = (float)(s[i] + magic_value);
  134.  
  135. //            dst[i*stride] = (int)floor(0.5 + s[i]);
  136.             dst[i*stride] = (signed short)converter.i;
  137.         }
  138.     } else {
  139.         for(int i=0; i<8; ++i)
  140.             dst[i*stride] = (DT)s[i];
  141.     }
  142. }
  143.  
  144. template<int stride, bool round, class DT, class ST>
  145. static inline void reference_idct_1D_4x2(DT *dst, const ST *src) {
  146.     static const double coeffs2[2]={
  147.         4.0 * 0.5*0.92387953251128674,
  148.         4.0 * 0.5*0.38268343236508984,
  149.     };
  150.  
  151.     double t[8];
  152.  
  153.     for(int i=0; i<8; ++i)
  154.         t[i] = src[i*stride];
  155.  
  156.     double s[8], u[8];
  157.  
  158.     s[0] = t[0];
  159.     s[1] = t[4];
  160.     s[2] = t[2];
  161.     s[3] = t[6];
  162.     s[4] = t[1];
  163.     s[5] = t[5];
  164.     s[6] = t[3];
  165.     s[7] = t[7];
  166.  
  167.     s[2] -= s[3];
  168.     s[2] *= 0.70710678118654752440084436210485;
  169.     s[6] -= s[7];
  170.     s[6] *= 0.70710678118654752440084436210485;
  171.  
  172.     // begin 2x2's
  173.  
  174.     u[0] = (s[0]+s[1]) * (0.70710678118654752440084436210485 * 0.5);
  175.     u[1] = (s[0]-s[1]) * (0.70710678118654752440084436210485 * 0.5);
  176.     u[2] = (s[2]+s[3]) * (0.70710678118654752440084436210485 * 0.5);
  177.     u[3] = (s[2]-s[3]) * (0.70710678118654752440084436210485 * 0.5);
  178.     u[4] = (s[4]+s[5]) * (0.70710678118654752440084436210485 * 0.5);
  179.     u[5] = (s[4]-s[5]) * (0.70710678118654752440084436210485 * 0.5);
  180.     u[6] = (s[6]+s[7]) * (0.70710678118654752440084436210485 * 0.5);
  181.     u[7] = (s[6]-s[7]) * (0.70710678118654752440084436210485 * 0.5);
  182.  
  183.     // end 2x2's
  184.  
  185.     u[2] *= coeffs2[0];
  186.     u[3] *= coeffs2[1];
  187.     u[6] *= coeffs2[0];
  188.     u[7] *= coeffs2[1];
  189.  
  190.     t[0] = (u[0]+u[2]);
  191.     t[1] = (u[1]+u[3]);
  192.     t[3] = (u[0]-u[2]);
  193.     t[2] = (u[1]-u[3]);
  194.     t[4] = (u[4]+u[6]);
  195.     t[5] = (u[5]+u[7]);
  196.     t[7] = (u[4]-u[6]);
  197.     t[6] = (u[5]-u[7]);
  198.  
  199.     // end 4x4's
  200.  
  201.     s[0] = (t[0]+t[4]);
  202.     s[1] = (t[0]-t[4]);
  203.     s[2] = (t[1]+t[5]);
  204.     s[3] = (t[1]-t[5]);
  205.     s[4] = (t[2]+t[6]);
  206.     s[5] = (t[2]-t[6]);
  207.     s[6] = (t[3]+t[7]);
  208.     s[7] = (t[3]-t[7]);
  209.  
  210.     static const float magic_value = (float)((1<<23) + (1<<22));
  211.  
  212.     if (round) {
  213.         for(int i=0; i<8; ++i) {
  214.             union {
  215.                 float f;
  216.                 int i;
  217.             } converter;
  218.  
  219.             converter.f = (float)(s[i] + magic_value);
  220.  
  221. //            dst[i*stride] = (int)floor(0.5 + s[i]);
  222.             dst[i*stride] = (signed short)converter.i;
  223.         }
  224.     } else {
  225.         for(int i=0; i<8; ++i)
  226.             dst[i*stride] = (DT)s[i];
  227.     }
  228. }
  229.  
  230. static void reference_idct_2D(short *dct_coeff) {
  231.     double tmp[64];
  232.     int i;
  233.  
  234. #ifndef _M_AMD64
  235.     __asm emms
  236. #endif
  237.  
  238.     for(i=0; i<8; ++i)
  239.         reference_idct_1D<1, false, double, short>(tmp + 8*i, dct_coeff + 8*i);
  240.  
  241.     for(i=0; i<8; ++i)
  242.         reference_idct_1D<8, true, short, double>(dct_coeff + i, tmp + i);
  243. }
  244.  
  245. static void reference_idct_2D_4x2(short *dct_coeff) {
  246.     double tmp[64];
  247.     int i;
  248.  
  249. #ifndef _M_AMD64
  250.     __asm emms
  251. #endif
  252.  
  253.     for(i=0; i<8; ++i)
  254.         reference_idct_1D<1, false, double, short>(tmp + 8*i, dct_coeff + 8*i);
  255.  
  256.     for(i=0; i<8; ++i)
  257.         reference_idct_1D_4x2<8, true, short, double>(dct_coeff + i, tmp + i);
  258. }
  259.  
  260. static void reference_idct_intra(unsigned char *dst, int pitch, const short *src, int last_pos) {
  261.     short tmp[64];
  262.  
  263.     memcpy(tmp, src, sizeof tmp);
  264.  
  265.     reference_idct_2D(tmp);
  266.  
  267.     for(int j=0; j<8; ++j) {
  268.         for(int i=0; i<8; ++i) {
  269.             int v = tmp[j*8+i];
  270.  
  271.             dst[i] = clip_table[v + 288];
  272.         }
  273.         dst += pitch;
  274.     }
  275. }
  276.  
  277. static void reference_idct_nonintra(unsigned char *dst, int pitch, const short *src, int last_pos) {
  278.     short tmp[64];
  279.  
  280.     memcpy(tmp, src, sizeof tmp);
  281.  
  282.     reference_idct_2D(tmp);
  283.  
  284.     for(int j=0; j<8; ++j) {
  285.         for(int i=0; i<8; ++i) {
  286.             int v = tmp[j*8+i] + dst[i];
  287.  
  288.             dst[i] = clip_table[v+288];
  289.         }
  290.         dst += pitch;
  291.     }
  292. }
  293.  
  294. static void reference_idct_intra4x2(unsigned char *dst, int pitch, const short *src, int last_pos) {
  295.     short tmp[64];
  296.  
  297.     memcpy(tmp, src, sizeof tmp);
  298.  
  299.     reference_idct_2D_4x2(tmp);
  300.  
  301.     for(int j=0; j<8; ++j) {
  302.         for(int i=0; i<8; ++i) {
  303.             int v = tmp[j*8+i];
  304.  
  305.             dst[i] = clip_table[v+288];
  306.         }
  307.         dst += pitch;
  308.     }
  309. }
  310.  
  311. static void reference_idct_test(short *src, int last_pos) {
  312.     reference_idct_2D(src);
  313. }
  314.  
  315. const struct VDMPEGIDCTSet g_VDMPEGIDCT_reference = {
  316.     (tVDMPEGIDCT)reference_idct_intra,
  317.     (tVDMPEGIDCT)reference_idct_nonintra,
  318.     (tVDMPEGIDCTTest)reference_idct_test,
  319.     NULL,
  320.     NULL,
  321.     (tVDMPEGIDCT)reference_idct_intra4x2,
  322. };
  323.