simple_idct.c
上传用户:shlianrong
上传日期:2022-07-08
资源大小:309k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * Simple IDCT
  3.  *
  4.  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22. /**
  23.  * @file simple_idct.c
  24.  * simpleidct in C.
  25.  */
  26. /*
  27.   based upon some outcommented c code from mpeg2dec (idct_mmx.c
  28.   written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>)
  29.  */
  30. #include "dsputil.h"
  31. //#include "internal.h"
  32. //#include "integer.h"
  33. #include "mathops.h"
  34. //#include "simple_idct.h"
  35. #if 0
  36. #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
  37. #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
  38. #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
  39. #define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
  40. #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
  41. #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
  42. #define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
  43. #define ROW_SHIFT 8
  44. #define COL_SHIFT 17
  45. #else
  46. #define W1  22725  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  47. #define W2  21407  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  48. #define W3  19266  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  49. #define W4  16383  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  50. #define W5  12873  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  51. #define W6  8867   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  52. #define W7  4520   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
  53. #define ROW_SHIFT 11
  54. #define COL_SHIFT 20 // 6
  55. #endif
  56. static inline void idctRowCondDC (DCTELEM * row)
  57. {
  58.         int a0, a1, a2, a3, b0, b1, b2, b3;
  59. #ifdef HAVE_FAST_64BIT
  60.         uint64_t temp;
  61. #else
  62.         uint32_t temp;
  63. #endif
  64. #ifdef HAVE_FAST_64BIT
  65. #ifdef WORDS_BIGENDIAN
  66. #define ROW0_MASK 0xffff000000000000LL
  67. #else
  68. #define ROW0_MASK 0xffffLL
  69. #endif
  70.         if(sizeof(DCTELEM)==2){
  71.             if ( ((((uint64_t *)row)[0] & ~ROW0_MASK) |
  72.                   ((uint64_t *)row)[1]) == 0) {
  73.                 temp = (row[0] << 3) & 0xffff;
  74.                 temp += temp << 16;
  75.                 temp += temp << 32;
  76.                 ((uint64_t *)row)[0] = temp;
  77.                 ((uint64_t *)row)[1] = temp;
  78.                 return;
  79.             }
  80.         }else{
  81.             if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) {
  82.                 row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3;
  83.                 return;
  84.             }
  85.         }
  86. #else
  87.         if(sizeof(DCTELEM)==2){
  88.             if (!(((uint32_t*)row)[1] |
  89.                   ((uint32_t*)row)[2] |
  90.                   ((uint32_t*)row)[3] |
  91.                   row[1])) {
  92.                 temp = (row[0] << 3) & 0xffff;
  93.                 temp += temp << 16;
  94.                 ((uint32_t*)row)[0]=((uint32_t*)row)[1] =
  95.                 ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp;
  96.                 return;
  97.             }
  98.         }else{
  99.             if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) {
  100.                 row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3;
  101.                 return;
  102.             }
  103.         }
  104. #endif
  105.         a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
  106.         a1 = a0;
  107.         a2 = a0;
  108.         a3 = a0;
  109.         /* no need to optimize : gcc does it */
  110.         a0 += W2 * row[2];
  111.         a1 += W6 * row[2];
  112.         a2 -= W6 * row[2];
  113.         a3 -= W2 * row[2];
  114.         b0 = MUL16(W1, row[1]);
  115.         MAC16(b0, W3, row[3]);
  116.         b1 = MUL16(W3, row[1]);
  117.         MAC16(b1, -W7, row[3]);
  118.         b2 = MUL16(W5, row[1]);
  119.         MAC16(b2, -W1, row[3]);
  120.         b3 = MUL16(W7, row[1]);
  121.         MAC16(b3, -W5, row[3]);
  122. #ifdef HAVE_FAST_64BIT
  123.         temp = ((uint64_t*)row)[1];
  124. #else
  125.         temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3];
  126. #endif
  127.         if (temp != 0) {
  128.             a0 += W4*row[4] + W6*row[6];
  129.             a1 += - W4*row[4] - W2*row[6];
  130.             a2 += - W4*row[4] + W2*row[6];
  131.             a3 += W4*row[4] - W6*row[6];
  132.             MAC16(b0, W5, row[5]);
  133.             MAC16(b0, W7, row[7]);
  134.             MAC16(b1, -W1, row[5]);
  135.             MAC16(b1, -W5, row[7]);
  136.             MAC16(b2, W7, row[5]);
  137.             MAC16(b2, W3, row[7]);
  138.             MAC16(b3, W3, row[5]);
  139.             MAC16(b3, -W1, row[7]);
  140.         }
  141.         row[0] = (a0 + b0) >> ROW_SHIFT;
  142.         row[7] = (a0 - b0) >> ROW_SHIFT;
  143.         row[1] = (a1 + b1) >> ROW_SHIFT;
  144.         row[6] = (a1 - b1) >> ROW_SHIFT;
  145.         row[2] = (a2 + b2) >> ROW_SHIFT;
  146.         row[5] = (a2 - b2) >> ROW_SHIFT;
  147.         row[3] = (a3 + b3) >> ROW_SHIFT;
  148.         row[4] = (a3 - b3) >> ROW_SHIFT;
  149. }
  150. static inline void idctSparseColPut (uint8_t *dest, int line_size,
  151.                                      DCTELEM * col)
  152. {
  153.         int a0, a1, a2, a3, b0, b1, b2, b3;
  154.         uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  155.         /* XXX: I did that only to give same values as previous code */
  156.         a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
  157.         a1 = a0;
  158.         a2 = a0;
  159.         a3 = a0;
  160.         a0 +=  + W2*col[8*2];
  161.         a1 +=  + W6*col[8*2];
  162.         a2 +=  - W6*col[8*2];
  163.         a3 +=  - W2*col[8*2];
  164.         b0 = MUL16(W1, col[8*1]);
  165.         b1 = MUL16(W3, col[8*1]);
  166.         b2 = MUL16(W5, col[8*1]);
  167.         b3 = MUL16(W7, col[8*1]);
  168.         MAC16(b0, + W3, col[8*3]);
  169.         MAC16(b1, - W7, col[8*3]);
  170.         MAC16(b2, - W1, col[8*3]);
  171.         MAC16(b3, - W5, col[8*3]);
  172.         if(col[8*4]){
  173.             a0 += + W4*col[8*4];
  174.             a1 += - W4*col[8*4];
  175.             a2 += - W4*col[8*4];
  176.             a3 += + W4*col[8*4];
  177.         }
  178.         if (col[8*5]) {
  179.             MAC16(b0, + W5, col[8*5]);
  180.             MAC16(b1, - W1, col[8*5]);
  181.             MAC16(b2, + W7, col[8*5]);
  182.             MAC16(b3, + W3, col[8*5]);
  183.         }
  184.         if(col[8*6]){
  185.             a0 += + W6*col[8*6];
  186.             a1 += - W2*col[8*6];
  187.             a2 += + W2*col[8*6];
  188.             a3 += - W6*col[8*6];
  189.         }
  190.         if (col[8*7]) {
  191.             MAC16(b0, + W7, col[8*7]);
  192.             MAC16(b1, - W5, col[8*7]);
  193.             MAC16(b2, + W3, col[8*7]);
  194.             MAC16(b3, - W1, col[8*7]);
  195.         }
  196.         dest[0] = cm[(a0 + b0) >> COL_SHIFT];
  197.         dest += line_size;
  198.         dest[0] = cm[(a1 + b1) >> COL_SHIFT];
  199.         dest += line_size;
  200.         dest[0] = cm[(a2 + b2) >> COL_SHIFT];
  201.         dest += line_size;
  202.         dest[0] = cm[(a3 + b3) >> COL_SHIFT];
  203.         dest += line_size;
  204.         dest[0] = cm[(a3 - b3) >> COL_SHIFT];
  205.         dest += line_size;
  206.         dest[0] = cm[(a2 - b2) >> COL_SHIFT];
  207.         dest += line_size;
  208.         dest[0] = cm[(a1 - b1) >> COL_SHIFT];
  209.         dest += line_size;
  210.         dest[0] = cm[(a0 - b0) >> COL_SHIFT];
  211. }
  212. static inline void idctSparseColAdd (uint8_t *dest, int line_size,
  213.                                      DCTELEM * col)
  214. {
  215.         int a0, a1, a2, a3, b0, b1, b2, b3;
  216.         uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  217.         /* XXX: I did that only to give same values as previous code */
  218.         a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
  219.         a1 = a0;
  220.         a2 = a0;
  221.         a3 = a0;
  222.         a0 +=  + W2*col[8*2];
  223.         a1 +=  + W6*col[8*2];
  224.         a2 +=  - W6*col[8*2];
  225.         a3 +=  - W2*col[8*2];
  226.         b0 = MUL16(W1, col[8*1]);
  227.         b1 = MUL16(W3, col[8*1]);
  228.         b2 = MUL16(W5, col[8*1]);
  229.         b3 = MUL16(W7, col[8*1]);
  230.         MAC16(b0, + W3, col[8*3]);
  231.         MAC16(b1, - W7, col[8*3]);
  232.         MAC16(b2, - W1, col[8*3]);
  233.         MAC16(b3, - W5, col[8*3]);
  234.         if(col[8*4]){
  235.             a0 += + W4*col[8*4];
  236.             a1 += - W4*col[8*4];
  237.             a2 += - W4*col[8*4];
  238.             a3 += + W4*col[8*4];
  239.         }
  240.         if (col[8*5]) {
  241.             MAC16(b0, + W5, col[8*5]);
  242.             MAC16(b1, - W1, col[8*5]);
  243.             MAC16(b2, + W7, col[8*5]);
  244.             MAC16(b3, + W3, col[8*5]);
  245.         }
  246.         if(col[8*6]){
  247.             a0 += + W6*col[8*6];
  248.             a1 += - W2*col[8*6];
  249.             a2 += + W2*col[8*6];
  250.             a3 += - W6*col[8*6];
  251.         }
  252.         if (col[8*7]) {
  253.             MAC16(b0, + W7, col[8*7]);
  254.             MAC16(b1, - W5, col[8*7]);
  255.             MAC16(b2, + W3, col[8*7]);
  256.             MAC16(b3, - W1, col[8*7]);
  257.         }
  258.         dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)];
  259.         dest += line_size;
  260.         dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)];
  261.         dest += line_size;
  262.         dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)];
  263.         dest += line_size;
  264.         dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)];
  265.         dest += line_size;
  266.         dest[0] = cm[dest[0] + ((a3 - b3) >> COL_SHIFT)];
  267.         dest += line_size;
  268.         dest[0] = cm[dest[0] + ((a2 - b2) >> COL_SHIFT)];
  269.         dest += line_size;
  270.         dest[0] = cm[dest[0] + ((a1 - b1) >> COL_SHIFT)];
  271.         dest += line_size;
  272.         dest[0] = cm[dest[0] + ((a0 - b0) >> COL_SHIFT)];
  273. }
  274. static inline void idctSparseCol (DCTELEM * col)
  275. {
  276.         int a0, a1, a2, a3, b0, b1, b2, b3;
  277.         /* XXX: I did that only to give same values as previous code */
  278.         a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
  279.         a1 = a0;
  280.         a2 = a0;
  281.         a3 = a0;
  282.         a0 +=  + W2*col[8*2];
  283.         a1 +=  + W6*col[8*2];
  284.         a2 +=  - W6*col[8*2];
  285.         a3 +=  - W2*col[8*2];
  286.         b0 = MUL16(W1, col[8*1]);
  287.         b1 = MUL16(W3, col[8*1]);
  288.         b2 = MUL16(W5, col[8*1]);
  289.         b3 = MUL16(W7, col[8*1]);
  290.         MAC16(b0, + W3, col[8*3]);
  291.         MAC16(b1, - W7, col[8*3]);
  292.         MAC16(b2, - W1, col[8*3]);
  293.         MAC16(b3, - W5, col[8*3]);
  294.         if(col[8*4]){
  295.             a0 += + W4*col[8*4];
  296.             a1 += - W4*col[8*4];
  297.             a2 += - W4*col[8*4];
  298.             a3 += + W4*col[8*4];
  299.         }
  300.         if (col[8*5]) {
  301.             MAC16(b0, + W5, col[8*5]);
  302.             MAC16(b1, - W1, col[8*5]);
  303.             MAC16(b2, + W7, col[8*5]);
  304.             MAC16(b3, + W3, col[8*5]);
  305.         }
  306.         if(col[8*6]){
  307.             a0 += + W6*col[8*6];
  308.             a1 += - W2*col[8*6];
  309.             a2 += + W2*col[8*6];
  310.             a3 += - W6*col[8*6];
  311.         }
  312.         if (col[8*7]) {
  313.             MAC16(b0, + W7, col[8*7]);
  314.             MAC16(b1, - W5, col[8*7]);
  315.             MAC16(b2, + W3, col[8*7]);
  316.             MAC16(b3, - W1, col[8*7]);
  317.         }
  318.         col[0 ] = ((a0 + b0) >> COL_SHIFT);
  319.         col[8 ] = ((a1 + b1) >> COL_SHIFT);
  320.         col[16] = ((a2 + b2) >> COL_SHIFT);
  321.         col[24] = ((a3 + b3) >> COL_SHIFT);
  322.         col[32] = ((a3 - b3) >> COL_SHIFT);
  323.         col[40] = ((a2 - b2) >> COL_SHIFT);
  324.         col[48] = ((a1 - b1) >> COL_SHIFT);
  325.         col[56] = ((a0 - b0) >> COL_SHIFT);
  326. }
  327. void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block)
  328. {
  329.     int i;
  330.     for(i=0; i<8; i++)
  331.         idctRowCondDC(block + i*8);
  332.     for(i=0; i<8; i++)
  333.         idctSparseColPut(dest + i, line_size, block + i);
  334. }
  335. void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block)
  336. {
  337.     int i;
  338.     for(i=0; i<8; i++)
  339.         idctRowCondDC(block + i*8);
  340.     for(i=0; i<8; i++)
  341.         idctSparseColAdd(dest + i, line_size, block + i);
  342. }
  343. void ff_simple_idct(DCTELEM *block)
  344. {
  345.     int i;
  346.     for(i=0; i<8; i++)
  347.         idctRowCondDC(block + i*8);
  348.     for(i=0; i<8; i++)
  349.         idctSparseCol(block + i);
  350. }
  351. /* 2x4x8 idct */
  352. #define CN_SHIFT 12
  353. #define C_FIX(x) ((int)((x) * (1 << CN_SHIFT) + 0.5))
  354. #define C1 C_FIX(0.6532814824)
  355. #define C2 C_FIX(0.2705980501)
  356. /* row idct is multiple by 16 * sqrt(2.0), col idct4 is normalized,
  357.    and the butterfly must be multiplied by 0.5 * sqrt(2.0) */
  358. #define C_SHIFT (4+1+12)
  359. static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col)
  360. {
  361.     int c0, c1, c2, c3, a0, a1, a2, a3;
  362.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  363.     a0 = col[8*0];
  364.     a1 = col[8*2];
  365.     a2 = col[8*4];
  366.     a3 = col[8*6];
  367.     c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
  368.     c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
  369.     c1 = a1 * C1 + a3 * C2;
  370.     c3 = a1 * C2 - a3 * C1;
  371.     dest[0] = cm[(c0 + c1) >> C_SHIFT];
  372.     dest += line_size;
  373.     dest[0] = cm[(c2 + c3) >> C_SHIFT];
  374.     dest += line_size;
  375.     dest[0] = cm[(c2 - c3) >> C_SHIFT];
  376.     dest += line_size;
  377.     dest[0] = cm[(c0 - c1) >> C_SHIFT];
  378. }
  379. #define BF(k) 
  380. {
  381.     int a0, a1;
  382.     a0 = ptr[k];
  383.     a1 = ptr[8 + k];
  384.     ptr[k] = a0 + a1;
  385.     ptr[8 + k] = a0 - a1;
  386. }
  387. /* only used by DV codec. The input must be interlaced. 128 is added
  388.    to the pixels before clamping to avoid systematic error
  389.    (1024*sqrt(2)) offset would be needed otherwise. */
  390. /* XXX: I think a 1.0/sqrt(2) normalization should be needed to
  391.    compensate the extra butterfly stage - I don't have the full DV
  392.    specification */
  393. void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
  394. {
  395.     int i;
  396.     DCTELEM *ptr;
  397.     /* butterfly */
  398.     ptr = block;
  399.     for(i=0;i<4;i++) {
  400.         BF(0);
  401.         BF(1);
  402.         BF(2);
  403.         BF(3);
  404.         BF(4);
  405.         BF(5);
  406.         BF(6);
  407.         BF(7);
  408.         ptr += 2 * 8;
  409.     }
  410.     /* IDCT8 on each line */
  411.     for(i=0; i<8; i++) {
  412.         idctRowCondDC(block + i*8);
  413.     }
  414.     /* IDCT4 and store */
  415.     for(i=0;i<8;i++) {
  416.         idct4col_put(dest + i, 2 * line_size, block + i);
  417.         idct4col_put(dest + line_size + i, 2 * line_size, block + 8 + i);
  418.     }
  419. }
  420. /* 8x4 & 4x8 WMV2 IDCT */
  421. #undef CN_SHIFT
  422. #undef C_SHIFT
  423. #undef C_FIX
  424. #undef C1
  425. #undef C2
  426. #define CN_SHIFT 12
  427. #define C_FIX(x) ((int)((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5))
  428. #define C1 C_FIX(0.6532814824)
  429. #define C2 C_FIX(0.2705980501)
  430. #define C3 C_FIX(0.5)
  431. #define C_SHIFT (4+1+12)
  432. static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col)
  433. {
  434.     int c0, c1, c2, c3, a0, a1, a2, a3;
  435.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  436.     a0 = col[8*0];
  437.     a1 = col[8*1];
  438.     a2 = col[8*2];
  439.     a3 = col[8*3];
  440.     c0 = (a0 + a2)*C3 + (1 << (C_SHIFT - 1));
  441.     c2 = (a0 - a2)*C3 + (1 << (C_SHIFT - 1));
  442.     c1 = a1 * C1 + a3 * C2;
  443.     c3 = a1 * C2 - a3 * C1;
  444.     dest[0] = cm[dest[0] + ((c0 + c1) >> C_SHIFT)];
  445.     dest += line_size;
  446.     dest[0] = cm[dest[0] + ((c2 + c3) >> C_SHIFT)];
  447.     dest += line_size;
  448.     dest[0] = cm[dest[0] + ((c2 - c3) >> C_SHIFT)];
  449.     dest += line_size;
  450.     dest[0] = cm[dest[0] + ((c0 - c1) >> C_SHIFT)];
  451. }
  452. #define RN_SHIFT 15
  453. #define R_FIX(x) ((int)((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5))
  454. #define R1 R_FIX(0.6532814824)
  455. #define R2 R_FIX(0.2705980501)
  456. #define R3 R_FIX(0.5)
  457. #define R_SHIFT 11
  458. static inline void idct4row(DCTELEM *row)
  459. {
  460.     int c0, c1, c2, c3, a0, a1, a2, a3;
  461.     //const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  462.     a0 = row[0];
  463.     a1 = row[1];
  464.     a2 = row[2];
  465.     a3 = row[3];
  466.     c0 = (a0 + a2)*R3 + (1 << (R_SHIFT - 1));
  467.     c2 = (a0 - a2)*R3 + (1 << (R_SHIFT - 1));
  468.     c1 = a1 * R1 + a3 * R2;
  469.     c3 = a1 * R2 - a3 * R1;
  470.     row[0]= (c0 + c1) >> R_SHIFT;
  471.     row[1]= (c2 + c3) >> R_SHIFT;
  472.     row[2]= (c2 - c3) >> R_SHIFT;
  473.     row[3]= (c0 - c1) >> R_SHIFT;
  474. }
  475. void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
  476. {
  477.     int i;
  478.     /* IDCT8 on each line */
  479.     for(i=0; i<4; i++) {
  480.         idctRowCondDC(block + i*8);
  481.     }
  482.     /* IDCT4 and store */
  483.     for(i=0;i<8;i++) {
  484.         idct4col_add(dest + i, line_size, block + i);
  485.     }
  486. }
  487. void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
  488. {
  489.     int i;
  490.     /* IDCT4 on each line */
  491.     for(i=0; i<8; i++) {
  492.         idct4row(block + i*8);
  493.     }
  494.     /* IDCT8 and store */
  495.     for(i=0; i<4; i++){
  496.         idctSparseColAdd(dest + i, line_size, block + i);
  497.     }
  498. }
  499. void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
  500. {
  501.     int i;
  502.     /* IDCT4 on each line */
  503.     for(i=0; i<4; i++) {
  504.         idct4row(block + i*8);
  505.     }
  506.     /* IDCT4 and store */
  507.     for(i=0; i<4; i++){
  508.         idct4col_add(dest + i, line_size, block + i);
  509.     }
  510. }