00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 #define JPEG_INTERNALS
00015 #include "jinclude.h"
00016 #include "jpeglib.h"
00017 #include "jdct.h"               
00018 
00019 
00020 
00021 
00022 typedef struct {
00023   struct jpeg_forward_dct pub;  
00024 
00025   
00026   forward_DCT_method_ptr do_dct;
00027 
00028   
00029 
00030 
00031 
00032   DCTELEM * divisors[NUM_QUANT_TBLS];
00033 
00034 #ifdef DCT_FLOAT_SUPPORTED
00035   
00036   float_DCT_method_ptr do_float_dct;
00037   FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
00038 #endif
00039 } my_fdct_controller;
00040 
00041 typedef my_fdct_controller * my_fdct_ptr;
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 METHODDEF(void)
00054 start_pass_fdctmgr (j_compress_ptr cinfo)
00055 {
00056   my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
00057   int ci, qtblno, i;
00058   jpeg_component_info *compptr;
00059   JQUANT_TBL * qtbl;
00060   DCTELEM * dtbl;
00061 
00062   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00063        ci++, compptr++) {
00064     qtblno = compptr->quant_tbl_no;
00065     
00066     if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
00067         cinfo->quant_tbl_ptrs[qtblno] == NULL)
00068       ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
00069     qtbl = cinfo->quant_tbl_ptrs[qtblno];
00070     
00071     
00072     switch (cinfo->dct_method) {
00073 #ifdef DCT_ISLOW_SUPPORTED
00074     case JDCT_ISLOW:
00075       
00076 
00077 
00078       if (fdct->divisors[qtblno] == NULL) {
00079         fdct->divisors[qtblno] = (DCTELEM *)
00080           (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00081                                       DCTSIZE2 * SIZEOF(DCTELEM));
00082       }
00083       dtbl = fdct->divisors[qtblno];
00084       for (i = 0; i < DCTSIZE2; i++) {
00085         dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
00086       }
00087       break;
00088 #endif
00089 #ifdef DCT_IFAST_SUPPORTED
00090     case JDCT_IFAST:
00091       {
00092         
00093 
00094 
00095 
00096 
00097 
00098 #define CONST_BITS 14
00099         static const INT16 aanscales[DCTSIZE2] = {
00100           
00101           16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
00102           22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
00103           21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
00104           19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
00105           16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
00106           12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
00107            8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
00108            4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
00109         };
00110         SHIFT_TEMPS
00111 
00112         if (fdct->divisors[qtblno] == NULL) {
00113           fdct->divisors[qtblno] = (DCTELEM *)
00114             (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00115                                         DCTSIZE2 * SIZEOF(DCTELEM));
00116         }
00117         dtbl = fdct->divisors[qtblno];
00118         for (i = 0; i < DCTSIZE2; i++) {
00119           dtbl[i] = (DCTELEM)
00120             DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
00121                                   (INT32) aanscales[i]),
00122                     CONST_BITS-3);
00123         }
00124       }
00125       break;
00126 #endif
00127 #ifdef DCT_FLOAT_SUPPORTED
00128     case JDCT_FLOAT:
00129       {
00130         
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138         FAST_FLOAT * fdtbl;
00139         int row, col;
00140         static const double aanscalefactor[DCTSIZE] = {
00141           1.0, 1.387039845, 1.306562965, 1.175875602,
00142           1.0, 0.785694958, 0.541196100, 0.275899379
00143         };
00144 
00145         if (fdct->float_divisors[qtblno] == NULL) {
00146           fdct->float_divisors[qtblno] = (FAST_FLOAT *)
00147             (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00148                                         DCTSIZE2 * SIZEOF(FAST_FLOAT));
00149         }
00150         fdtbl = fdct->float_divisors[qtblno];
00151         i = 0;
00152         for (row = 0; row < DCTSIZE; row++) {
00153           for (col = 0; col < DCTSIZE; col++) {
00154             fdtbl[i] = (FAST_FLOAT)
00155               (1.0 / (((double) qtbl->quantval[i] *
00156                        aanscalefactor[row] * aanscalefactor[col] * 8.0)));
00157             i++;
00158           }
00159         }
00160       }
00161       break;
00162 #endif
00163     default:
00164       ERREXIT(cinfo, JERR_NOT_COMPILED);
00165       break;
00166     }
00167   }
00168 }
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 METHODDEF(void)
00180 forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
00181              JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
00182              JDIMENSION start_row, JDIMENSION start_col,
00183              JDIMENSION num_blocks)
00184 
00185 {
00186   
00187   my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
00188   forward_DCT_method_ptr do_dct = fdct->do_dct;
00189   DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
00190   DCTELEM workspace[DCTSIZE2];  
00191   JDIMENSION bi;
00192 
00193   sample_data += start_row;     
00194 
00195   for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
00196     
00197     { register DCTELEM *workspaceptr;
00198       register JSAMPROW elemptr;
00199       register int elemr;
00200 
00201       workspaceptr = workspace;
00202       for (elemr = 0; elemr < DCTSIZE; elemr++) {
00203         elemptr = sample_data[elemr] + start_col;
00204 #if DCTSIZE == 8                
00205         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00206         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00207         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00208         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00209         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00210         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00211         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00212         *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00213 #else
00214         { register int elemc;
00215           for (elemc = DCTSIZE; elemc > 0; elemc--) {
00216             *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
00217           }
00218         }
00219 #endif
00220       }
00221     }
00222 
00223     
00224     (*do_dct) (workspace);
00225 
00226     
00227     { register DCTELEM temp, qval;
00228       register int i;
00229       register JCOEFPTR output_ptr = coef_blocks[bi];
00230 
00231       for (i = 0; i < DCTSIZE2; i++) {
00232         qval = divisors[i];
00233         temp = workspace[i];
00234         
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 #ifdef FAST_DIVIDE
00247 #define DIVIDE_BY(a,b)  a /= b
00248 #else
00249 #define DIVIDE_BY(a,b)  if (a >= b) a /= b; else a = 0
00250 #endif
00251         if (temp < 0) {
00252           temp = -temp;
00253           temp += qval>>1;      
00254           DIVIDE_BY(temp, qval);
00255           temp = -temp;
00256         } else {
00257           temp += qval>>1;      
00258           DIVIDE_BY(temp, qval);
00259         }
00260         output_ptr[i] = (JCOEF) temp;
00261       }
00262     }
00263   }
00264 }
00265 
00266 
00267 #ifdef DCT_FLOAT_SUPPORTED
00268 
00269 METHODDEF(void)
00270 forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
00271                    JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
00272                    JDIMENSION start_row, JDIMENSION start_col,
00273                    JDIMENSION num_blocks)
00274 
00275 {
00276   
00277   my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
00278   float_DCT_method_ptr do_dct = fdct->do_float_dct;
00279   FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
00280   FAST_FLOAT workspace[DCTSIZE2]; 
00281   JDIMENSION bi;
00282 
00283   sample_data += start_row;     
00284 
00285   for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
00286     
00287     { register FAST_FLOAT *workspaceptr;
00288       register JSAMPROW elemptr;
00289       register int elemr;
00290 
00291       workspaceptr = workspace;
00292       for (elemr = 0; elemr < DCTSIZE; elemr++) {
00293         elemptr = sample_data[elemr] + start_col;
00294 #if DCTSIZE == 8                
00295         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00296         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00297         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00298         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00299         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00300         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00301         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00302         *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00303 #else
00304         { register int elemc;
00305           for (elemc = DCTSIZE; elemc > 0; elemc--) {
00306             *workspaceptr++ = (FAST_FLOAT)
00307               (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
00308           }
00309         }
00310 #endif
00311       }
00312     }
00313 
00314     
00315     (*do_dct) (workspace);
00316 
00317     
00318     { register FAST_FLOAT temp;
00319       register int i;
00320       register JCOEFPTR output_ptr = coef_blocks[bi];
00321 
00322       for (i = 0; i < DCTSIZE2; i++) {
00323         
00324         temp = workspace[i] * divisors[i];
00325         
00326 
00327 
00328 
00329 
00330 
00331         output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
00332       }
00333     }
00334   }
00335 }
00336 
00337 #endif 
00338 
00339 
00340 
00341 
00342 
00343 
00344 GLOBAL(void)
00345 jinit_forward_dct (j_compress_ptr cinfo)
00346 {
00347   my_fdct_ptr fdct;
00348   int i;
00349 
00350   fdct = (my_fdct_ptr)
00351     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00352                                 SIZEOF(my_fdct_controller));
00353   cinfo->fdct = (struct jpeg_forward_dct *) fdct;
00354   fdct->pub.start_pass = start_pass_fdctmgr;
00355 
00356   switch (cinfo->dct_method) {
00357 #ifdef DCT_ISLOW_SUPPORTED
00358   case JDCT_ISLOW:
00359     fdct->pub.forward_DCT = forward_DCT;
00360     fdct->do_dct = jpeg_fdct_islow;
00361     break;
00362 #endif
00363 #ifdef DCT_IFAST_SUPPORTED
00364   case JDCT_IFAST:
00365     fdct->pub.forward_DCT = forward_DCT;
00366     fdct->do_dct = jpeg_fdct_ifast;
00367     break;
00368 #endif
00369 #ifdef DCT_FLOAT_SUPPORTED
00370   case JDCT_FLOAT:
00371     fdct->pub.forward_DCT = forward_DCT_float;
00372     fdct->do_float_dct = jpeg_fdct_float;
00373     break;
00374 #endif
00375   default:
00376     ERREXIT(cinfo, JERR_NOT_COMPILED);
00377     break;
00378   }
00379 
00380   
00381   for (i = 0; i < NUM_QUANT_TBLS; i++) {
00382     fdct->divisors[i] = NULL;
00383 #ifdef DCT_FLOAT_SUPPORTED
00384     fdct->float_divisors[i] = NULL;
00385 #endif
00386   }
00387 }