home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / jpeg / jidctfst.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  51.2 KB  |  1,652 lines

  1. /*
  2.  * jidctfst.c
  3.  *
  4.  * Copyright (C) 1994-1996, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains a fast, not so accurate integer implementation of the
  9.  * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
  10.  * must also perform dequantization of the input coefficients.
  11.  *
  12.  * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
  13.  * on each row (or vice versa, but it's more convenient to emit a row at
  14.  * a time).  Direct algorithms are also available, but they are much more
  15.  * complex and seem not to be any faster when reduced to code.
  16.  *
  17.  * This implementation is based on Arai, Agui, and Nakajima's algorithm for
  18.  * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
  19.  * Japanese, but the algorithm is described in the Pennebaker & Mitchell
  20.  * JPEG textbook (see REFERENCES section in file README).  The following code
  21.  * is based directly on figure 4-8 in P&M.
  22.  * While an 8-point DCT cannot be done in less than 11 multiplies, it is
  23.  * possible to arrange the computation so that many of the multiplies are
  24.  * simple scalings of the final outputs.  These multiplies can then be
  25.  * folded into the multiplications or divisions by the JPEG quantization
  26.  * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
  27.  * to be done in the DCT itself.
  28.  * The primary disadvantage of this method is that with fixed-point math,
  29.  * accuracy is lost due to imprecise representation of the scaled
  30.  * quantization values.  The smaller the quantization table entry, the less
  31.  * precise the scaled value, so this implementation does worse with high-
  32.  * quality-setting files than with low-quality ones.
  33.  */
  34.  
  35.  
  36. #define JPEG_INTERNALS
  37. #include "jinclude.h"
  38. #include "jpeglib.h"
  39. #include "jdct.h"        /* Private declarations for DCT subsystem */
  40. #include "xp_core.h"
  41.  
  42. #ifdef DCT_IFAST_SUPPORTED
  43.  
  44.  
  45. /*
  46.  * This module is specialized to the case DCTSIZE = 8.
  47.  */
  48.  
  49. #if DCTSIZE != 8
  50.   Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  51. #endif
  52.  
  53.  
  54. /* Scaling decisions are generally the same as in the LL&M algorithm;
  55.  * see jidctint.c for more details.  However, we choose to descale
  56.  * (right shift) multiplication products as soon as they are formed,
  57.  * rather than carrying additional fractional bits into subsequent additions.
  58.  * This compromises accuracy slightly, but it lets us save a few shifts.
  59.  * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
  60.  * everywhere except in the multiplications proper; this saves a good deal
  61.  * of work on 16-bit-int machines.
  62.  *
  63.  * The dequantized coefficients are not integers because the AA&N scaling
  64.  * factors have been incorporated.  We represent them scaled up by PASS1_BITS,
  65.  * so that the first and second IDCT rounds have the same input scaling.
  66.  * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
  67.  * avoid a descaling shift; this compromises accuracy rather drastically
  68.  * for small quantization table entries, but it saves a lot of shifts.
  69.  * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
  70.  * so we use a much larger scaling factor to preserve accuracy.
  71.  *
  72.  * A final compromise is to represent the multiplicative constants to only
  73.  * 8 fractional bits, rather than 13.  This saves some shifting work on some
  74.  * machines, and may also reduce the cost of multiplication (since there
  75.  * are fewer one-bits in the constants).
  76.  */
  77.  
  78. #if BITS_IN_JSAMPLE == 8
  79. #define CONST_BITS  8
  80. #define PASS1_BITS  2
  81. #else
  82. #define CONST_BITS  8
  83. #define PASS1_BITS  1        /* lose a little precision to avoid overflow */
  84. #endif
  85.  
  86. /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
  87.  * causing a lot of useless floating-point operations at run time.
  88.  * To get around this we use the following pre-calculated constants.
  89.  * If you change CONST_BITS you may want to add appropriate values.
  90.  * (With a reasonable C compiler, you can just rely on the FIX() macro...)
  91.  */
  92.  
  93. #if CONST_BITS == 8
  94. #define FIX_1_082392200  ((INT32)  277)        /* FIX(1.082392200) */
  95. #define FIX_1_414213562  ((INT32)  362)        /* FIX(1.414213562) */
  96. #define FIX_1_847759065  ((INT32)  473)        /* FIX(1.847759065) */
  97. #define FIX_2_613125930  ((INT32)  669)        /* FIX(2.613125930) */
  98. #else
  99. #define FIX_1_082392200  FIX(1.082392200)
  100. #define FIX_1_414213562  FIX(1.414213562)
  101. #define FIX_1_847759065  FIX(1.847759065)
  102. #define FIX_2_613125930  FIX(2.613125930)
  103. #endif
  104.  
  105.  
  106. /* We can gain a little more speed, with a further compromise in accuracy,
  107.  * by omitting the addition in a descaling shift.  This yields an incorrectly
  108.  * rounded result half the time...
  109.  */
  110.  
  111. #ifndef USE_ACCURATE_ROUNDING
  112. #undef DESCALE
  113. #define DESCALE(x,n)  RIGHT_SHIFT(x, n)
  114. #endif
  115.  
  116.  
  117. /* Multiply a DCTELEM variable by an INT32 constant, and immediately
  118.  * descale to yield a DCTELEM result.
  119.  */
  120.  
  121. #define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
  122.  
  123.  
  124. /* Dequantize a coefficient by multiplying it by the multiplier-table
  125.  * entry; produce a DCTELEM result.  For 8-bit data a 16x16->16
  126.  * multiplication will do.  For 12-bit data, the multiplier table is
  127.  * declared INT32, so a 32-bit multiply will be used.
  128.  */
  129.  
  130. #if BITS_IN_JSAMPLE == 8
  131. #define DEQUANTIZE(coef,quantval)  (((IFAST_MULT_TYPE) (coef)) * (quantval))
  132. #else
  133. #define DEQUANTIZE(coef,quantval)  \
  134.     DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
  135. #endif
  136.  
  137.  
  138. /* Like DESCALE, but applies to a DCTELEM and produces an int.
  139.  * We assume that int right shift is unsigned if INT32 right shift is.
  140.  */
  141.  
  142. #ifdef RIGHT_SHIFT_IS_UNSIGNED
  143. #define ISHIFT_TEMPS    DCTELEM ishift_temp;
  144. #if BITS_IN_JSAMPLE == 8
  145. #define DCTELEMBITS  16        /* DCTELEM may be 16 or 32 bits */
  146. #else
  147. #define DCTELEMBITS  32        /* DCTELEM must be 32 bits */
  148. #endif
  149. #define IRIGHT_SHIFT(x,shft)  \
  150.     ((ishift_temp = (x)) < 0 ? \
  151.      (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
  152.      (ishift_temp >> (shft)))
  153. #else
  154. #define ISHIFT_TEMPS
  155. #define IRIGHT_SHIFT(x,shft)    ((x) >> (shft))
  156. #endif
  157.  
  158. #ifdef USE_ACCURATE_ROUNDING
  159. #define IDESCALE(x,n)  ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
  160. #else
  161. #define IDESCALE(x,n)  ((int) IRIGHT_SHIFT(x, n))
  162. #endif
  163.  
  164. #ifdef XP_WIN32
  165. __inline GLOBAL void
  166. jpeg_idct_ifast_mmx (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  167.          JCOEFPTR coef_block,
  168.          JSAMPARRAY output_buf, JDIMENSION output_col);
  169. __inline GLOBAL void
  170. jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  171.          JCOEFPTR coef_block,
  172.          JSAMPARRAY output_buf, JDIMENSION output_col);
  173. #endif
  174.  
  175. GLOBAL void
  176. jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info * compptr,
  177.          JCOEFPTR coef_block,
  178.          JSAMPARRAY output_buf, JDIMENSION output_col);
  179.  
  180.  
  181. #ifdef XP_WIN32
  182. GLOBAL void 
  183. jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  184.          JCOEFPTR coef_block,
  185.          JSAMPARRAY output_buf, JDIMENSION output_col)
  186. {
  187. if (MMXAvailable)
  188.     jpeg_idct_ifast_mmx(cinfo, compptr, coef_block, output_buf, output_col);
  189. else
  190.     jpeg_idct_ifast_orig(cinfo, compptr, coef_block, output_buf, output_col);
  191. }
  192. #else
  193.  
  194. /*
  195.  * Perform dequantization and inverse DCT on one block of coefficients.
  196.  */
  197.  
  198. GLOBAL void
  199. jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  200.          JCOEFPTR coef_block,
  201.          JSAMPARRAY output_buf, JDIMENSION output_col)
  202. {
  203.   DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  204.   DCTELEM tmp10, tmp11, tmp12, tmp13;
  205.   DCTELEM z5, z10, z11, z12, z13;
  206.   JCOEFPTR inptr;
  207.   IFAST_MULT_TYPE * quantptr;
  208.   int16 * wsptr;
  209.   JSAMPROW outptr;
  210.   JSAMPLE *range_limit = IDCT_range_limit(cinfo);
  211.   int ctr;
  212.   int16 workspace[DCTSIZE2];    /* buffers data between passes */
  213.   SHIFT_TEMPS            /* for DESCALE */
  214.   ISHIFT_TEMPS            /* for IDESCALE */
  215.  
  216.   /* Pass 1: process columns from input, store into work array. */
  217.  
  218.   inptr = coef_block;
  219.   quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
  220.   wsptr = workspace;
  221.   for (ctr = DCTSIZE; ctr > 0; ctr--) {
  222.     /* Due to quantization, we will usually find that many of the input
  223.      * coefficients are zero, especially the AC terms.  We can exploit this
  224.      * by short-circuiting the IDCT calculation for any column in which all
  225.      * the AC terms are zero.  In that case each output is equal to the
  226.      * DC coefficient (with scale factor as needed).
  227.      * With typical images and quantization tables, half or more of the
  228.      * column DCT calculations can be simplified this way.
  229.      */
  230.     
  231.     if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
  232.      inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
  233.      inptr[DCTSIZE*7]) == 0) {
  234.       /* AC terms all zero */
  235.       int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
  236.  
  237.       wsptr[DCTSIZE*0] = dcval;
  238.       wsptr[DCTSIZE*1] = dcval;
  239.       wsptr[DCTSIZE*2] = dcval;
  240.       wsptr[DCTSIZE*3] = dcval;
  241.       wsptr[DCTSIZE*4] = dcval;
  242.       wsptr[DCTSIZE*5] = dcval;
  243.       wsptr[DCTSIZE*6] = dcval;
  244.       wsptr[DCTSIZE*7] = dcval;
  245.       
  246.       inptr++;            /* advance pointers to next column */
  247.       quantptr++;
  248.       wsptr++;
  249.       continue;
  250.     }
  251.     
  252.     /* Even part */
  253.  
  254.     tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
  255.     tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
  256.     tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
  257.     tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
  258.  
  259.     tmp10 = tmp0 + tmp2;    /* phase 3 */
  260.     tmp11 = tmp0 - tmp2;
  261.  
  262.     tmp13 = tmp1 + tmp3;    /* phases 5-3 */
  263.     tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
  264.  
  265.     tmp0 = tmp10 + tmp13;    /* phase 2 */
  266.     tmp3 = tmp10 - tmp13;
  267.     tmp1 = tmp11 + tmp12;
  268.     tmp2 = tmp11 - tmp12;
  269.     
  270.     /* Odd part */
  271.  
  272.     tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
  273.     tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
  274.     tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
  275.     tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
  276.  
  277.     z13 = tmp6 + tmp5;        /* phase 6 */
  278.     z10 = tmp6 - tmp5;
  279.     z11 = tmp4 + tmp7;
  280.     z12 = tmp4 - tmp7;
  281.  
  282.     tmp7 = z11 + z13;        /* phase 5 */
  283.     tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
  284.  
  285.     z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
  286.     tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
  287.     tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
  288.  
  289.     tmp6 = tmp12 - tmp7;    /* phase 2 */
  290.     tmp5 = tmp11 - tmp6;
  291.     tmp4 = tmp10 + tmp5;
  292.  
  293.     wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
  294.     wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
  295.     wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
  296.     wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
  297.     wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
  298.     wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
  299.     wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
  300.     wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
  301.  
  302.     inptr++;            /* advance pointers to next column */
  303.     quantptr++;
  304.     wsptr++;
  305.   }
  306.   
  307.   /* Pass 2: process rows from work array, store into output array. */
  308.   /* Note that we must descale the results by a factor of 8 == 2**3, */
  309.   /* and also undo the PASS1_BITS scaling. */
  310.  
  311.   wsptr = workspace;
  312.   for (ctr = 0; ctr < DCTSIZE; ctr++) {
  313.     outptr = output_buf[ctr] + output_col;
  314.     /* Rows of zeroes can be exploited in the same way as we did with columns.
  315.      * However, the column calculation has created many nonzero AC terms, so
  316.      * the simplification applies less often (typically 5% to 10% of the time).
  317.      * On machines with very fast multiplication, it's possible that the
  318.      * test takes more time than it's worth.  In that case this section
  319.      * may be commented out.
  320.      */
  321.     
  322. #ifndef NO_ZERO_ROW_TEST
  323.     if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
  324.      wsptr[7]) == 0) {
  325.       /* AC terms all zero */
  326.       JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
  327.                   & RANGE_MASK];
  328.       
  329.       outptr[0] = dcval;
  330.       outptr[1] = dcval;
  331.       outptr[2] = dcval;
  332.       outptr[3] = dcval;
  333.       outptr[4] = dcval;
  334.       outptr[5] = dcval;
  335.       outptr[6] = dcval;
  336.       outptr[7] = dcval;
  337.  
  338.       wsptr += DCTSIZE;        /* advance pointer to next row */
  339.       continue;
  340.     }
  341. #endif
  342.     
  343.     /* Even part */
  344.  
  345.     tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
  346.     tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
  347.  
  348.     tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
  349.     tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
  350.         - tmp13;
  351.  
  352.     tmp0 = tmp10 + tmp13;
  353.     tmp3 = tmp10 - tmp13;
  354.     tmp1 = tmp11 + tmp12;
  355.     tmp2 = tmp11 - tmp12;
  356.  
  357.     /* Odd part */
  358.  
  359.     z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
  360.     z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
  361.     z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
  362.     z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
  363.  
  364.     tmp7 = z11 + z13;        /* phase 5 */
  365.     tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
  366.  
  367.     z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
  368.     tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
  369.     tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
  370.  
  371.     tmp6 = tmp12 - tmp7;    /* phase 2 */
  372.     tmp5 = tmp11 - tmp6;
  373.     tmp4 = tmp10 + tmp5;
  374.  
  375.     /* Final output stage: scale down by a factor of 8 and range-limit */
  376.  
  377.     outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
  378.                 & RANGE_MASK];
  379.     outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
  380.                 & RANGE_MASK];
  381.     outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
  382.                 & RANGE_MASK];
  383.     outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
  384.                 & RANGE_MASK];
  385.     outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
  386.                 & RANGE_MASK];
  387.     outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
  388.                 & RANGE_MASK];
  389.     outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
  390.                 & RANGE_MASK];
  391.     outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
  392.                 & RANGE_MASK];
  393.  
  394.     wsptr += DCTSIZE;        /* advance pointer to next row */
  395.   }
  396. }
  397. #endif
  398.  
  399. #ifdef XP_WIN32
  400.  
  401.  
  402. _inline GLOBAL void
  403. jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  404.          JCOEFPTR coef_block,
  405.          JSAMPARRAY output_buf, JDIMENSION output_col)
  406. {
  407.   DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  408.   DCTELEM tmp10, tmp11, tmp12, tmp13;
  409.   DCTELEM z5, z10, z11, z12, z13;
  410.   JCOEFPTR inptr;
  411.   IFAST_MULT_TYPE * quantptr;
  412.   int * wsptr;
  413.   JSAMPROW outptr;
  414.   JSAMPLE *range_limit = IDCT_range_limit(cinfo);
  415.   int ctr;
  416.   int workspace[DCTSIZE2];    /* buffers data between passes */
  417.   SHIFT_TEMPS            /* for DESCALE */
  418.   ISHIFT_TEMPS            /* for IDESCALE */
  419.  
  420.   /* Pass 1: process columns from input, store into work array. */
  421.  
  422.   inptr = coef_block;
  423.   quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
  424.   wsptr = workspace;
  425.   for (ctr = DCTSIZE; ctr > 0; ctr--) {
  426.     /* Due to quantization, we will usually find that many of the input
  427.      * coefficients are zero, especially the AC terms.  We can exploit this
  428.      * by short-circuiting the IDCT calculation for any column in which all
  429.      * the AC terms are zero.  In that case each output is equal to the
  430.      * DC coefficient (with scale factor as needed).
  431.      * With typical images and quantization tables, half or more of the
  432.      * column DCT calculations can be simplified this way.
  433.      */
  434.     
  435.     if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
  436.      inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
  437.      inptr[DCTSIZE*7]) == 0) {
  438.       /* AC terms all zero */
  439.       int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
  440.  
  441.       wsptr[DCTSIZE*0] = dcval;
  442.       wsptr[DCTSIZE*1] = dcval;
  443.       wsptr[DCTSIZE*2] = dcval;
  444.       wsptr[DCTSIZE*3] = dcval;
  445.       wsptr[DCTSIZE*4] = dcval;
  446.       wsptr[DCTSIZE*5] = dcval;
  447.       wsptr[DCTSIZE*6] = dcval;
  448.       wsptr[DCTSIZE*7] = dcval;
  449.       
  450.       inptr++;            /* advance pointers to next column */
  451.       quantptr++;
  452.       wsptr++;
  453.       continue;
  454.     }
  455.     
  456.     /* Even part */
  457.  
  458.     tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
  459.     tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
  460.     tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
  461.     tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
  462.  
  463.     tmp10 = tmp0 + tmp2;    /* phase 3 */
  464.     tmp11 = tmp0 - tmp2;
  465.  
  466.     tmp13 = tmp1 + tmp3;    /* phases 5-3 */
  467.     tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
  468.  
  469.     tmp0 = tmp10 + tmp13;    /* phase 2 */
  470.     tmp3 = tmp10 - tmp13;
  471.     tmp1 = tmp11 + tmp12;
  472.     tmp2 = tmp11 - tmp12;
  473.     
  474.     /* Odd part */
  475.  
  476.     tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
  477.     tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
  478.     tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
  479.     tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
  480.  
  481.     z13 = tmp6 + tmp5;        /* phase 6 */
  482.     z10 = tmp6 - tmp5;
  483.     z11 = tmp4 + tmp7;
  484.     z12 = tmp4 - tmp7;
  485.  
  486.     tmp7 = z11 + z13;        /* phase 5 */
  487.     tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
  488.  
  489.     z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
  490.     tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
  491.     tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
  492.  
  493.     tmp6 = tmp12 - tmp7;    /* phase 2 */
  494.     tmp5 = tmp11 - tmp6;
  495.     tmp4 = tmp10 + tmp5;
  496.  
  497.     wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
  498.     wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
  499.     wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
  500.     wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
  501.     wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
  502.     wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
  503.     wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
  504.     wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
  505.  
  506.     inptr++;            /* advance pointers to next column */
  507.     quantptr++;
  508.     wsptr++;
  509.   }
  510.   
  511.   /* Pass 2: process rows from work array, store into output array. */
  512.   /* Note that we must descale the results by a factor of 8 == 2**3, */
  513.   /* and also undo the PASS1_BITS scaling. */
  514.  
  515.   wsptr = workspace;
  516.   for (ctr = 0; ctr < DCTSIZE; ctr++) {
  517.     outptr = output_buf[ctr] + output_col;
  518.     /* Rows of zeroes can be exploited in the same way as we did with columns.
  519.      * However, the column calculation has created many nonzero AC terms, so
  520.      * the simplification applies less often (typically 5% to 10% of the time).
  521.      * On machines with very fast multiplication, it's possible that the
  522.      * test takes more time than it's worth.  In that case this section
  523.      * may be commented out.
  524.      */
  525.     
  526. #ifndef NO_ZERO_ROW_TEST
  527.     if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
  528.      wsptr[7]) == 0) {
  529.       /* AC terms all zero */
  530.       JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
  531.                   & RANGE_MASK];
  532.       
  533.       outptr[0] = dcval;
  534.       outptr[1] = dcval;
  535.       outptr[2] = dcval;
  536.       outptr[3] = dcval;
  537.       outptr[4] = dcval;
  538.       outptr[5] = dcval;
  539.       outptr[6] = dcval;
  540.       outptr[7] = dcval;
  541.  
  542.       wsptr += DCTSIZE;        /* advance pointer to next row */
  543.       continue;
  544.     }
  545. #endif
  546.     
  547.     /* Even part */
  548.  
  549.     tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
  550.     tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
  551.  
  552.     tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
  553.     tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
  554.         - tmp13;
  555.  
  556.     tmp0 = tmp10 + tmp13;
  557.     tmp3 = tmp10 - tmp13;
  558.     tmp1 = tmp11 + tmp12;
  559.     tmp2 = tmp11 - tmp12;
  560.  
  561.     /* Odd part */
  562.  
  563.     z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
  564.     z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
  565.     z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
  566.     z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
  567.  
  568.     tmp7 = z11 + z13;        /* phase 5 */
  569.     tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
  570.  
  571.     z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
  572.     tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
  573.     tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
  574.  
  575.     tmp6 = tmp12 - tmp7;    /* phase 2 */
  576.     tmp5 = tmp11 - tmp6;
  577.     tmp4 = tmp10 + tmp5;
  578.  
  579.     /* Final output stage: scale down by a factor of 8 and range-limit */
  580.  
  581.     outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
  582.                 & RANGE_MASK];
  583.     outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
  584.                 & RANGE_MASK];
  585.     outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
  586.                 & RANGE_MASK];
  587.     outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
  588.                 & RANGE_MASK];
  589.     outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
  590.                 & RANGE_MASK];
  591.     outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
  592.                 & RANGE_MASK];
  593.     outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
  594.                 & RANGE_MASK];
  595.     outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
  596.                 & RANGE_MASK];
  597.  
  598.     wsptr += DCTSIZE;        /* advance pointer to next row */
  599.   }
  600. }
  601.  
  602.  
  603.     static      __int64 fix_141        = 0x5a825a825a825a82;
  604.     static      __int64 fix_184n261    = 0xcf04cf04cf04cf04;
  605.     static      __int64 fix_184        = 0x7641764176417641;
  606.     static      __int64 fix_n184        = 0x896f896f896f896f;
  607.     static      __int64 fix_108n184    = 0xcf04cf04cf04cf04;
  608.     static      __int64 const_0x0080    = 0x0080008000800080;
  609.  
  610.  
  611. __inline GLOBAL void
  612. jpeg_idct_ifast_mmx (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  613.          JCOEFPTR inptr,
  614.          JSAMPARRAY outptr, JDIMENSION output_col)
  615. {
  616.  
  617.   int16 workspace[DCTSIZE2 + 4];    /* buffers data between passes */
  618.   int16 *wsptr=workspace;
  619.   int16 *quantptr=compptr->dct_table;
  620.  
  621.   __asm{ 
  622.     
  623.     mov        edi, quantptr
  624.     mov        ebx, inptr
  625.     mov        esi, wsptr
  626.     add        esi, 0x07        ;align wsptr to qword
  627.     and        esi, 0xfffffff8    ;align wsptr to qword
  628.  
  629.     mov        eax, esi
  630.  
  631.     /* Odd part */
  632.  
  633.  
  634.     movq        mm1, [ebx + 8*10]        ;load inptr[DCTSIZE*5]
  635.  
  636.     pmullw        mm1, [edi + 8*10]        ;tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
  637.  
  638.     movq        mm0, [ebx + 8*6]        ;load inptr[DCTSIZE*3]
  639.  
  640.     pmullw        mm0, [edi + 8*6]        ;tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
  641.  
  642.     movq        mm3, [ebx + 8*2]        ;load inptr[DCTSIZE*1]
  643.     movq    mm2, mm1                    ;copy tmp6    /* phase 6 */
  644.  
  645.     pmullw        mm3, [edi + 8*2]        ;tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
  646.  
  647.     movq        mm4, [ebx + 8*14]        ;load inptr[DCTSIZE*1]
  648.     paddw    mm1, mm0                    ;z13 = tmp6 + tmp5;
  649.  
  650.     pmullw        mm4, [edi + 8*14]        ;tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
  651.     psubw    mm2, mm0                    ;z10 = tmp6 - tmp5   
  652.  
  653.     psllw        mm2, 2                ;shift z10
  654.     movq        mm0, mm2            ;copy z10
  655.  
  656.     pmulhw        mm2, fix_184n261    ;MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */
  657.     movq        mm5, mm3                ;copy tmp4
  658.  
  659.     pmulhw        mm0, fix_n184        ;MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */
  660.     paddw        mm3, mm4                ;z11 = tmp4 + tmp7;
  661.  
  662.     movq        mm6, mm3                ;copy z11            /* phase 5 */
  663.     psubw        mm5, mm4                ;z12 = tmp4 - tmp7;
  664.  
  665.     psubw        mm6, mm1                ;z11-z13
  666.     psllw        mm5, 2                ;shift z12
  667.  
  668.     movq        mm4, [ebx + 8*12]        ;load inptr[DCTSIZE*6], even part
  669.      movq        mm7, mm5            ;copy z12
  670.  
  671.     pmulhw        mm5, fix_108n184    ;MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part
  672.     paddw        mm3, mm1                ;tmp7 = z11 + z13;    
  673.  
  674.  
  675.     /* Even part */
  676.     pmulhw        mm7, fix_184        ;MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */
  677.     psllw        mm6, 2
  678.  
  679.     movq        mm1, [ebx + 8*4]        ;load inptr[DCTSIZE*2]
  680.  
  681.     pmullw        mm1, [edi + 8*4]        ;tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
  682.     paddw        mm0, mm5            ;tmp10
  683.  
  684.     pmullw        mm4, [edi + 8*12]        ;tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
  685.     paddw        mm2, mm7            ;tmp12
  686.  
  687.     pmulhw        mm6, fix_141            ;tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
  688.     psubw        mm2, mm3        ;tmp6 = tmp12 - tmp7
  689.  
  690.     movq        mm5, mm1                ;copy tmp1
  691.     paddw        mm1, mm4                ;tmp13= tmp1 + tmp3;    /* phases 5-3 */
  692.  
  693.     psubw        mm5, mm4                ;tmp1-tmp3
  694.     psubw        mm6, mm2        ;tmp5 = tmp11 - tmp6;
  695.  
  696.     movq        [esi+8*0], mm1            ;save tmp13 in workspace
  697.     psllw        mm5, 2                    ;shift tmp1-tmp3
  698.     
  699.     movq        mm7, [ebx + 8*0]        ;load inptr[DCTSIZE*0]
  700.  
  701.     pmulhw        mm5, fix_141            ;MULTIPLY(tmp1 - tmp3, FIX_1_414213562)
  702.     paddw        mm0, mm6        ;tmp4 = tmp10 + tmp5;
  703.  
  704.     pmullw        mm7, [edi + 8*0]        ;tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
  705.  
  706.     movq        mm4, [ebx + 8*8]        ;load inptr[DCTSIZE*4]
  707.     
  708.     pmullw        mm4, [edi + 8*8]        ;tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
  709.     psubw        mm5, mm1                ;tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
  710.  
  711.     movq        [esi+8*4], mm0        ;save tmp4 in workspace
  712.     movq        mm1, mm7            ;copy tmp0    /* phase 3 */
  713.  
  714.     movq        [esi+8*2], mm5        ;save tmp12 in workspace
  715.     psubw        mm1, mm4            ;tmp11 = tmp0 - tmp2; 
  716.  
  717.     paddw        mm7, mm4            ;tmp10 = tmp0 + tmp2;
  718.     movq        mm5, mm1        ;copy tmp11
  719.     
  720.     paddw        mm1, [esi+8*2]    ;tmp1 = tmp11 + tmp12;
  721.     movq        mm4, mm7        ;copy tmp10        /* phase 2 */
  722.  
  723.     paddw        mm7, [esi+8*0]    ;tmp0 = tmp10 + tmp13;    
  724.  
  725.     psubw        mm4, [esi+8*0]    ;tmp3 = tmp10 - tmp13;
  726.     movq        mm0, mm7        ;copy tmp0
  727.  
  728.     psubw        mm5, [esi+8*2]    ;tmp2 = tmp11 - tmp12;
  729.     paddw        mm7, mm3        ;wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
  730.     
  731.     psubw        mm0, mm3            ;wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
  732.  
  733.     movq        [esi + 8*0], mm7    ;wsptr[DCTSIZE*0]
  734.     movq        mm3, mm1            ;copy tmp1
  735.  
  736.     movq        [esi + 8*14], mm0    ;wsptr[DCTSIZE*7]
  737.     paddw        mm1, mm2            ;wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
  738.  
  739.     psubw        mm3, mm2            ;wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
  740.  
  741.     movq        [esi + 8*2], mm1    ;wsptr[DCTSIZE*1]
  742.     movq        mm1, mm4            ;copy tmp3
  743.  
  744.     movq        [esi + 8*12], mm3    ;wsptr[DCTSIZE*6]
  745.  
  746.     paddw        mm4, [esi+8*4]        ;wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
  747.  
  748.     psubw        mm1, [esi+8*4]        ;wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
  749.  
  750.     movq        [esi + 8*8], mm4
  751.     movq        mm7, mm5            ;copy tmp2
  752.  
  753.     paddw        mm5, mm6            ;wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5)
  754.  
  755.     movq        [esi+8*6], mm1        ;
  756.     psubw        mm7, mm6            ;wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
  757.  
  758.     movq        [esi + 8*4], mm5
  759.  
  760.     movq        [esi + 8*10], mm7
  761.  
  762.  
  763.  
  764. /*****************************************************************/
  765.     add        edi, 8
  766.     add        ebx, 8
  767.     add        esi, 8
  768.  
  769. /*****************************************************************/
  770.  
  771.  
  772.  
  773.  
  774.     movq        mm1, [ebx + 8*10]        ;load inptr[DCTSIZE*5]
  775.  
  776.     pmullw        mm1, [edi + 8*10]        ;tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
  777.  
  778.     movq        mm0, [ebx + 8*6]        ;load inptr[DCTSIZE*3]
  779.  
  780.     pmullw        mm0, [edi + 8*6]        ;tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
  781.  
  782.     movq        mm3, [ebx + 8*2]        ;load inptr[DCTSIZE*1]
  783.     movq    mm2, mm1                    ;copy tmp6    /* phase 6 */
  784.  
  785.     pmullw        mm3, [edi + 8*2]        ;tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
  786.  
  787.     movq        mm4, [ebx + 8*14]        ;load inptr[DCTSIZE*1]
  788.     paddw    mm1, mm0                    ;z13 = tmp6 + tmp5;
  789.  
  790.     pmullw        mm4, [edi + 8*14]        ;tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
  791.     psubw    mm2, mm0                    ;z10 = tmp6 - tmp5   
  792.  
  793.     psllw        mm2, 2                ;shift z10
  794.     movq        mm0, mm2            ;copy z10
  795.  
  796.     pmulhw        mm2, fix_184n261    ;MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */
  797.     movq        mm5, mm3                ;copy tmp4
  798.  
  799.     pmulhw        mm0, fix_n184        ;MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */
  800.     paddw        mm3, mm4                ;z11 = tmp4 + tmp7;
  801.  
  802.     movq        mm6, mm3                ;copy z11            /* phase 5 */
  803.     psubw        mm5, mm4                ;z12 = tmp4 - tmp7;
  804.  
  805.     psubw        mm6, mm1                ;z11-z13
  806.     psllw        mm5, 2                ;shift z12
  807.  
  808.     movq        mm4, [ebx + 8*12]        ;load inptr[DCTSIZE*6], even part
  809.      movq        mm7, mm5            ;copy z12
  810.  
  811.     pmulhw        mm5, fix_108n184    ;MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part
  812.     paddw        mm3, mm1                ;tmp7 = z11 + z13;    
  813.  
  814.  
  815.     /* Even part */
  816.     pmulhw        mm7, fix_184        ;MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */
  817.     psllw        mm6, 2
  818.  
  819.     movq        mm1, [ebx + 8*4]        ;load inptr[DCTSIZE*2]
  820.  
  821.     pmullw        mm1, [edi + 8*4]        ;tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
  822.     paddw        mm0, mm5            ;tmp10
  823.  
  824.     pmullw        mm4, [edi + 8*12]        ;tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
  825.     paddw        mm2, mm7            ;tmp12
  826.  
  827.     pmulhw        mm6, fix_141            ;tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
  828.     psubw        mm2, mm3        ;tmp6 = tmp12 - tmp7
  829.  
  830.     movq        mm5, mm1                ;copy tmp1
  831.     paddw        mm1, mm4                ;tmp13= tmp1 + tmp3;    /* phases 5-3 */
  832.  
  833.     psubw        mm5, mm4                ;tmp1-tmp3
  834.     psubw        mm6, mm2        ;tmp5 = tmp11 - tmp6;
  835.  
  836.     movq        [esi+8*0], mm1            ;save tmp13 in workspace
  837.     psllw        mm5, 2                    ;shift tmp1-tmp3
  838.     
  839.     movq        mm7, [ebx + 8*0]        ;load inptr[DCTSIZE*0]
  840.     paddw        mm0, mm6        ;tmp4 = tmp10 + tmp5;
  841.  
  842.     pmulhw        mm5, fix_141            ;MULTIPLY(tmp1 - tmp3, FIX_1_414213562)
  843.  
  844.     pmullw        mm7, [edi + 8*0]        ;tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
  845.  
  846.     movq        mm4, [ebx + 8*8]        ;load inptr[DCTSIZE*4]
  847.     
  848.     pmullw        mm4, [edi + 8*8]        ;tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
  849.     psubw        mm5, mm1                ;tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
  850.  
  851.     movq        [esi+8*4], mm0        ;save tmp4 in workspace
  852.     movq        mm1, mm7            ;copy tmp0    /* phase 3 */
  853.  
  854.     movq        [esi+8*2], mm5        ;save tmp12 in workspace
  855.     psubw        mm1, mm4            ;tmp11 = tmp0 - tmp2; 
  856.  
  857.     paddw        mm7, mm4            ;tmp10 = tmp0 + tmp2;
  858.     movq        mm5, mm1        ;copy tmp11
  859.     
  860.     paddw        mm1, [esi+8*2]    ;tmp1 = tmp11 + tmp12;
  861.     movq        mm4, mm7        ;copy tmp10        /* phase 2 */
  862.  
  863.     paddw        mm7, [esi+8*0]    ;tmp0 = tmp10 + tmp13;    
  864.  
  865.     psubw        mm4, [esi+8*0]    ;tmp3 = tmp10 - tmp13;
  866.     movq        mm0, mm7        ;copy tmp0
  867.  
  868.     psubw        mm5, [esi+8*2]    ;tmp2 = tmp11 - tmp12;
  869.     paddw        mm7, mm3        ;wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
  870.     
  871.     psubw        mm0, mm3            ;wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
  872.  
  873.     movq        [esi + 8*0], mm7    ;wsptr[DCTSIZE*0]
  874.     movq        mm3, mm1            ;copy tmp1
  875.  
  876.     movq        [esi + 8*14], mm0    ;wsptr[DCTSIZE*7]
  877.     paddw        mm1, mm2            ;wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
  878.  
  879.     psubw        mm3, mm2            ;wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
  880.  
  881.     movq        [esi + 8*2], mm1    ;wsptr[DCTSIZE*1]
  882.     movq        mm1, mm4            ;copy tmp3
  883.  
  884.     movq        [esi + 8*12], mm3    ;wsptr[DCTSIZE*6]
  885.  
  886.     paddw        mm4, [esi+8*4]        ;wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
  887.  
  888.     psubw        mm1, [esi+8*4]        ;wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
  889.  
  890.     movq        [esi + 8*8], mm4
  891.     movq        mm7, mm5            ;copy tmp2
  892.  
  893.     paddw        mm5, mm6            ;wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5)
  894.  
  895.     movq        [esi+8*6], mm1        ;
  896.     psubw        mm7, mm6            ;wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
  897.  
  898.     movq        [esi + 8*4], mm5
  899.  
  900.     movq        [esi + 8*10], mm7
  901.  
  902.  
  903.  
  904.  
  905. /*****************************************************************/
  906.  
  907.   /* Pass 2: process rows from work array, store into output array. */
  908.   /* Note that we must descale the results by a factor of 8 == 2**3, */
  909.   /* and also undo the PASS1_BITS scaling. */
  910.  
  911. /*****************************************************************/
  912.     /* Even part */
  913.  
  914.     mov            esi, eax
  915.     mov            eax, outptr
  916.  
  917. //    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
  918. //    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
  919. //    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
  920. //    tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]);
  921.     movq        mm0, [esi+8*0]        ;wsptr[0,0],[0,1],[0,2],[0,3]
  922.  
  923.     movq        mm1, [esi+8*1]        ;wsptr[0,4],[0,5],[0,6],[0,7]
  924.     movq        mm2, mm0
  925.     
  926.     movq        mm3, [esi+8*2]        ;wsptr[1,0],[1,1],[1,2],[1,3]
  927.     paddw        mm0, mm1            ;wsptr[0,tmp10],[xxx],[0,tmp13],[xxx]
  928.  
  929.     movq        mm4, [esi+8*3]        ;wsptr[1,4],[1,5],[1,6],[1,7]
  930.     psubw        mm2, mm1            ;wsptr[0,tmp11],[xxx],[0,tmp14],[xxx]
  931.  
  932.     movq        mm6, mm0
  933.     movq        mm5, mm3
  934.     
  935.     paddw        mm3, mm4            ;wsptr[1,tmp10],[xxx],[1,tmp13],[xxx]
  936.     movq        mm1, mm2
  937.  
  938.     psubw        mm5, mm4            ;wsptr[1,tmp11],[xxx],[1,tmp14],[xxx]
  939.     punpcklwd    mm0, mm3            ;wsptr[0,tmp10],[1,tmp10],[xxx],[xxx]
  940.  
  941.     movq        mm7, [esi+8*7]        ;wsptr[3,4],[3,5],[3,6],[3,7]
  942.     punpckhwd    mm6, mm3            ;wsptr[0,tmp13],[1,tmp13],[xxx],[xxx]
  943.  
  944.     movq        mm3, [esi+8*4]        ;wsptr[2,0],[2,1],[2,2],[2,3]
  945.     punpckldq    mm0, mm6    ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
  946.  
  947.     punpcklwd    mm1, mm5            ;wsptr[0,tmp11],[1,tmp11],[xxx],[xxx]
  948.     movq        mm4, mm3
  949.  
  950.     movq        mm6, [esi+8*6]        ;wsptr[3,0],[3,1],[3,2],[3,3]
  951.     punpckhwd    mm2, mm5            ;wsptr[0,tmp14],[1,tmp14],[xxx],[xxx]
  952.  
  953.     movq        mm5, [esi+8*5]        ;wsptr[2,4],[2,5],[2,6],[2,7]
  954.     punpckldq    mm1, mm2    ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
  955.  
  956.     
  957.     paddw        mm3, mm5            ;wsptr[2,tmp10],[xxx],[2,tmp13],[xxx]
  958.     movq        mm2, mm6
  959.  
  960.     psubw        mm4, mm5            ;wsptr[2,tmp11],[xxx],[2,tmp14],[xxx]
  961.     paddw        mm6, mm7            ;wsptr[3,tmp10],[xxx],[3,tmp13],[xxx]
  962.  
  963.     movq        mm5, mm3
  964.     punpcklwd    mm3, mm6            ;wsptr[2,tmp10],[3,tmp10],[xxx],[xxx]
  965.     
  966.     psubw        mm2, mm7            ;wsptr[3,tmp11],[xxx],[3,tmp14],[xxx]
  967.     punpckhwd    mm5, mm6            ;wsptr[2,tmp13],[3,tmp13],[xxx],[xxx]
  968.  
  969.     movq        mm7, mm4
  970.     punpckldq    mm3, mm5    ;wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13]
  971.  
  972.     punpcklwd    mm4, mm2            ;wsptr[2,tmp11],[3,tmp11],[xxx],[xxx]
  973.  
  974.     punpckhwd    mm7, mm2            ;wsptr[2,tmp14],[3,tmp14],[xxx],[xxx]
  975.  
  976.     punpckldq    mm4, mm7    ;wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14]
  977.     movq        mm6, mm1
  978.  
  979. //    mm0 =     ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
  980. //    mm1 =    ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
  981.  
  982.  
  983.     movq        mm2, mm0
  984.     punpckhdq    mm6, mm4    ;wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14]
  985.  
  986.     punpckldq    mm1, mm4    ;wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11]
  987.     psllw        mm6, 2
  988.  
  989.     pmulhw        mm6, fix_141
  990.     punpckldq    mm0, mm3    ;wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10]
  991.  
  992.     punpckhdq    mm2, mm3    ;wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13]
  993.     movq        mm7, mm0
  994.  
  995. //    tmp0 = tmp10 + tmp13;
  996. //    tmp3 = tmp10 - tmp13;
  997.     paddw        mm0, mm2    ;[0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0]
  998.     psubw        mm7, mm2    ;[0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3]
  999.  
  1000. //    tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13;
  1001.     psubw        mm6, mm2    ;wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12]
  1002. //    tmp1 = tmp11 + tmp12;
  1003. //    tmp2 = tmp11 - tmp12;
  1004.     movq        mm5, mm1
  1005.  
  1006.  
  1007.  
  1008.     /* Odd part */
  1009.  
  1010. //    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
  1011. //    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
  1012. //    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
  1013. //    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
  1014.     movq        mm3, [esi+8*0]        ;wsptr[0,0],[0,1],[0,2],[0,3]
  1015.     paddw        mm1, mm6    ;[0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1]
  1016.  
  1017.     movq        mm4, [esi+8*1]        ;wsptr[0,4],[0,5],[0,6],[0,7]
  1018.     psubw        mm5, mm6    ;[0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2]
  1019.  
  1020.     movq        mm6, mm3
  1021.     punpckldq    mm3, mm4            ;wsptr[0,0],[0,1],[0,4],[0,5]
  1022.  
  1023.     punpckhdq    mm4, mm6            ;wsptr[0,6],[0,7],[0,2],[0,3]
  1024.     movq        mm2, mm3
  1025.  
  1026. //Save tmp0 and tmp1 in wsptr
  1027.     movq        [esi+8*0], mm0        ;save tmp0
  1028.     paddw        mm2, mm4            ;wsptr[xxx],[0,z11],[xxx],[0,z13]
  1029.  
  1030.     
  1031. //Continue with z10 --- z13
  1032.     movq        mm6, [esi+8*2]        ;wsptr[1,0],[1,1],[1,2],[1,3]
  1033.     psubw        mm3, mm4            ;wsptr[xxx],[0,z12],[xxx],[0,z10]
  1034.  
  1035.     movq        mm0, [esi+8*3]        ;wsptr[1,4],[1,5],[1,6],[1,7]
  1036.     movq        mm4, mm6
  1037.  
  1038.     movq        [esi+8*1], mm1        ;save tmp1
  1039.     punpckldq    mm6, mm0            ;wsptr[1,0],[1,1],[1,4],[1,5]
  1040.  
  1041.     punpckhdq    mm0, mm4            ;wsptr[1,6],[1,7],[1,2],[1,3]
  1042.     movq        mm1, mm6
  1043.     
  1044. //Save tmp2 and tmp3 in wsptr
  1045.     paddw        mm6, mm0        ;wsptr[xxx],[1,z11],[xxx],[1,z13]
  1046.     movq        mm4, mm2
  1047.     
  1048. //Continue with z10 --- z13
  1049.     movq        [esi+8*2], mm5        ;save tmp2
  1050.     punpcklwd    mm2, mm6        ;wsptr[xxx],[xxx],[0,z11],[1,z11]
  1051.  
  1052.     psubw        mm1, mm0        ;wsptr[xxx],[1,z12],[xxx],[1,z10]
  1053.     punpckhwd    mm4, mm6        ;wsptr[xxx],[xxx],[0,z13],[1,z13]
  1054.  
  1055.     movq        mm0, mm3
  1056.     punpcklwd    mm3, mm1        ;wsptr[xxx],[xxx],[0,z12],[1,z12]
  1057.  
  1058.     movq        [esi+8*3], mm7        ;save tmp3
  1059.     punpckhwd    mm0, mm1        ;wsptr[xxx],[xxx],[0,z10],[1,z10]
  1060.  
  1061.     movq        mm6, [esi+8*4]        ;wsptr[2,0],[2,1],[2,2],[2,3]
  1062.     punpckhdq    mm0, mm2        ;wsptr[0,z10],[1,z10],[0,z11],[1,z11]
  1063.  
  1064.     movq        mm7, [esi+8*5]        ;wsptr[2,4],[2,5],[2,6],[2,7]
  1065.     punpckhdq    mm3, mm4        ;wsptr[0,z12],[1,z12],[0,z13],[1,z13]
  1066.  
  1067.     movq        mm1, [esi+8*6]        ;wsptr[3,0],[3,1],[3,2],[3,3]
  1068.     movq        mm4, mm6
  1069.  
  1070.     punpckldq    mm6, mm7            ;wsptr[2,0],[2,1],[2,4],[2,5]
  1071.     movq        mm5, mm1
  1072.  
  1073.     punpckhdq    mm7, mm4            ;wsptr[2,6],[2,7],[2,2],[2,3]
  1074.     movq        mm2, mm6
  1075.     
  1076.     movq        mm4, [esi+8*7]        ;wsptr[3,4],[3,5],[3,6],[3,7]
  1077.     paddw        mm6, mm7        ;wsptr[xxx],[2,z11],[xxx],[2,z13]
  1078.  
  1079.     psubw        mm2, mm7        ;wsptr[xxx],[2,z12],[xxx],[2,z10]
  1080.     punpckldq    mm1, mm4            ;wsptr[3,0],[3,1],[3,4],[3,5]
  1081.  
  1082.     punpckhdq    mm4, mm5            ;wsptr[3,6],[3,7],[3,2],[3,3]
  1083.     movq        mm7, mm1
  1084.  
  1085.     paddw        mm1, mm4        ;wsptr[xxx],[3,z11],[xxx],[3,z13]
  1086.     psubw        mm7, mm4        ;wsptr[xxx],[3,z12],[xxx],[3,z10]
  1087.  
  1088.     movq        mm5, mm6
  1089.     punpcklwd    mm6, mm1        ;wsptr[xxx],[xxx],[2,z11],[3,z11]
  1090.  
  1091.     punpckhwd    mm5, mm1        ;wsptr[xxx],[xxx],[2,z13],[3,z13]
  1092.     movq        mm4, mm2
  1093.  
  1094.     punpcklwd    mm2, mm7        ;wsptr[xxx],[xxx],[2,z12],[3,z12]
  1095.  
  1096.     punpckhwd    mm4, mm7        ;wsptr[xxx],[xxx],[2,z10],[3,z10]
  1097.  
  1098.     punpckhdq    mm4, mm6        ;wsptr[2,z10],[3,z10],[2,z11],[3,z11]
  1099.  
  1100.     punpckhdq    mm2, mm5        ;wsptr[2,z12],[3,z12],[2,z13],[3,z13]
  1101.     movq        mm5, mm0
  1102.  
  1103.     punpckldq    mm0, mm4        ;wsptr[0,z10],[1,z10],[2,z10],[3,z10]
  1104.  
  1105.     punpckhdq    mm5, mm4        ;wsptr[0,z11],[1,z11],[2,z11],[3,z11]
  1106.     movq        mm4, mm3
  1107.  
  1108.     punpckhdq    mm4, mm2        ;wsptr[0,z13],[1,z13],[2,z13],[3,z13]
  1109.     movq        mm1, mm5
  1110.  
  1111.     punpckldq    mm3, mm2        ;wsptr[0,z12],[1,z12],[2,z12],[3,z12]
  1112. //    tmp7 = z11 + z13;        /* phase 5 */
  1113. //    tmp8 = z11 - z13;        /* phase 5 */
  1114.     psubw        mm1, mm4        ;tmp8
  1115.  
  1116.     paddw        mm5, mm4        ;tmp7
  1117. //    tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */
  1118.     psllw        mm1, 2
  1119.  
  1120.     psllw        mm0, 2
  1121.  
  1122.     pmulhw        mm1, fix_141    ;tmp21
  1123. //    tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065))  /* 2*(c2-c6) */
  1124. //            + MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */
  1125.     psllw        mm3, 2
  1126.     movq        mm7, mm0
  1127.  
  1128.     pmulhw        mm7, fix_n184
  1129.     movq        mm6, mm3
  1130.  
  1131.     movq        mm2, [esi+8*0]    ;tmp0,final1
  1132.  
  1133.     pmulhw        mm6, fix_108n184
  1134. //     tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */
  1135. //            + MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */
  1136.     movq        mm4, mm2        ;final1
  1137.   
  1138.     pmulhw        mm0, fix_184n261
  1139.     paddw        mm2, mm5        ;tmp0+tmp7,final1
  1140.  
  1141.     pmulhw        mm3, fix_184
  1142.     psubw        mm4, mm5        ;tmp0-tmp7,final1
  1143.  
  1144. //    tmp6 = tmp22 - tmp7;    /* phase 2 */
  1145.     psraw        mm2, 5            ;outptr[0,0],[1,0],[2,0],[3,0],final1
  1146.  
  1147.     paddsw        mm2, const_0x0080    ;final1
  1148.     paddw        mm7, mm6            ;tmp20
  1149.     psraw        mm4, 5            ;outptr[0,7],[1,7],[2,7],[3,7],final1
  1150.  
  1151.     paddsw        mm4, const_0x0080    ;final1
  1152.     paddw        mm3, mm0            ;tmp22
  1153.  
  1154. //    tmp5 = tmp21 - tmp6;
  1155.     psubw        mm3, mm5        ;tmp6
  1156.  
  1157. //    tmp4 = tmp20 + tmp5;
  1158.     movq        mm0, [esi+8*1]        ;tmp1,final2
  1159.     psubw        mm1, mm3        ;tmp5
  1160.  
  1161.     movq        mm6, mm0            ;final2
  1162.     paddw        mm0, mm3        ;tmp1+tmp6,final2
  1163.  
  1164.     /* Final output stage: scale down by a factor of 8 and range-limit */
  1165.  
  1166.  
  1167. //    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
  1168. //                & RANGE_MASK];
  1169. //    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
  1170. //                & RANGE_MASK];    final1
  1171.  
  1172.  
  1173. //    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
  1174. //                & RANGE_MASK];
  1175. //    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
  1176. //                & RANGE_MASK];    final2
  1177.     psubw        mm6, mm3        ;tmp1-tmp6,final2
  1178.     psraw        mm0, 5            ;outptr[0,1],[1,1],[2,1],[3,1]
  1179.  
  1180.     paddsw        mm0, const_0x0080
  1181.     psraw        mm6, 5            ;outptr[0,6],[1,6],[2,6],[3,6]
  1182.     
  1183.     paddsw        mm6, const_0x0080        ;need to check this value
  1184.     packuswb    mm0, mm4    ;out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7]
  1185.     
  1186.     movq        mm5, [esi+8*2]        ;tmp2,final3
  1187.     packuswb    mm2, mm6    ;out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6]
  1188.  
  1189. //    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
  1190. //                & RANGE_MASK];
  1191. //    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
  1192. //                & RANGE_MASK];    final3
  1193.     paddw        mm7, mm1        ;tmp4
  1194.     movq        mm3, mm5
  1195.  
  1196.     paddw        mm5, mm1        ;tmp2+tmp5
  1197.     psubw        mm3, mm1        ;tmp2-tmp5
  1198.  
  1199.     psraw        mm5, 5            ;outptr[0,2],[1,2],[2,2],[3,2]
  1200.  
  1201.     paddsw        mm5, const_0x0080
  1202.     movq        mm4, [esi+8*3]        ;tmp3,final4
  1203.     psraw        mm3, 5            ;outptr[0,5],[1,5],[2,5],[3,5]
  1204.  
  1205.     paddsw        mm3, const_0x0080
  1206.  
  1207.  
  1208. //    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
  1209. //                & RANGE_MASK];
  1210. //    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
  1211. //                & RANGE_MASK];    final4
  1212.     movq        mm6, mm4
  1213.     paddw        mm4, mm7        ;tmp3+tmp4
  1214.  
  1215.     psubw        mm6, mm7        ;tmp3-tmp4
  1216.     psraw        mm4, 5            ;outptr[0,4],[1,4],[2,4],[3,4]
  1217.     mov            ecx, [eax]
  1218.  
  1219.     paddsw        mm4, const_0x0080
  1220.     psraw        mm6, 5            ;outptr[0,3],[1,3],[2,3],[3,3]
  1221.  
  1222.     paddsw        mm6, const_0x0080
  1223.     packuswb    mm5, mm4    ;out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4]
  1224.  
  1225.     packuswb    mm6, mm3    ;out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5]
  1226.     movq        mm4, mm2
  1227.  
  1228.     movq        mm7, mm5
  1229.     punpcklbw    mm2, mm0    ;out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1]
  1230.  
  1231.     punpckhbw    mm4, mm0    ;out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7]
  1232.     movq        mm1, mm2
  1233.  
  1234.     punpcklbw    mm5, mm6    ;out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]
  1235.     add             eax, 4
  1236.  
  1237.     punpckhbw    mm7, mm6    ;out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]
  1238.  
  1239.     punpcklwd    mm2, mm5    ;out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]
  1240.     add            ecx, output_col
  1241.  
  1242.     movq        mm6, mm7
  1243.     punpckhwd    mm1, mm5    ;out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]
  1244.  
  1245.     movq        mm0, mm2
  1246.     punpcklwd    mm6, mm4    ;out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7]
  1247.  
  1248.     mov            ebx, [eax]
  1249.     punpckldq    mm2, mm6    ;out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]
  1250.  
  1251.     add             eax, 4
  1252.     movq        mm3, mm1
  1253.  
  1254.     add            ebx, output_col 
  1255.     punpckhwd    mm7, mm4    ;out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7]
  1256.     
  1257.     movq        [ecx], mm2
  1258.     punpckhdq    mm0, mm6    ;out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]
  1259.  
  1260.     mov            ecx, [eax]
  1261.     add             eax, 4
  1262.     add            ecx, output_col
  1263.  
  1264.     movq        [ebx], mm0
  1265.     punpckldq    mm1, mm7    ;out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7]
  1266.  
  1267.     mov            ebx, [eax]
  1268.  
  1269.     add            ebx, output_col
  1270.     punpckhdq    mm3, mm7    ;out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7]
  1271.     movq        [ecx], mm1
  1272.  
  1273.  
  1274.     movq        [ebx], mm3
  1275.  
  1276.  
  1277.         
  1278. /*******************************************************************/
  1279.     
  1280.  
  1281.     add            esi, 64
  1282.     add            eax, 4
  1283.  
  1284. /*******************************************************************/
  1285.  
  1286. //    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
  1287. //    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
  1288. //    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
  1289. //    tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]);
  1290.     movq        mm0, [esi+8*0]        ;wsptr[0,0],[0,1],[0,2],[0,3]
  1291.  
  1292.     movq        mm1, [esi+8*1]        ;wsptr[0,4],[0,5],[0,6],[0,7]
  1293.     movq        mm2, mm0
  1294.     
  1295.     movq        mm3, [esi+8*2]        ;wsptr[1,0],[1,1],[1,2],[1,3]
  1296.     paddw        mm0, mm1            ;wsptr[0,tmp10],[xxx],[0,tmp13],[xxx]
  1297.  
  1298.     movq        mm4, [esi+8*3]        ;wsptr[1,4],[1,5],[1,6],[1,7]
  1299.     psubw        mm2, mm1            ;wsptr[0,tmp11],[xxx],[0,tmp14],[xxx]
  1300.  
  1301.     movq        mm6, mm0
  1302.     movq        mm5, mm3
  1303.     
  1304.     paddw        mm3, mm4            ;wsptr[1,tmp10],[xxx],[1,tmp13],[xxx]
  1305.     movq        mm1, mm2
  1306.  
  1307.     psubw        mm5, mm4            ;wsptr[1,tmp11],[xxx],[1,tmp14],[xxx]
  1308.     punpcklwd    mm0, mm3            ;wsptr[0,tmp10],[1,tmp10],[xxx],[xxx]
  1309.  
  1310.     movq        mm7, [esi+8*7]        ;wsptr[3,4],[3,5],[3,6],[3,7]
  1311.     punpckhwd    mm6, mm3            ;wsptr[0,tmp13],[1,tmp13],[xxx],[xxx]
  1312.  
  1313.     movq        mm3, [esi+8*4]        ;wsptr[2,0],[2,1],[2,2],[2,3]
  1314.     punpckldq    mm0, mm6    ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
  1315.  
  1316.     punpcklwd    mm1, mm5            ;wsptr[0,tmp11],[1,tmp11],[xxx],[xxx]
  1317.     movq        mm4, mm3
  1318.  
  1319.     movq        mm6, [esi+8*6]        ;wsptr[3,0],[3,1],[3,2],[3,3]
  1320.     punpckhwd    mm2, mm5            ;wsptr[0,tmp14],[1,tmp14],[xxx],[xxx]
  1321.  
  1322.     movq        mm5, [esi+8*5]        ;wsptr[2,4],[2,5],[2,6],[2,7]
  1323.     punpckldq    mm1, mm2    ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
  1324.  
  1325.     
  1326.     paddw        mm3, mm5            ;wsptr[2,tmp10],[xxx],[2,tmp13],[xxx]
  1327.     movq        mm2, mm6
  1328.  
  1329.     psubw        mm4, mm5            ;wsptr[2,tmp11],[xxx],[2,tmp14],[xxx]
  1330.     paddw        mm6, mm7            ;wsptr[3,tmp10],[xxx],[3,tmp13],[xxx]
  1331.  
  1332.     movq        mm5, mm3
  1333.     punpcklwd    mm3, mm6            ;wsptr[2,tmp10],[3,tmp10],[xxx],[xxx]
  1334.     
  1335.     psubw        mm2, mm7            ;wsptr[3,tmp11],[xxx],[3,tmp14],[xxx]
  1336.     punpckhwd    mm5, mm6            ;wsptr[2,tmp13],[3,tmp13],[xxx],[xxx]
  1337.  
  1338.     movq        mm7, mm4
  1339.     punpckldq    mm3, mm5    ;wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13]
  1340.  
  1341.     punpcklwd    mm4, mm2            ;wsptr[2,tmp11],[3,tmp11],[xxx],[xxx]
  1342.  
  1343.     punpckhwd    mm7, mm2            ;wsptr[2,tmp14],[3,tmp14],[xxx],[xxx]
  1344.  
  1345.     punpckldq    mm4, mm7    ;wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14]
  1346.     movq        mm6, mm1
  1347.  
  1348. //    mm0 =     ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
  1349. //    mm1 =    ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
  1350.  
  1351.  
  1352.     movq        mm2, mm0
  1353.     punpckhdq    mm6, mm4    ;wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14]
  1354.  
  1355.     punpckldq    mm1, mm4    ;wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11]
  1356.     psllw        mm6, 2
  1357.  
  1358.     pmulhw        mm6, fix_141
  1359.     punpckldq    mm0, mm3    ;wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10]
  1360.  
  1361.     punpckhdq    mm2, mm3    ;wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13]
  1362.     movq        mm7, mm0
  1363.  
  1364. //    tmp0 = tmp10 + tmp13;
  1365. //    tmp3 = tmp10 - tmp13;
  1366.     paddw        mm0, mm2    ;[0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0]
  1367.     psubw        mm7, mm2    ;[0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3]
  1368.  
  1369. //    tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13;
  1370.     psubw        mm6, mm2    ;wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12]
  1371. //    tmp1 = tmp11 + tmp12;
  1372. //    tmp2 = tmp11 - tmp12;
  1373.     movq        mm5, mm1
  1374.  
  1375.  
  1376.  
  1377.     /* Odd part */
  1378.  
  1379. //    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
  1380. //    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
  1381. //    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
  1382. //    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
  1383.     movq        mm3, [esi+8*0]        ;wsptr[0,0],[0,1],[0,2],[0,3]
  1384.     paddw        mm1, mm6    ;[0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1]
  1385.  
  1386.     movq        mm4, [esi+8*1]        ;wsptr[0,4],[0,5],[0,6],[0,7]
  1387.     psubw        mm5, mm6    ;[0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2]
  1388.  
  1389.     movq        mm6, mm3
  1390.     punpckldq    mm3, mm4            ;wsptr[0,0],[0,1],[0,4],[0,5]
  1391.  
  1392.     punpckhdq    mm4, mm6            ;wsptr[0,6],[0,7],[0,2],[0,3]
  1393.     movq        mm2, mm3
  1394.  
  1395. //Save tmp0 and tmp1 in wsptr
  1396.     movq        [esi+8*0], mm0        ;save tmp0
  1397.     paddw        mm2, mm4            ;wsptr[xxx],[0,z11],[xxx],[0,z13]
  1398.  
  1399.     
  1400. //Continue with z10 --- z13
  1401.     movq        mm6, [esi+8*2]        ;wsptr[1,0],[1,1],[1,2],[1,3]
  1402.     psubw        mm3, mm4            ;wsptr[xxx],[0,z12],[xxx],[0,z10]
  1403.  
  1404.     movq        mm0, [esi+8*3]        ;wsptr[1,4],[1,5],[1,6],[1,7]
  1405.     movq        mm4, mm6
  1406.  
  1407.     movq        [esi+8*1], mm1        ;save tmp1
  1408.     punpckldq    mm6, mm0            ;wsptr[1,0],[1,1],[1,4],[1,5]
  1409.  
  1410.     punpckhdq    mm0, mm4            ;wsptr[1,6],[1,7],[1,2],[1,3]
  1411.     movq        mm1, mm6
  1412.     
  1413. //Save tmp2 and tmp3 in wsptr
  1414.     paddw        mm6, mm0        ;wsptr[xxx],[1,z11],[xxx],[1,z13]
  1415.     movq        mm4, mm2
  1416.     
  1417. //Continue with z10 --- z13
  1418.     movq        [esi+8*2], mm5        ;save tmp2
  1419.     punpcklwd    mm2, mm6        ;wsptr[xxx],[xxx],[0,z11],[1,z11]
  1420.  
  1421.     psubw        mm1, mm0        ;wsptr[xxx],[1,z12],[xxx],[1,z10]
  1422.     punpckhwd    mm4, mm6        ;wsptr[xxx],[xxx],[0,z13],[1,z13]
  1423.  
  1424.     movq        mm0, mm3
  1425.     punpcklwd    mm3, mm1        ;wsptr[xxx],[xxx],[0,z12],[1,z12]
  1426.  
  1427.     movq        [esi+8*3], mm7        ;save tmp3
  1428.     punpckhwd    mm0, mm1        ;wsptr[xxx],[xxx],[0,z10],[1,z10]
  1429.  
  1430.     movq        mm6, [esi+8*4]        ;wsptr[2,0],[2,1],[2,2],[2,3]
  1431.     punpckhdq    mm0, mm2        ;wsptr[0,z10],[1,z10],[0,z11],[1,z11]
  1432.  
  1433.     movq        mm7, [esi+8*5]        ;wsptr[2,4],[2,5],[2,6],[2,7]
  1434.     punpckhdq    mm3, mm4        ;wsptr[0,z12],[1,z12],[0,z13],[1,z13]
  1435.  
  1436.     movq        mm1, [esi+8*6]        ;wsptr[3,0],[3,1],[3,2],[3,3]
  1437.     movq        mm4, mm6
  1438.  
  1439.     punpckldq    mm6, mm7            ;wsptr[2,0],[2,1],[2,4],[2,5]
  1440.     movq        mm5, mm1
  1441.  
  1442.     punpckhdq    mm7, mm4            ;wsptr[2,6],[2,7],[2,2],[2,3]
  1443.     movq        mm2, mm6
  1444.     
  1445.     movq        mm4, [esi+8*7]        ;wsptr[3,4],[3,5],[3,6],[3,7]
  1446.     paddw        mm6, mm7        ;wsptr[xxx],[2,z11],[xxx],[2,z13]
  1447.  
  1448.     psubw        mm2, mm7        ;wsptr[xxx],[2,z12],[xxx],[2,z10]
  1449.     punpckldq    mm1, mm4            ;wsptr[3,0],[3,1],[3,4],[3,5]
  1450.  
  1451.     punpckhdq    mm4, mm5            ;wsptr[3,6],[3,7],[3,2],[3,3]
  1452.     movq        mm7, mm1
  1453.  
  1454.     paddw        mm1, mm4        ;wsptr[xxx],[3,z11],[xxx],[3,z13]
  1455.     psubw        mm7, mm4        ;wsptr[xxx],[3,z12],[xxx],[3,z10]
  1456.  
  1457.     movq        mm5, mm6
  1458.     punpcklwd    mm6, mm1        ;wsptr[xxx],[xxx],[2,z11],[3,z11]
  1459.  
  1460.     punpckhwd    mm5, mm1        ;wsptr[xxx],[xxx],[2,z13],[3,z13]
  1461.     movq        mm4, mm2
  1462.  
  1463.     punpcklwd    mm2, mm7        ;wsptr[xxx],[xxx],[2,z12],[3,z12]
  1464.  
  1465.     punpckhwd    mm4, mm7        ;wsptr[xxx],[xxx],[2,z10],[3,z10]
  1466.  
  1467.     punpckhdq    mm4, mm6        ;wsptr[2,z10],[3,z10],[2,z11],[3,z11]
  1468.  
  1469.     punpckhdq    mm2, mm5        ;wsptr[2,z12],[3,z12],[2,z13],[3,z13]
  1470.     movq        mm5, mm0
  1471.  
  1472.     punpckldq    mm0, mm4        ;wsptr[0,z10],[1,z10],[2,z10],[3,z10]
  1473.  
  1474.     punpckhdq    mm5, mm4        ;wsptr[0,z11],[1,z11],[2,z11],[3,z11]
  1475.     movq        mm4, mm3
  1476.  
  1477.     punpckhdq    mm4, mm2        ;wsptr[0,z13],[1,z13],[2,z13],[3,z13]
  1478.     movq        mm1, mm5
  1479.  
  1480.     punpckldq    mm3, mm2        ;wsptr[0,z12],[1,z12],[2,z12],[3,z12]
  1481. //    tmp7 = z11 + z13;        /* phase 5 */
  1482. //    tmp8 = z11 - z13;        /* phase 5 */
  1483.     psubw        mm1, mm4        ;tmp8
  1484.  
  1485.     paddw        mm5, mm4        ;tmp7
  1486. //    tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */
  1487.     psllw        mm1, 2
  1488.  
  1489.     psllw        mm0, 2
  1490.  
  1491.     pmulhw        mm1, fix_141    ;tmp21
  1492. //    tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065))  /* 2*(c2-c6) */
  1493. //            + MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */
  1494.     psllw        mm3, 2
  1495.     movq        mm7, mm0
  1496.  
  1497.     pmulhw        mm7, fix_n184
  1498.     movq        mm6, mm3
  1499.  
  1500.     movq        mm2, [esi+8*0]    ;tmp0,final1
  1501.  
  1502.     pmulhw        mm6, fix_108n184
  1503. //     tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */
  1504. //            + MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */
  1505.     movq        mm4, mm2        ;final1
  1506.   
  1507.     pmulhw        mm0, fix_184n261
  1508.     paddw        mm2, mm5        ;tmp0+tmp7,final1
  1509.  
  1510.     pmulhw        mm3, fix_184
  1511.     psubw        mm4, mm5        ;tmp0-tmp7,final1
  1512.  
  1513. //    tmp6 = tmp22 - tmp7;    /* phase 2 */
  1514.     psraw        mm2, 5            ;outptr[0,0],[1,0],[2,0],[3,0],final1
  1515.  
  1516.     paddsw        mm2, const_0x0080    ;final1
  1517.     paddw        mm7, mm6            ;tmp20
  1518.     psraw        mm4, 5            ;outptr[0,7],[1,7],[2,7],[3,7],final1
  1519.  
  1520.     paddsw        mm4, const_0x0080    ;final1
  1521.     paddw        mm3, mm0            ;tmp22
  1522.  
  1523. //    tmp5 = tmp21 - tmp6;
  1524.     psubw        mm3, mm5        ;tmp6
  1525.  
  1526. //    tmp4 = tmp20 + tmp5;
  1527.     movq        mm0, [esi+8*1]        ;tmp1,final2
  1528.     psubw        mm1, mm3        ;tmp5
  1529.  
  1530.     movq        mm6, mm0            ;final2
  1531.     paddw        mm0, mm3        ;tmp1+tmp6,final2
  1532.  
  1533.     /* Final output stage: scale down by a factor of 8 and range-limit */
  1534.  
  1535.  
  1536. //    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
  1537. //                & RANGE_MASK];
  1538. //    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
  1539. //                & RANGE_MASK];    final1
  1540.  
  1541.  
  1542. //    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
  1543. //                & RANGE_MASK];
  1544. //    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
  1545. //                & RANGE_MASK];    final2
  1546.     psubw        mm6, mm3        ;tmp1-tmp6,final2
  1547.     psraw        mm0, 5            ;outptr[0,1],[1,1],[2,1],[3,1]
  1548.  
  1549.     paddsw        mm0, const_0x0080
  1550.     psraw        mm6, 5            ;outptr[0,6],[1,6],[2,6],[3,6]
  1551.     
  1552.     paddsw        mm6, const_0x0080        ;need to check this value
  1553.     packuswb    mm0, mm4    ;out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7]
  1554.     
  1555.     movq        mm5, [esi+8*2]        ;tmp2,final3
  1556.     packuswb    mm2, mm6    ;out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6]
  1557.  
  1558. //    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
  1559. //                & RANGE_MASK];
  1560. //    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
  1561. //                & RANGE_MASK];    final3
  1562.     paddw        mm7, mm1        ;tmp4
  1563.     movq        mm3, mm5
  1564.  
  1565.     paddw        mm5, mm1        ;tmp2+tmp5
  1566.     psubw        mm3, mm1        ;tmp2-tmp5
  1567.  
  1568.     psraw        mm5, 5            ;outptr[0,2],[1,2],[2,2],[3,2]
  1569.  
  1570.     paddsw        mm5, const_0x0080
  1571.     movq        mm4, [esi+8*3]        ;tmp3,final4
  1572.     psraw        mm3, 5            ;outptr[0,5],[1,5],[2,5],[3,5]
  1573.  
  1574.     paddsw        mm3, const_0x0080
  1575.  
  1576.  
  1577. //    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
  1578. //                & RANGE_MASK];
  1579. //    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
  1580. //                & RANGE_MASK];    final4
  1581.     movq        mm6, mm4
  1582.     paddw        mm4, mm7        ;tmp3+tmp4
  1583.  
  1584.     psubw        mm6, mm7        ;tmp3-tmp4
  1585.     psraw        mm4, 5            ;outptr[0,4],[1,4],[2,4],[3,4]
  1586.     mov            ecx, [eax]
  1587.  
  1588.     paddsw        mm4, const_0x0080
  1589.     psraw        mm6, 5            ;outptr[0,3],[1,3],[2,3],[3,3]
  1590.  
  1591.     paddsw        mm6, const_0x0080
  1592.     packuswb    mm5, mm4    ;out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4]
  1593.  
  1594.     packuswb    mm6, mm3    ;out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5]
  1595.     movq        mm4, mm2
  1596.  
  1597.     movq        mm7, mm5
  1598.     punpcklbw    mm2, mm0    ;out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1]
  1599.  
  1600.     punpckhbw    mm4, mm0    ;out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7]
  1601.     movq        mm1, mm2
  1602.  
  1603.     punpcklbw    mm5, mm6    ;out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]
  1604.     add             eax, 4
  1605.  
  1606.     punpckhbw    mm7, mm6    ;out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]
  1607.  
  1608.     punpcklwd    mm2, mm5    ;out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]
  1609.     add            ecx, output_col
  1610.  
  1611.     movq        mm6, mm7
  1612.     punpckhwd    mm1, mm5    ;out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]
  1613.  
  1614.     movq        mm0, mm2
  1615.     punpcklwd    mm6, mm4    ;out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7]
  1616.  
  1617.     mov            ebx, [eax]
  1618.     punpckldq    mm2, mm6    ;out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]
  1619.  
  1620.     add             eax, 4
  1621.     movq        mm3, mm1
  1622.  
  1623.     add            ebx, output_col 
  1624.     punpckhwd    mm7, mm4    ;out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7]
  1625.     
  1626.     movq        [ecx], mm2
  1627.     punpckhdq    mm0, mm6    ;out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]
  1628.  
  1629.     mov            ecx, [eax]
  1630.     add             eax, 4
  1631.     add            ecx, output_col
  1632.  
  1633.     movq        [ebx], mm0
  1634.     punpckldq    mm1, mm7    ;out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7]
  1635.  
  1636.     mov            ebx, [eax]
  1637.  
  1638.     add            ebx, output_col
  1639.     punpckhdq    mm3, mm7    ;out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7]
  1640.     movq        [ecx], mm1
  1641.  
  1642.     movq        [ebx], mm3
  1643.  
  1644.     emms
  1645.     }
  1646. }
  1647. #endif
  1648.  
  1649.  
  1650. #endif /* DCT_IFAST_SUPPORTED */
  1651.  
  1652.