00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "libavutil/intreadwrite.h"
00029 #include "avcodec.h"
00030 #include "dsputil.h"
00031 #include "mathops.h"
00032 #include "simple_idct.h"
00033
00034 #define BIT_DEPTH 8
00035 #include "simple_idct_template.c"
00036 #undef BIT_DEPTH
00037
00038 #define BIT_DEPTH 10
00039 #include "simple_idct_template.c"
00040 #undef BIT_DEPTH
00041
00042
00043
00044 #define CN_SHIFT 12
00045 #define C_FIX(x) ((int)((x) * (1 << CN_SHIFT) + 0.5))
00046 #define C1 C_FIX(0.6532814824)
00047 #define C2 C_FIX(0.2705980501)
00048
00049
00050
00051 #define C_SHIFT (4+1+12)
00052
00053 static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col)
00054 {
00055 int c0, c1, c2, c3, a0, a1, a2, a3;
00056 const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00057
00058 a0 = col[8*0];
00059 a1 = col[8*2];
00060 a2 = col[8*4];
00061 a3 = col[8*6];
00062 c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
00063 c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
00064 c1 = a1 * C1 + a3 * C2;
00065 c3 = a1 * C2 - a3 * C1;
00066 dest[0] = cm[(c0 + c1) >> C_SHIFT];
00067 dest += line_size;
00068 dest[0] = cm[(c2 + c3) >> C_SHIFT];
00069 dest += line_size;
00070 dest[0] = cm[(c2 - c3) >> C_SHIFT];
00071 dest += line_size;
00072 dest[0] = cm[(c0 - c1) >> C_SHIFT];
00073 }
00074
00075 #define BF(k) \
00076 {\
00077 int a0, a1;\
00078 a0 = ptr[k];\
00079 a1 = ptr[8 + k];\
00080 ptr[k] = a0 + a1;\
00081 ptr[8 + k] = a0 - a1;\
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
00091 {
00092 int i;
00093 DCTELEM *ptr;
00094
00095
00096 ptr = block;
00097 for(i=0;i<4;i++) {
00098 BF(0);
00099 BF(1);
00100 BF(2);
00101 BF(3);
00102 BF(4);
00103 BF(5);
00104 BF(6);
00105 BF(7);
00106 ptr += 2 * 8;
00107 }
00108
00109
00110 for(i=0; i<8; i++) {
00111 idctRowCondDC_8(block + i*8, 0);
00112 }
00113
00114
00115 for(i=0;i<8;i++) {
00116 idct4col_put(dest + i, 2 * line_size, block + i);
00117 idct4col_put(dest + line_size + i, 2 * line_size, block + 8 + i);
00118 }
00119 }
00120
00121
00122 #undef CN_SHIFT
00123 #undef C_SHIFT
00124 #undef C_FIX
00125 #undef C1
00126 #undef C2
00127 #define CN_SHIFT 12
00128 #define C_FIX(x) ((int)((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5))
00129 #define C1 C_FIX(0.6532814824)
00130 #define C2 C_FIX(0.2705980501)
00131 #define C3 C_FIX(0.5)
00132 #define C_SHIFT (4+1+12)
00133 static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col)
00134 {
00135 int c0, c1, c2, c3, a0, a1, a2, a3;
00136 const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00137
00138 a0 = col[8*0];
00139 a1 = col[8*1];
00140 a2 = col[8*2];
00141 a3 = col[8*3];
00142 c0 = (a0 + a2)*C3 + (1 << (C_SHIFT - 1));
00143 c2 = (a0 - a2)*C3 + (1 << (C_SHIFT - 1));
00144 c1 = a1 * C1 + a3 * C2;
00145 c3 = a1 * C2 - a3 * C1;
00146 dest[0] = cm[dest[0] + ((c0 + c1) >> C_SHIFT)];
00147 dest += line_size;
00148 dest[0] = cm[dest[0] + ((c2 + c3) >> C_SHIFT)];
00149 dest += line_size;
00150 dest[0] = cm[dest[0] + ((c2 - c3) >> C_SHIFT)];
00151 dest += line_size;
00152 dest[0] = cm[dest[0] + ((c0 - c1) >> C_SHIFT)];
00153 }
00154
00155 #define RN_SHIFT 15
00156 #define R_FIX(x) ((int)((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5))
00157 #define R1 R_FIX(0.6532814824)
00158 #define R2 R_FIX(0.2705980501)
00159 #define R3 R_FIX(0.5)
00160 #define R_SHIFT 11
00161 static inline void idct4row(DCTELEM *row)
00162 {
00163 int c0, c1, c2, c3, a0, a1, a2, a3;
00164
00165
00166 a0 = row[0];
00167 a1 = row[1];
00168 a2 = row[2];
00169 a3 = row[3];
00170 c0 = (a0 + a2)*R3 + (1 << (R_SHIFT - 1));
00171 c2 = (a0 - a2)*R3 + (1 << (R_SHIFT - 1));
00172 c1 = a1 * R1 + a3 * R2;
00173 c3 = a1 * R2 - a3 * R1;
00174 row[0]= (c0 + c1) >> R_SHIFT;
00175 row[1]= (c2 + c3) >> R_SHIFT;
00176 row[2]= (c2 - c3) >> R_SHIFT;
00177 row[3]= (c0 - c1) >> R_SHIFT;
00178 }
00179
00180 void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
00181 {
00182 int i;
00183
00184
00185 for(i=0; i<4; i++) {
00186 idctRowCondDC_8(block + i*8, 0);
00187 }
00188
00189
00190 for(i=0;i<8;i++) {
00191 idct4col_add(dest + i, line_size, block + i);
00192 }
00193 }
00194
00195 void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
00196 {
00197 int i;
00198
00199
00200 for(i=0; i<8; i++) {
00201 idct4row(block + i*8);
00202 }
00203
00204
00205 for(i=0; i<4; i++){
00206 idctSparseColAdd_8(dest + i, line_size, block + i);
00207 }
00208 }
00209
00210 void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
00211 {
00212 int i;
00213
00214
00215 for(i=0; i<4; i++) {
00216 idct4row(block + i*8);
00217 }
00218
00219
00220 for(i=0; i<4; i++){
00221 idct4col_add(dest + i, line_size, block + i);
00222 }
00223 }
00224
00225 void ff_prores_idct(DCTELEM *block, const int16_t *qmat)
00226 {
00227 int i;
00228
00229 for (i = 0; i < 64; i++)
00230 block[i] *= qmat[i];
00231
00232 for (i = 0; i < 8; i++)
00233 idctRowCondDC_10(block + i*8, 2);
00234
00235 for (i = 0; i < 8; i++)
00236 idctSparseCol_10(block + i);
00237 }