Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
mfwddct.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "all.h"
00019
00020 #include "dct.h"
00021 #include "mtypes.h"
00022 #include "opts.h"
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define EIGHT_BIT_SAMPLES
00047 #ifdef EIGHT_BIT_SAMPLES
00048 #define LG2_DCT_SCALE 16
00049 #else
00050 #define LG2_DCT_SCALE 15
00051 #endif
00052
00053 #define ONE ((int32) 1)
00054
00055 #define DCT_SCALE (ONE << LG2_DCT_SCALE)
00056
00057
00058
00059
00060 #define LG2_OVERSCALE 2
00061 #define OVERSCALE (ONE << LG2_OVERSCALE)
00062 #define OVERSHIFT(x) ((x) <<= LG2_OVERSCALE)
00063
00064
00065 #define FIX(x) ((int32) ((x) * DCT_SCALE + 0.5))
00066
00067
00068
00069
00070 #define FIXO(x) ((int32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
00071
00072
00073 #define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
00074
00075
00076 #define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
00077
00078
00079 #define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)),\
00080 LG2_DCT_SCALE-LG2_OVERSCALE)
00081
00082
00083
00084
00085
00086 #define SIN_1_4 FIX(0.707106781)
00087 #define COS_1_4 SIN_1_4
00088
00089 #define SIN_1_8 FIX(0.382683432)
00090 #define COS_1_8 FIX(0.923879533)
00091 #define SIN_3_8 COS_1_8
00092 #define COS_3_8 SIN_1_8
00093
00094 #define SIN_1_16 FIX(0.195090322)
00095 #define COS_1_16 FIX(0.980785280)
00096 #define SIN_7_16 COS_1_16
00097 #define COS_7_16 SIN_1_16
00098
00099 #define SIN_3_16 FIX(0.555570233)
00100 #define COS_3_16 FIX(0.831469612)
00101 #define SIN_5_16 COS_3_16
00102 #define COS_5_16 SIN_3_16
00103
00104
00105
00106
00107 #define OSIN_1_4 FIXO(0.707106781)
00108 #define OCOS_1_4 OSIN_1_4
00109
00110 #define OSIN_1_8 FIXO(0.382683432)
00111 #define OCOS_1_8 FIXO(0.923879533)
00112 #define OSIN_3_8 OCOS_1_8
00113 #define OCOS_3_8 OSIN_1_8
00114
00115 #define OSIN_1_16 FIXO(0.195090322)
00116 #define OCOS_1_16 FIXO(0.980785280)
00117 #define OSIN_7_16 OCOS_1_16
00118 #define OCOS_7_16 OSIN_1_16
00119
00120 #define OSIN_3_16 FIXO(0.555570233)
00121 #define OCOS_3_16 FIXO(0.831469612)
00122 #define OSIN_5_16 OCOS_3_16
00123 #define OCOS_5_16 OSIN_3_16
00124
00125
00126 void reference_fwd_dct _ANSI_ARGS_((Block block, Block dest));
00127 void mp_fwd_dct_fast _ANSI_ARGS_((Block data2d, Block dest2d));
00128 void init_fdct _ANSI_ARGS_((void));
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 extern boolean pureDCT;
00144 void
00145 mp_fwd_dct_block2(data, dest)
00146 Block data, dest;
00147 {
00148 if (pureDCT) reference_fwd_dct(data, dest);
00149 else mp_fwd_dct_fast(data, dest);
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 void
00170 mp_fwd_dct_fast(data2d, dest2d)
00171 Block data2d, dest2d;
00172 {
00173 int16 *data = (int16 *) data2d;
00174
00175 int16 *dest = (int16 *) dest2d;
00176 int pass, rowctr;
00177 register int16 *inptr, *outptr;
00178 int16 workspace[DCTSIZE_SQ];
00179 SHIFT_TEMPS
00180
00181 #ifdef ndef
00182 {
00183 int y;
00184
00185 printf("fwd_dct (beforehand):\n");
00186 for (y = 0; y < 8; y++)
00187 printf("%4d %4d %4d %4d %4d %4d %4d %4d\n",
00188 data2d[y][0], data2d[y][1],
00189 data2d[y][2], data2d[y][3],
00190 data2d[y][4], data2d[y][5],
00191 data2d[y][6], data2d[y][7]);
00192 }
00193 #endif
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 inptr = data;
00206 outptr = workspace;
00207 for (pass = 1; pass >= 0; pass--) {
00208 for (rowctr = DCTSIZE - 1; rowctr >= 0; rowctr--) {
00209
00210
00211
00212
00213
00214 int32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
00215 int32 tmp10, tmp11, tmp12, tmp13;
00216 int32 tmp14, tmp15, tmp16, tmp17;
00217 int32 tmp25, tmp26;
00218
00219
00220
00221
00222 tmp0 = inptr[7] + inptr[0];
00223 tmp1 = inptr[6] + inptr[1];
00224 tmp2 = inptr[5] + inptr[2];
00225 tmp3 = inptr[4] + inptr[3];
00226 tmp4 = inptr[3] - inptr[4];
00227 tmp5 = inptr[2] - inptr[5];
00228 tmp6 = inptr[1] - inptr[6];
00229 tmp7 = inptr[0] - inptr[7];
00230
00231
00232
00233 tmp10 = tmp3 + tmp0;
00234 tmp11 = tmp2 + tmp1;
00235 tmp12 = tmp1 - tmp2;
00236 tmp13 = tmp0 - tmp3;
00237
00238 outptr[0] = (int16) UNFIXH((tmp10 + tmp11) * SIN_1_4);
00239 outptr[DCTSIZE * 4] = (int16) UNFIXH((tmp10 - tmp11) * COS_1_4);
00240
00241 outptr[DCTSIZE * 2] = (int16) UNFIXH(tmp13 * COS_1_8 + tmp12 * SIN_1_8);
00242 outptr[DCTSIZE * 6] = (int16) UNFIXH(tmp13 * SIN_1_8 - tmp12 * COS_1_8);
00243
00244 tmp16 = UNFIXO((tmp6 + tmp5) * SIN_1_4);
00245 tmp15 = UNFIXO((tmp6 - tmp5) * COS_1_4);
00246
00247 OVERSHIFT(tmp4);
00248 OVERSHIFT(tmp7);
00249
00250
00251
00252
00253
00254
00255 tmp14 = tmp4 + tmp15;
00256 tmp25 = tmp4 - tmp15;
00257 tmp26 = tmp7 - tmp16;
00258 tmp17 = tmp7 + tmp16;
00259
00260 outptr[DCTSIZE] = (int16) UNFIXH(tmp17 * OCOS_1_16 + tmp14 * OSIN_1_16);
00261 outptr[DCTSIZE * 7] = (int16) UNFIXH(tmp17 * OCOS_7_16 - tmp14 * OSIN_7_16);
00262 outptr[DCTSIZE * 5] = (int16) UNFIXH(tmp26 * OCOS_5_16 + tmp25 * OSIN_5_16);
00263 outptr[DCTSIZE * 3] = (int16) UNFIXH(tmp26 * OCOS_3_16 - tmp25 * OSIN_3_16);
00264
00265 inptr += DCTSIZE;
00266 outptr++;
00267 }
00268
00269 inptr = workspace;
00270 outptr = dest;
00271 }
00272 #ifdef ndef
00273 {
00274 int y;
00275
00276 printf("fwd_dct (afterward):\n");
00277 for (y = 0; y < 8; y++)
00278 printf("%4d %4d %4d %4d %4d %4d %4d %4d\n",
00279 dest2d[y][0], dest2d[y][1],
00280 dest2d[y][2], dest2d[y][3],
00281 dest2d[y][4], dest2d[y][5],
00282 dest2d[y][6], dest2d[y][7]);
00283 }
00284 #endif
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 #ifndef PI
00319 #ifdef M_PI
00320 #define PI M_PI
00321 #else
00322 #define PI 3.14159265358979323846
00323 #endif
00324 #endif
00325
00326
00327 static double trans_coef[8][8];
00328
00329 void init_fdct()
00330 {
00331 int i, j;
00332 double s;
00333
00334 for (i=0; i<8; i++)
00335 {
00336 s = (i==0) ? sqrt(0.125) : 0.5;
00337
00338 for (j=0; j<8; j++)
00339 trans_coef[i][j] = s * cos((PI/8.0)*i*(j+0.5));
00340 }
00341 }
00342
00343 void reference_fwd_dct(block, dest)
00344 Block block, dest;
00345 {
00346 int i, j, k;
00347 double s;
00348 double tmp[64];
00349
00350 if (DoLaplace) {
00351 LaplaceNum++;
00352 }
00353
00354 for (i=0; i<8; i++)
00355 for (j=0; j<8; j++)
00356 {
00357 s = 0.0;
00358
00359 for (k=0; k<8; k++)
00360 s += trans_coef[j][k] * block[i][k];
00361
00362 tmp[8*i+j] = s;
00363 }
00364
00365 for (i=0; i<8; i++)
00366 for (j=0; j<8; j++)
00367 {
00368 s = 0.0;
00369
00370 for (k=0; k<8; k++)
00371 s += trans_coef[i][k] * tmp[8*k+j];
00372
00373 if (collect_quant) {
00374 fprintf(collect_quant_fp, "%d %f\n", 8*i+j, s);
00375 }
00376 if (DoLaplace) {
00377 L1[LaplaceCnum][i*8+j] += s*s;
00378 L2[LaplaceCnum][i*8+j] += s;
00379 }
00380
00381
00382 dest[i][j] = (int)floor(s+0.499999);
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 }
00393 }