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
00057 a0 = col[8*0];
00058 a1 = col[8*2];
00059 a2 = col[8*4];
00060 a3 = col[8*6];
00061 c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
00062 c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
00063 c1 = a1 * C1 + a3 * C2;
00064 c3 = a1 * C2 - a3 * C1;
00065 dest[0] = av_clip_uint8((c0 + c1) >> C_SHIFT);
00066 dest += line_size;
00067 dest[0] = av_clip_uint8((c2 + c3) >> C_SHIFT);
00068 dest += line_size;
00069 dest[0] = av_clip_uint8((c2 - c3) >> C_SHIFT);
00070 dest += line_size;
00071 dest[0] = av_clip_uint8((c0 - c1) >> C_SHIFT);
00072 }
00073
00074 #define BF(k) \
00075 {\
00076 int a0, a1;\
00077 a0 = ptr[k];\
00078 a1 = ptr[8 + k];\
00079 ptr[k] = a0 + a1;\
00080 ptr[8 + k] = a0 - a1;\
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
00090 {
00091 int i;
00092 DCTELEM *ptr;
00093
00094
00095 ptr = block;
00096 for(i=0;i<4;i++) {
00097 BF(0);
00098 BF(1);
00099 BF(2);
00100 BF(3);
00101 BF(4);
00102 BF(5);
00103 BF(6);
00104 BF(7);
00105 ptr += 2 * 8;
00106 }
00107
00108
00109 for(i=0; i<8; i++) {
00110 idctRowCondDC_8(block + i*8, 0);
00111 }
00112
00113
00114 for(i=0;i<8;i++) {
00115 idct4col_put(dest + i, 2 * line_size, block + i);
00116 idct4col_put(dest + line_size + i, 2 * line_size, block + 8 + i);
00117 }
00118 }
00119
00120
00121 #undef CN_SHIFT
00122 #undef C_SHIFT
00123 #undef C_FIX
00124 #undef C1
00125 #undef C2
00126 #define CN_SHIFT 12
00127 #define C_FIX(x) ((int)((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5))
00128 #define C1 C_FIX(0.6532814824)
00129 #define C2 C_FIX(0.2705980501)
00130 #define C3 C_FIX(0.5)
00131 #define C_SHIFT (4+1+12)
00132 static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col)
00133 {
00134 int c0, c1, c2, c3, a0, a1, a2, a3;
00135
00136 a0 = col[8*0];
00137 a1 = col[8*1];
00138 a2 = col[8*2];
00139 a3 = col[8*3];
00140 c0 = (a0 + a2)*C3 + (1 << (C_SHIFT - 1));
00141 c2 = (a0 - a2)*C3 + (1 << (C_SHIFT - 1));
00142 c1 = a1 * C1 + a3 * C2;
00143 c3 = a1 * C2 - a3 * C1;
00144 dest[0] = av_clip_uint8(dest[0] + ((c0 + c1) >> C_SHIFT));
00145 dest += line_size;
00146 dest[0] = av_clip_uint8(dest[0] + ((c2 + c3) >> C_SHIFT));
00147 dest += line_size;
00148 dest[0] = av_clip_uint8(dest[0] + ((c2 - c3) >> C_SHIFT));
00149 dest += line_size;
00150 dest[0] = av_clip_uint8(dest[0] + ((c0 - c1) >> C_SHIFT));
00151 }
00152
00153 #define RN_SHIFT 15
00154 #define R_FIX(x) ((int)((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5))
00155 #define R1 R_FIX(0.6532814824)
00156 #define R2 R_FIX(0.2705980501)
00157 #define R3 R_FIX(0.5)
00158 #define R_SHIFT 11
00159 static inline void idct4row(DCTELEM *row)
00160 {
00161 int c0, c1, c2, c3, a0, a1, a2, a3;
00162
00163 a0 = row[0];
00164 a1 = row[1];
00165 a2 = row[2];
00166 a3 = row[3];
00167 c0 = (a0 + a2)*R3 + (1 << (R_SHIFT - 1));
00168 c2 = (a0 - a2)*R3 + (1 << (R_SHIFT - 1));
00169 c1 = a1 * R1 + a3 * R2;
00170 c3 = a1 * R2 - a3 * R1;
00171 row[0]= (c0 + c1) >> R_SHIFT;
00172 row[1]= (c2 + c3) >> R_SHIFT;
00173 row[2]= (c2 - c3) >> R_SHIFT;
00174 row[3]= (c0 - c1) >> R_SHIFT;
00175 }
00176
00177 void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
00178 {
00179 int i;
00180
00181
00182 for(i=0; i<4; i++) {
00183 idctRowCondDC_8(block + i*8, 0);
00184 }
00185
00186
00187 for(i=0;i<8;i++) {
00188 idct4col_add(dest + i, line_size, block + i);
00189 }
00190 }
00191
00192 void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
00193 {
00194 int i;
00195
00196
00197 for(i=0; i<8; i++) {
00198 idct4row(block + i*8);
00199 }
00200
00201
00202 for(i=0; i<4; i++){
00203 idctSparseColAdd_8(dest + i, line_size, block + i);
00204 }
00205 }
00206
00207 void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
00208 {
00209 int i;
00210
00211
00212 for(i=0; i<4; i++) {
00213 idct4row(block + i*8);
00214 }
00215
00216
00217 for(i=0; i<4; i++){
00218 idct4col_add(dest + i, line_size, block + i);
00219 }
00220 }
00221
00222 void ff_prores_idct(DCTELEM *block, const int16_t *qmat)
00223 {
00224 int i;
00225
00226 for (i = 0; i < 64; i++)
00227 block[i] *= qmat[i];
00228
00229 for (i = 0; i < 8; i++)
00230 idctRowCondDC_10(block + i*8, 2);
00231
00232 for (i = 0; i < 8; i++)
00233 idctSparseCol_10(block + i);
00234 }