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 }