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_scalar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  17.1 KB  |  816 lines

  1. #include <string.h>
  2. #include <math.h>
  3.  
  4. #include <crtdbg.h>
  5.  
  6. #include <vd2/system/vdtypes.h>
  7. #include <vd2/Meia/MPEGIDCT.h>
  8. #include "tables.h"
  9.  
  10. //#define VERIFY_PRUNING
  11.  
  12. using namespace nsVDMPEGTables;
  13.  
  14. namespace nsVDMPEGIDCTScalar {
  15.  
  16.     #define PRESCALE_CHEAT_BITS (8)
  17.     #define PRESCALE_BITS (8)
  18.     #define SCALE_BITS (14)
  19.  
  20.     #define FIXED_SCALE(x) ((int)(((x)<0 ? (x)*(double)(1<<SCALE_BITS)-0.5 : (x)*(double)(1<<SCALE_BITS) + 0.5) ))
  21.  
  22.     static const double sqrt2 = 1.4142135623730950488016887242097;
  23.     static const double invsqrt2 = 0.70710678118654752440084436210485;
  24.  
  25.     // lambda(x) = cos(pi*k/16)
  26.  
  27.     static const double lambda[8]={
  28.         1,
  29.         0.98078528040323043,
  30.         0.92387953251128674,
  31.         0.83146961230254524,
  32.         0.70710678118654757,
  33.         0.55557023301960229,
  34.         0.38268343236508984,
  35.         0.19509032201612833,
  36.     };
  37.  
  38.  
  39.     // these are not the same but are very similar in their use
  40.  
  41.     static const int inv_a1 = 21407;    //FIXED_SCALE(lambda[6] + lambda[2]);
  42.     static const int inv_a2 = -15137;    //FIXED_SCALE(-lambda[2]);
  43.     static const int inv_a3 = -8868;    //FIXED_SCALE(lambda[6] - lambda[2]) - 1;
  44.     static const int inv_b1 = 30274;    //FIXED_SCALE((lambda[6] + lambda[2]) * sqrt2);
  45.     static const int inv_b2 = -21407;    //FIXED_SCALE(-lambda[2] * sqrt2);
  46.     static const int inv_b3 = -12541;    //FIXED_SCALE((lambda[6] - lambda[2]) * sqrt2) - 1;
  47.  
  48.     // these are inverses
  49.  
  50.     static const int inv_a0            = 11585;    //FIXED_SCALE(invsqrt2);
  51.     static const int inv_c0            = 11585;    //FIXED_SCALE(invsqrt2);
  52.     static const int inv_rot1        = 21407;    //FIXED_SCALE(lambda[6] + lambda[2]);
  53.     static const int inv_rot2        = -8867;    //FIXED_SCALE(lambda[6] - lambda[2]);
  54.     static const int inv_rot3        = 15137;    //FIXED_SCALE(lambda[2]);
  55.     static const int inv_rot1sq2    = 30274;    //FIXED_SCALE((lambda[6] + lambda[2]) * sqrt2);
  56.     static const int inv_rot2sq2    = -12540;    //FIXED_SCALE((lambda[6] - lambda[2]) * sqrt2);
  57.     static const int inv_rot3sq2    = 21407;    //FIXED_SCALE(lambda[2] * sqrt2);
  58.  
  59.     #define FIXED_PRESCALE(x) ((int)(((x)<0 ? (x)*(double)(1<<(PRESCALE_BITS+PRESCALE_CHEAT_BITS))-0.5 : (x)*(double)(1<<(PRESCALE_BITS + PRESCALE_CHEAT_BITS)) + 0.5) ))
  60.  
  61.     static const double prescale_values_1D[8]={
  62.         lambda[0] * 0.5,
  63.         lambda[4] * invsqrt2,
  64.         lambda[6] * invsqrt2,
  65.         lambda[2] * invsqrt2,
  66.         lambda[1] * invsqrt2,
  67.         lambda[5] * invsqrt2,
  68.         lambda[7] * invsqrt2,
  69.         lambda[3] * invsqrt2,
  70.     };
  71.  
  72.     #define ONE(i,j) FIXED_PRESCALE(prescale_values_1D[i] * prescale_values_1D[j])
  73.     #define ROW(j) ONE(0,j),ONE(1,j),ONE(2,j),ONE(3,j),ONE(4,j),ONE(5,j),ONE(6,j),ONE(7,j)
  74.  
  75.     static const int prescale_values_2D[64]={
  76.         ROW(0),
  77.         ROW(1),
  78.         ROW(2),
  79.         ROW(3),
  80.         ROW(4),
  81.         ROW(5),
  82.         ROW(6),
  83.         ROW(7),
  84.     };
  85.  
  86.     #undef ROW
  87.     #undef ONE
  88.  
  89.     #define ROW(x) (x*8)+0,(x*8)+5,(x*8)+2,(x*8)+4,(x*8)+1,(x*8)+6,(x*8)+3,(x*8)+7
  90.  
  91.     static const int reorder[64]={
  92.         ROW(0),ROW(5),ROW(2),ROW(4),ROW(1),ROW(6),ROW(3),ROW(7)
  93.     };
  94.  
  95.     #undef ROW
  96.  
  97.  
  98. #if 1
  99.     #include "idct_scalar_asm.inl"
  100. #else
  101.     static void scalar_idct_feig_winograd_8x8(int *d) {
  102.         int i;
  103.  
  104.         d[0] += 1<<(PRESCALE_BITS);
  105.         
  106.         //---------- full 8x8 IDCT [462a54m22s]
  107.  
  108.         // apply horizontal R2 (R18) transform [64a]
  109.         
  110.         for(i=0; i<8*8; i+=8) {
  111.             int x2, x3, x4, x5, x6, x7;
  112.             int y4, y5, y6, y7;
  113.  
  114.             x2 = d[i+2];
  115.             x3 = d[i+3];
  116.  
  117.             d[i+2] = x2-x3;
  118.             d[i+3] = x2+x3;
  119.  
  120.             x4 = d[i+4];
  121.             x5 = d[i+5];
  122.             x6 = d[i+6];
  123.             x7 = d[i+7];
  124.  
  125.             y4 = x4-x6;
  126.             y5 = x7+x5;
  127.             y6 = x4+x6;
  128.             y7 = x7-x5;
  129.                     
  130.             d[i+4] = y5+y4;
  131.             d[i+5] = y5-y4;
  132.             d[i+6] = y6;
  133.             d[i+7] = y7;
  134.         }
  135.  
  136.         // apply vertical R2 transform [64a]
  137.  
  138.         for(i=0; i<8; ++i) {
  139.             int x2, x3, x4, x5, x6, x7;
  140.             int y4, y5, y6, y7;
  141.  
  142.             x2 = d[i+16];
  143.             x3 = d[i+24];
  144.  
  145.             d[i+16] = x2-x3;
  146.             d[i+24] = x2+x3;
  147.  
  148.             x4 = d[i+32];
  149.             x5 = d[i+40];
  150.             x6 = d[i+48];
  151.             x7 = d[i+56];
  152.  
  153.             y4 = x4-x6;
  154.             y5 = x7+x5;
  155.             y6 = x4+x6;
  156.             y7 = x7-x5;
  157.                     
  158.             d[i+32] = y5+y4;
  159.             d[i+40] = y5-y4;
  160.             d[i+48] = y6;
  161.             d[i+56] = y7;
  162.         }
  163.  
  164.         // apply M1/M2 and R1 to first 6 rows
  165.  
  166.         for(i=0; i<6*8; i+=8) {
  167.             int x0, x1, x2, x3, x4, x5, x6, x7;
  168.             int y0, y1, y2, y3, y4, y5, y6, y7;
  169.             int z0, z1, z2, z3, z4, z5, z6, z7;
  170.  
  171.             x0 = d[i+0];
  172.             x1 = d[i+1];
  173.             x2 = d[i+2];
  174.             x3 = d[i+3];
  175.             x4 = d[i+4];
  176.             x5 = d[i+5];
  177.             x6 = d[i+6];
  178.             x7 = d[i+7];
  179.  
  180.             // M1 or M2 [18a34m20s]
  181.  
  182.             if (i==3*8 || i==4*8) {    // M2
  183.                 x0 *= inv_a0;
  184.                 x1 *= inv_a0;
  185.                 x2 *= inv_a0;
  186.                 x3 <<= SCALE_BITS;
  187.                 x4 <<= SCALE_BITS;
  188.                 x5 *= inv_a0;
  189.                 
  190.                 int tmp = (x6+x7) * inv_b2;
  191.  
  192.                 x6 = x6 * inv_b3 - tmp;
  193.                 x7 = x7 * inv_b1 + tmp;
  194.             } else { // M1
  195.  
  196.                 x0 <<= SCALE_BITS - 1;
  197.                 x1 <<= SCALE_BITS - 1;
  198.                 x2 <<= SCALE_BITS - 1;
  199.                 x3 *= inv_a0;
  200.                 x4 *= inv_a0;
  201.                 x5 <<= SCALE_BITS - 1;
  202.  
  203.                 int tmp = (x6+x7) * inv_a2;
  204.  
  205.                 x6 = x6 * inv_a3 - tmp;
  206.                 x7 = x7 * inv_a1 + tmp;
  207.             }
  208.  
  209.             d[i+0] = x0;
  210.             d[i+1] = x1;
  211.             d[i+2] = x2;
  212.             d[i+3] = x3;
  213.             d[i+4] = x4;
  214.             d[i+5] = x5;
  215.             d[i+6] = x6;
  216.             d[i+7] = x7;
  217.         }
  218.  
  219.         // Apply M3 and R2 to last two rows together
  220.  
  221.         {
  222.             int x60, x61, x62, x63, x64, x65, x66, x67;
  223.             int x70, x71, x72, x73, x74, x75, x76, x77;
  224.             int y60, y61, y62, y63, y64, y65, y66, y67;
  225.             int y70, y71, y72, y73, y74, y75, y76, y77;
  226.             int tmp;
  227.  
  228.             x60 = d[48];
  229.             x61 = d[49];
  230.             x62 = d[50];
  231.             x63 = d[51];
  232.             x64 = d[52];
  233.             x65 = d[53];
  234.             x66 = d[54];
  235.             x67 = d[55];
  236.  
  237.             x70 = d[56];
  238.             x71 = d[57];
  239.             x72 = d[58];
  240.             x73 = d[59];
  241.             x74 = d[60];
  242.             x75 = d[61];
  243.             x76 = d[62];
  244.             x77 = d[63];
  245.  
  246.             // apply inverse rotator (1/G2) [18a18m]
  247.             //
  248.             // x0 =  y0*g6 - y1*g2
  249.             // x1 =  y0*g2 + y1*g6
  250.             //
  251.             // let: t = g2*(y0+y1)
  252.             //
  253.             // x0 =  y0*(g6+g2) - t
  254.             // x1 =  y1*(g6-g2) + t
  255.  
  256.             tmp = inv_rot3 * (x60 + x70);
  257.             y60 = x60*inv_rot2 + tmp;
  258.             y70 = x70*inv_rot1 - tmp;
  259.             
  260.             tmp = inv_rot3 * (x61 + x71);
  261.             y61 = x61*inv_rot2 + tmp;
  262.             y71 = x71*inv_rot1 - tmp;
  263.             
  264.             tmp = inv_rot3 * (x62 + x72);
  265.             y62 = x62*inv_rot2 + tmp;
  266.             y72 = x72*inv_rot1 - tmp;
  267.             
  268.             tmp = inv_rot3sq2 * (x63 + x73);
  269.             y63 = x63*inv_rot2sq2 + tmp;
  270.             y73 = x73*inv_rot1sq2 - tmp;
  271.             
  272.             tmp = inv_rot3sq2 * (x64 + x74);
  273.             y64 = x64*inv_rot2sq2 + tmp;
  274.             y74 = x74*inv_rot1sq2 - tmp;
  275.             
  276.             tmp = inv_rot3 * (x65 + x75);
  277.             y65 = x65*inv_rot2 + tmp;
  278.             y75 = x75*inv_rot1 - tmp;
  279.  
  280.             // last two rows (Q3) are a little annoying [10a2m2s].
  281.             //
  282.             // order:    66
  283.             //            76
  284.             //            67
  285.             //            77
  286.  
  287.             y77 = x77-x66;
  288.             y67 = x67+x76;
  289.             y76 = x67-x76;
  290.             y66 = x77+x66;
  291.  
  292.             x77 = (y77+y67) * inv_c0;
  293.             x67 = (y77-y67) * inv_c0;
  294.             x76 = y76 << SCALE_BITS;
  295.             x66 = y66 << SCALE_BITS;
  296.  
  297.             y77 = x66-x77;
  298.             y67 = x67+x76;
  299.             y76 = x67-x76;
  300.             y66 = x66+x77;
  301.  
  302.             d[48] = y60;
  303.             d[49] = y61;
  304.             d[50] = y62;
  305.             d[51] = y63;
  306.             d[52] = y64;
  307.             d[53] = y65;
  308.             d[54] = y66;
  309.             d[55] = y67;
  310.  
  311.             d[56] = y70;
  312.             d[57] = y71;
  313.             d[58] = y72;
  314.             d[59] = y73;
  315.             d[60] = y74;
  316.             d[61] = y75;
  317.             d[62] = y76;
  318.             d[63] = y77;
  319.         }
  320.  
  321.         // Apply horizontal R1 (B1t * B2 * B3) to last two rows [144a]
  322.  
  323.         for(i=0*8; i<8*8; i+=8) {
  324.             int x0, x1, x2, x3, x4, x5, x6, x7;
  325.             int y0, y1, y2, y3, y4, y5, y6, y7;
  326.             int z0, z1, z2, z3, z4, z5, z6, z7;
  327.  
  328.             x0 = d[i+0];
  329.             x1 = d[i+1];
  330.             x2 = d[i+2];
  331.             x3 = d[i+3];
  332.             x4 = d[i+4];
  333.             x5 = d[i+5];
  334.             x6 = d[i+6];
  335.             x7 = d[i+7];
  336.             
  337.             y0 = x0+x1;
  338.             y1 = x0-x1;
  339.             y2 = x2;
  340.             y3 = x2+x3;
  341.  
  342.             y5 = x5;
  343.             y7 = x5-x7;
  344.             y4 = y7-x4;
  345.             y6 = x6+y4;
  346.  
  347.             z0 = y0+y3;
  348.             z1 = y1+y2;
  349.             z2 = y1-y2;
  350.             z3 = y0-y3;
  351.             z4 = y4;
  352.             z5 = y5;
  353.             z6 = y6;
  354.             z7 = y7;
  355.  
  356.             d[i+0] = z0+z7;
  357.             d[i+1] = z1-z6;
  358.             d[i+2] = z2+z5;
  359.             d[i+3] = z3+z4;
  360.             d[i+4] = z3-z4;
  361.             d[i+5] = z2-z5;
  362.             d[i+6] = z1+z6;
  363.             d[i+7] = z0-z7;
  364.         }
  365.  
  366.         // Apply vertical R1 [144a].
  367.  
  368.         for(i=0; i<8; i++) {
  369.             int x0, x1, x2, x3, x4, x5, x6, x7;
  370.             int y0, y1, y2, y3, y4, y5, y6, y7;
  371.             int z0, z1, z2, z3, z4, z5, z6, z7;
  372.  
  373.             x0 = d[i+0];
  374.             x1 = d[i+8];
  375.             x2 = d[i+16];
  376.             x3 = d[i+24];
  377.             x4 = d[i+32];
  378.             x5 = d[i+40];
  379.             x6 = d[i+48];
  380.             x7 = d[i+56];
  381.             
  382.             y0 = x0+x1;
  383.             y1 = x0-x1;
  384.             y2 = x2;
  385.             y3 = x2+x3;
  386.  
  387.             y5 = x5;
  388.             y7 = x5-x7;
  389.             y4 = y7-x4;
  390.             y6 = y4+x6;
  391.  
  392.             z0 = y0+y3;
  393.             z1 = y1+y2;
  394.             z2 = y1-y2;
  395.             z3 = y0-y3;
  396.             z4 = y4;
  397.             z5 = y5;
  398.             z6 = y6;
  399.             z7 = y7;
  400.  
  401.             d[i+ 0] = (z0+z7)>>(PRESCALE_BITS + SCALE_BITS);
  402.             d[i+ 8] = (z1-z6)>>(PRESCALE_BITS + SCALE_BITS);
  403.             d[i+16] = (z2+z5)>>(PRESCALE_BITS + SCALE_BITS);
  404.             d[i+24] = (z3+z4)>>(PRESCALE_BITS + SCALE_BITS);
  405.             d[i+32] = (z3-z4)>>(PRESCALE_BITS + SCALE_BITS);
  406.             d[i+40] = (z2-z5)>>(PRESCALE_BITS + SCALE_BITS);
  407.             d[i+48] = (z1+z6)>>(PRESCALE_BITS + SCALE_BITS);
  408.             d[i+56] = (z0-z7)>>(PRESCALE_BITS + SCALE_BITS);
  409.         }
  410.     }
  411.  
  412.     static void scalar_idct_feig_winograd_4x4(int *d) {
  413.         int i;
  414.  
  415.         //    reordering performed by zigzag matrix:
  416.         //
  417.         //    normal indices    0 1 2 3 4 5 6 7
  418.         //    dest indices    0 5 2 4 1 6 3 7
  419.         //
  420.         //    Thus if last_pos < 10, we can consider columns/rows 1, 3, 6, and 7
  421.         //    to be zero.
  422.  
  423.         d[0] += 1<<(PRESCALE_BITS);
  424.         
  425.         //---------- VR-pruned 4x4 IDCT [309a44m22s] [VR-PRUNE:156a10m7s]
  426.  
  427.         // move row 0 into row 1
  428.  
  429.         d[8] = d[0];
  430.         d[10] = d[2];
  431.         d[12] = d[4];
  432.         d[13] = d[5];
  433.  
  434.         // apply horizontal R2 (R18) transform [10a] [VR-PRUNE: 54a]
  435.         
  436.         for(i=1*8; i<6*8; i+=8) {
  437.             int x2, x4, x5, x6, x7;
  438.             int y4, y5, y6, y7;
  439.  
  440.             x4 = d[i+4];
  441.             x5 = d[i+5];
  442.             x6 = d[i+6];
  443.             x7 = d[i+7];
  444.  
  445.             y4 = x4;
  446.             y5 = x5;
  447.             y6 = x4;
  448.             y7 = x5;
  449.                     
  450.             d[i+4] = y5+y4;
  451.             d[i+5] = y5-y4;
  452.             d[i+6] = y6;
  453.             d[i+7] = y7;
  454.         }
  455.  
  456.         // apply vertical R2 transform [16a] [VR-PRUNE: 48a]
  457.  
  458.         for(i=0; i<8; ++i) {
  459.             int x2, x4, x5, x6, x7;
  460.             int y4, y5, y6, y7;
  461.  
  462.             x2 = d[i+16];
  463.  
  464.             d[i+16] = x2;
  465.             d[i+24] = x2;
  466.  
  467.             x4 = d[i+32];
  468.             x5 = d[i+40];
  469.             x6 = d[i+48];
  470.             x7 = d[i+56];
  471.  
  472.             y4 = x4;
  473.             y5 = x5;
  474.             y6 = x4;
  475.             y7 = x5;
  476.                     
  477.             d[i+32] = y5+y4;
  478.             d[i+40] = y5-y4;
  479.             d[i+48] = y6;
  480.             d[i+56] = y7;
  481.         }
  482.  
  483.         // apply M1/M2 to first 6 rows
  484.  
  485.         for(i=1*8; i<6*8; i+=8) {
  486.             int x0, x2, x3, x4, x5, x6, x7;
  487.  
  488.             x0 = d[i+0];
  489.             x2 = d[i+2];
  490.             x4 = d[i+4];
  491.             x5 = d[i+5];
  492.             x6 = d[i+6];
  493.             x7 = d[i+7];
  494.  
  495.             // M1 or M2 [18a27m20s] [VR-PRUNE: 3a7m7s]
  496.  
  497.             if (i==3*8 || i==4*8) {    // M2
  498.                 x0 *= inv_a0;
  499.                 x3 = x2 << SCALE_BITS;
  500.                 x2 *= inv_a0;
  501.                 x4 <<= SCALE_BITS;
  502.                 x5 *= inv_a0;
  503.                 
  504.                 int tmp = (x6-x7) * inv_b2;
  505.  
  506.                 x6 = x6 * inv_b3 - tmp;
  507.                 x7 = x7 * -inv_b1 + tmp;
  508.             } else { // M1
  509.  
  510.                 x0 <<= SCALE_BITS - 1;
  511.                 x3 = x2 * inv_a0;
  512.                 x2 <<= SCALE_BITS - 1;
  513.                 x4 *= inv_a0;
  514.                 x5 <<= SCALE_BITS - 1;
  515.  
  516.                 int tmp = (x6-x7) * inv_a2;
  517.  
  518.                 x6 = x6 * inv_a3 - tmp;
  519.                 x7 = x7 * -inv_a1 + tmp;
  520.             }
  521.  
  522.             d[i+0] = x0;
  523.             d[i+2] = x2;
  524.             d[i+3] = x3;
  525.             d[i+4] = x4;
  526.             d[i+5] = x5;
  527.             d[i+6] = x6;
  528.             d[i+7] = x7;
  529.         }
  530.  
  531.         // Apply M3 and R2 to last two rows together
  532.  
  533.         {
  534.             int x60, x61, x62, x64, x65, x66, x67;
  535.             int x70, x71, x72, x74, x75, x76, x77;
  536.             int y60, y61, y62, y63, y64, y65, y66, y67;
  537.             int y70, y71, y72, y73, y74, y75, y76, y77;
  538.             int tmp;
  539.  
  540.             x60 = d[48];
  541.             x61 = d[49];
  542.             x62 = d[50];
  543.             x64 = d[52];
  544.             x65 = d[53];
  545.             x66 = d[54];
  546.             x67 = d[55];
  547.  
  548.             x70 = d[56];
  549.             x71 = d[57];
  550.             x72 = d[58];
  551.             x74 = d[60];
  552.             x75 = d[61];
  553.             x76 = d[62];
  554.             x77 = d[63];
  555.  
  556.             // apply inverse rotator (1/G2) [15a15m] [VR-PRUNE: 3a3m]
  557.             //
  558.             // x0 =  y0*g6 - y1*g2
  559.             // x1 =  y0*g2 + y1*g6
  560.             //
  561.             // let: t = g2*(y0+y1)
  562.             //
  563.             // x0 =  y0*(g6+g2) - t
  564.             // x1 =  y1*(g6-g2) + t
  565.  
  566.             tmp = inv_rot3 * (x60 - x70);
  567.             y60 = x60*inv_rot2 + tmp;
  568.             y70 = x70*-inv_rot1 - tmp;
  569.             
  570.             tmp = inv_rot3 * (x62 - x72);
  571.             y62 = x62*inv_rot2 + tmp;
  572.             y72 = x72*-inv_rot1 - tmp;
  573.             
  574.             tmp = inv_rot3sq2 * (x62 - x72);
  575.             y63 = x62*inv_rot2sq2 + tmp;
  576.             y73 = x72*-inv_rot1sq2 - tmp;
  577.             
  578.             tmp = inv_rot3sq2 * (x64 - x74);
  579.             y64 = x64*inv_rot2sq2 + tmp;
  580.             y74 = x74*-inv_rot1sq2 - tmp;
  581.             
  582.             tmp = inv_rot3 * (x65 - x75);
  583.             y65 = x65*inv_rot2 + tmp;
  584.             y75 = x75*-inv_rot1 - tmp;
  585.  
  586.             // last two rows (Q3) are a little annoying [10a2m2s].
  587.             //
  588.             // order:    66
  589.             //            76
  590.             //            67
  591.             //            77
  592.  
  593.             y77 = x77-x66;
  594.             y67 = x67+x76;
  595.             y76 = x67-x76;
  596.             y66 = x77+x66;
  597.  
  598.             x77 = (y77-y67) * inv_c0;
  599.             x67 = (y77+y67) * inv_c0;
  600.             x76 = y76 << SCALE_BITS;
  601.             x66 = y66 << SCALE_BITS;
  602.  
  603.             y77 = x66-x77;
  604.             y67 = x67-x76;
  605.             y76 = x67+x76;
  606.             y66 = x66+x77;
  607.  
  608.             d[48] = y60;
  609.             d[50] = y62;
  610.             d[51] = y63;
  611.             d[52] = y64;
  612.             d[53] = y65;
  613.             d[54] = y66;
  614.             d[55] = y67;
  615.  
  616.             d[56] = y70;
  617.             d[58] = y72;
  618.             d[59] = y73;
  619.             d[60] = y74;
  620.             d[61] = y75;
  621.             d[62] = y76;
  622.             d[63] = y77;
  623.         }
  624.  
  625.         // Apply horizontal R1 (B1t * B2 * B3) to last two rows [112a] [VR-PRUNE: 32a]
  626.  
  627.         for(i=1*8; i<8*8; i+=8) {
  628.             int x0, x2, x3, x4, x5, x6, x7;
  629.             int y0, y2, y3, y4, y5, y6, y7;
  630.             int z0, z1, z2, z3, z4, z5, z6, z7;
  631.  
  632.             x0 = d[i+0];
  633.             x2 = d[i+2];
  634.             x3 = d[i+3];
  635.             x4 = d[i+4];
  636.             x5 = d[i+5];
  637.             x6 = d[i+6];
  638.             x7 = d[i+7];
  639.             
  640.             y0 = x0;
  641.             y2 = x2;
  642.             y3 = x2+x3;
  643.  
  644.             y5 = x5;
  645.             y7 = x5-x7;
  646.             y4 = y7-x4;
  647.             y6 = x6+y4;
  648.  
  649.             z0 = y0+y3;
  650.             z1 = y0+y2;
  651.             z2 = y0-y2;
  652.             z3 = y0-y3;
  653.             z4 = y4;
  654.             z5 = y5;
  655.             z6 = y6;
  656.             z7 = y7;
  657.  
  658.             d[i+0] = z0+z7;
  659.             d[i+1] = z1-z6;
  660.             d[i+2] = z2+z5;
  661.             d[i+3] = z3+z4;
  662.             d[i+4] = z3-z4;
  663.             d[i+5] = z2-z5;
  664.             d[i+6] = z1+z6;
  665.             d[i+7] = z0-z7;
  666.         }
  667.  
  668.         // Apply vertical R1 [128a] [VR-PRUNE: 16a]
  669.  
  670.         for(i=0; i<8; i++) {
  671.             int x0, x2, x3, x4, x5, x6, x7;
  672.             int y0, y2, y3, y4, y5, y6, y7;
  673.             int z0, z1, z2, z3, z4, z5, z6, z7;
  674.  
  675.             x0 = d[i+8];
  676.             x2 = d[i+16];
  677.             x3 = d[i+24];
  678.             x4 = d[i+32];
  679.             x5 = d[i+40];
  680.             x6 = d[i+48];
  681.             x7 = d[i+56];
  682.             
  683.             y0 = x0;
  684.             y2 = x2;
  685.             y3 = x2+x3;
  686.  
  687.             y5 = x5;
  688.             y7 = x5-x7;
  689.             y4 = y7-x4;
  690.             y6 = y4+x6;
  691.  
  692.             z0 = y0+y3;
  693.             z1 = y0+y2;
  694.             z2 = y0-y2;
  695.             z3 = y0-y3;
  696.             z4 = y4;
  697.             z5 = y5;
  698.             z6 = y6;
  699.             z7 = y7;
  700.  
  701.             d[i+ 0] = (z0+z7)>>(PRESCALE_BITS + SCALE_BITS);
  702.             d[i+ 8] = (z1-z6)>>(PRESCALE_BITS + SCALE_BITS);
  703.             d[i+16] = (z2+z5)>>(PRESCALE_BITS + SCALE_BITS);
  704.             d[i+24] = (z3+z4)>>(PRESCALE_BITS + SCALE_BITS);
  705.             d[i+32] = (z3-z4)>>(PRESCALE_BITS + SCALE_BITS);
  706.             d[i+40] = (z2-z5)>>(PRESCALE_BITS + SCALE_BITS);
  707.             d[i+48] = (z1+z6)>>(PRESCALE_BITS + SCALE_BITS);
  708.             d[i+56] = (z0-z7)>>(PRESCALE_BITS + SCALE_BITS);
  709.         }
  710.     }
  711. #endif
  712.  
  713.     static void scalar_idct_intra(unsigned char *dst, int pitch, int *tmp, int last_pos) {
  714.         if (!last_pos) {
  715.             const unsigned char v = clip_table[288 + ((tmp[0] + (1 << PRESCALE_BITS)) >> (PRESCALE_BITS + 1))];
  716.             for(int j=0; j<8; ++j) {
  717.                 for(int i=0; i<8; ++i)
  718.                     dst[i] = v;
  719.  
  720.                 dst += pitch;
  721.             }
  722.         } else {
  723.             if (last_pos < 10) {
  724.                 #ifdef VERIFY_PRUNING
  725.                     int chk[64];
  726.                     memcpy(chk, tmp, sizeof(int)*64);
  727.                     scalar_idct_feig_winograd_8x8(chk);
  728.                 #endif
  729.  
  730.                 scalar_idct_feig_winograd_4x4(tmp);
  731.  
  732.                 #ifdef VERIFY_PRUNING
  733.                     VDASSERT(!memcmp(chk, tmp, 64*sizeof(int)));
  734.                 #endif
  735.             } else
  736.                 scalar_idct_feig_winograd_8x8(tmp);
  737.  
  738.             for(int j=0; j<8; ++j) {
  739.                 for(int i=0; i<8; ++i) {
  740.                     int v = tmp[j*8+i];
  741.  
  742.                     dst[i] = clip_table[v + 288];
  743.                 }
  744.                 dst += pitch;
  745.             }
  746.         }
  747.     }
  748.  
  749.     static void scalar_idct_nonintra(unsigned char *dst, int pitch, int *tmp, int last_pos) {
  750.         if (last_pos == 0) {
  751.             const unsigned char *p = &clip_table[288 + ((tmp[0] + (1 << PRESCALE_BITS)) >> (PRESCALE_BITS + 1))];
  752.             for(int j=0; j<8; ++j) {
  753.                 for(int i=0; i<8; ++i)
  754.                     dst[i] = p[dst[i]];
  755.  
  756.                 dst += pitch;
  757.             }
  758.         } else {
  759.             if (last_pos < 10) {
  760.                 #ifdef VERIFY_PRUNING
  761.                     int chk[64];
  762.                     memcpy(chk, tmp, sizeof(int)*64);
  763.                     scalar_idct_feig_winograd_8x8(chk);
  764.                 #endif
  765.  
  766.                 scalar_idct_feig_winograd_4x4(tmp);
  767.  
  768.                 #ifdef VERIFY_PRUNING
  769.                     VDASSERT(!memcmp(chk, tmp, 64*sizeof(int)));
  770.                 #endif
  771.             } else
  772.                 scalar_idct_feig_winograd_8x8(tmp);
  773.  
  774.             for(int j=0; j<8; ++j) {
  775.                 for(int i=0; i<8; ++i) {
  776.                     int v = tmp[j*8+i] + dst[i];
  777.  
  778.                     dst[i] = clip_table[v+288];
  779.                 }
  780.                 dst += pitch;
  781.             }
  782.         }
  783.     }
  784.  
  785.     static void scalar_idct_test(int *tmp, int last_pos) {
  786.         scalar_idct_feig_winograd_8x8(tmp);
  787.     }
  788.     ///////////////////////////////////////////////////////////////////////
  789.  
  790.     static const int zigzag_std[64]={
  791.          0,  1,  8, 16,  9,  2,  3, 10,
  792.         17, 24, 32, 25, 18, 11,  4,  5,
  793.         12, 19, 26, 33, 40, 48, 41, 34,
  794.         27, 20, 13,  6,  7, 14, 21, 28,
  795.         35, 42, 49, 56, 57, 50, 43, 36,
  796.         29, 22, 15, 23, 30, 37, 44, 51,
  797.         58, 59, 52, 45, 38, 31, 39, 46,
  798.         53, 60, 61, 54, 47, 55, 62, 63,
  799.     };
  800.  
  801.     #define ROW(x) reorder[zigzag_std[(x*8)+0]],reorder[zigzag_std[(x*8)+1]],reorder[zigzag_std[(x*8)+2]],reorder[zigzag_std[(x*8)+3]],reorder[zigzag_std[(x*8)+4]],reorder[zigzag_std[(x*8)+5]],reorder[zigzag_std[(x*8)+6]],reorder[zigzag_std[(x*8)+7]]
  802.  
  803.     static const int zigzag_reordered[64]={
  804.         ROW(0),ROW(1),ROW(2),ROW(3),ROW(4),ROW(5),ROW(6),ROW(7)
  805.     };
  806.  
  807. };
  808.  
  809. const struct VDMPEGIDCTSet g_VDMPEGIDCT_scalar = {
  810.     (tVDMPEGIDCT)nsVDMPEGIDCTScalar::scalar_idct_intra,
  811.     (tVDMPEGIDCT)nsVDMPEGIDCTScalar::scalar_idct_nonintra,
  812.     (tVDMPEGIDCTTest)nsVDMPEGIDCTScalar::scalar_idct_test,
  813.     nsVDMPEGIDCTScalar::prescale_values_2D,
  814.     nsVDMPEGIDCTScalar::zigzag_reordered,
  815. };
  816.