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[MAX_COMPONENTS];
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[MAX_COMPONENTS];
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 #ifdef DCT_ISLOW_SUPPORTED
00048 #define PROVIDE_ISLOW_TABLES
00049 #else
00050 #ifdef DCT_SCALING_SUPPORTED
00051 #define PROVIDE_ISLOW_TABLES
00052 #endif
00053 #endif
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 METHODDEF(void)
00065 forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
00066 JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
00067 JDIMENSION start_row, JDIMENSION start_col,
00068 JDIMENSION num_blocks)
00069
00070 {
00071
00072 my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
00073 forward_DCT_method_ptr do_dct = fdct->do_dct[compptr->component_index];
00074 DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
00075 DCTELEM workspace[DCTSIZE2];
00076 JDIMENSION bi;
00077
00078 sample_data += start_row;
00079
00080 for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
00081
00082 (*do_dct) (workspace, sample_data, start_col);
00083
00084
00085 { register DCTELEM temp, qval;
00086 register int i;
00087 register JCOEFPTR output_ptr = coef_blocks[bi];
00088
00089 for (i = 0; i < DCTSIZE2; i++) {
00090 qval = divisors[i];
00091 temp = workspace[i];
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #ifdef FAST_DIVIDE
00105 #define DIVIDE_BY(a,b) a /= b
00106 #else
00107 #define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
00108 #endif
00109 if (temp < 0) {
00110 temp = -temp;
00111 temp += qval>>1;
00112 DIVIDE_BY(temp, qval);
00113 temp = -temp;
00114 } else {
00115 temp += qval>>1;
00116 DIVIDE_BY(temp, qval);
00117 }
00118 output_ptr[i] = (JCOEF) temp;
00119 }
00120 }
00121 }
00122 }
00123
00124
00125 #ifdef DCT_FLOAT_SUPPORTED
00126
00127 METHODDEF(void)
00128 forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
00129 JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
00130 JDIMENSION start_row, JDIMENSION start_col,
00131 JDIMENSION num_blocks)
00132
00133 {
00134
00135 my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
00136 float_DCT_method_ptr do_dct = fdct->do_float_dct[compptr->component_index];
00137 FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
00138 FAST_FLOAT workspace[DCTSIZE2];
00139 JDIMENSION bi;
00140
00141 sample_data += start_row;
00142
00143 for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
00144
00145 (*do_dct) (workspace, sample_data, start_col);
00146
00147
00148 { register FAST_FLOAT temp;
00149 register int i;
00150 register JCOEFPTR output_ptr = coef_blocks[bi];
00151
00152 for (i = 0; i < DCTSIZE2; i++) {
00153
00154 temp = workspace[i] * divisors[i];
00155
00156
00157
00158
00159
00160
00161 output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
00162 }
00163 }
00164 }
00165 }
00166
00167 #endif
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 METHODDEF(void)
00180 start_pass_fdctmgr (j_compress_ptr cinfo)
00181 {
00182 my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
00183 int ci, qtblno, i;
00184 jpeg_component_info *compptr;
00185 int method = 0;
00186 JQUANT_TBL * qtbl;
00187 DCTELEM * dtbl;
00188
00189 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00190 ci++, compptr++) {
00191
00192 switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
00193 #ifdef DCT_SCALING_SUPPORTED
00194 case ((1 << 8) + 1):
00195 fdct->do_dct[ci] = jpeg_fdct_1x1;
00196 method = JDCT_ISLOW;
00197 break;
00198 case ((2 << 8) + 2):
00199 fdct->do_dct[ci] = jpeg_fdct_2x2;
00200 method = JDCT_ISLOW;
00201 break;
00202 case ((3 << 8) + 3):
00203 fdct->do_dct[ci] = jpeg_fdct_3x3;
00204 method = JDCT_ISLOW;
00205 break;
00206 case ((4 << 8) + 4):
00207 fdct->do_dct[ci] = jpeg_fdct_4x4;
00208 method = JDCT_ISLOW;
00209 break;
00210 case ((5 << 8) + 5):
00211 fdct->do_dct[ci] = jpeg_fdct_5x5;
00212 method = JDCT_ISLOW;
00213 break;
00214 case ((6 << 8) + 6):
00215 fdct->do_dct[ci] = jpeg_fdct_6x6;
00216 method = JDCT_ISLOW;
00217 break;
00218 case ((7 << 8) + 7):
00219 fdct->do_dct[ci] = jpeg_fdct_7x7;
00220 method = JDCT_ISLOW;
00221 break;
00222 case ((9 << 8) + 9):
00223 fdct->do_dct[ci] = jpeg_fdct_9x9;
00224 method = JDCT_ISLOW;
00225 break;
00226 case ((10 << 8) + 10):
00227 fdct->do_dct[ci] = jpeg_fdct_10x10;
00228 method = JDCT_ISLOW;
00229 break;
00230 case ((11 << 8) + 11):
00231 fdct->do_dct[ci] = jpeg_fdct_11x11;
00232 method = JDCT_ISLOW;
00233 break;
00234 case ((12 << 8) + 12):
00235 fdct->do_dct[ci] = jpeg_fdct_12x12;
00236 method = JDCT_ISLOW;
00237 break;
00238 case ((13 << 8) + 13):
00239 fdct->do_dct[ci] = jpeg_fdct_13x13;
00240 method = JDCT_ISLOW;
00241 break;
00242 case ((14 << 8) + 14):
00243 fdct->do_dct[ci] = jpeg_fdct_14x14;
00244 method = JDCT_ISLOW;
00245 break;
00246 case ((15 << 8) + 15):
00247 fdct->do_dct[ci] = jpeg_fdct_15x15;
00248 method = JDCT_ISLOW;
00249 break;
00250 case ((16 << 8) + 16):
00251 fdct->do_dct[ci] = jpeg_fdct_16x16;
00252 method = JDCT_ISLOW;
00253 break;
00254 case ((16 << 8) + 8):
00255 fdct->do_dct[ci] = jpeg_fdct_16x8;
00256 method = JDCT_ISLOW;
00257 break;
00258 case ((14 << 8) + 7):
00259 fdct->do_dct[ci] = jpeg_fdct_14x7;
00260 method = JDCT_ISLOW;
00261 break;
00262 case ((12 << 8) + 6):
00263 fdct->do_dct[ci] = jpeg_fdct_12x6;
00264 method = JDCT_ISLOW;
00265 break;
00266 case ((10 << 8) + 5):
00267 fdct->do_dct[ci] = jpeg_fdct_10x5;
00268 method = JDCT_ISLOW;
00269 break;
00270 case ((8 << 8) + 4):
00271 fdct->do_dct[ci] = jpeg_fdct_8x4;
00272 method = JDCT_ISLOW;
00273 break;
00274 case ((6 << 8) + 3):
00275 fdct->do_dct[ci] = jpeg_fdct_6x3;
00276 method = JDCT_ISLOW;
00277 break;
00278 case ((4 << 8) + 2):
00279 fdct->do_dct[ci] = jpeg_fdct_4x2;
00280 method = JDCT_ISLOW;
00281 break;
00282 case ((2 << 8) + 1):
00283 fdct->do_dct[ci] = jpeg_fdct_2x1;
00284 method = JDCT_ISLOW;
00285 break;
00286 case ((8 << 8) + 16):
00287 fdct->do_dct[ci] = jpeg_fdct_8x16;
00288 method = JDCT_ISLOW;
00289 break;
00290 case ((7 << 8) + 14):
00291 fdct->do_dct[ci] = jpeg_fdct_7x14;
00292 method = JDCT_ISLOW;
00293 break;
00294 case ((6 << 8) + 12):
00295 fdct->do_dct[ci] = jpeg_fdct_6x12;
00296 method = JDCT_ISLOW;
00297 break;
00298 case ((5 << 8) + 10):
00299 fdct->do_dct[ci] = jpeg_fdct_5x10;
00300 method = JDCT_ISLOW;
00301 break;
00302 case ((4 << 8) + 8):
00303 fdct->do_dct[ci] = jpeg_fdct_4x8;
00304 method = JDCT_ISLOW;
00305 break;
00306 case ((3 << 8) + 6):
00307 fdct->do_dct[ci] = jpeg_fdct_3x6;
00308 method = JDCT_ISLOW;
00309 break;
00310 case ((2 << 8) + 4):
00311 fdct->do_dct[ci] = jpeg_fdct_2x4;
00312 method = JDCT_ISLOW;
00313 break;
00314 case ((1 << 8) + 2):
00315 fdct->do_dct[ci] = jpeg_fdct_1x2;
00316 method = JDCT_ISLOW;
00317 break;
00318 #endif
00319 case ((DCTSIZE << 8) + DCTSIZE):
00320 switch (cinfo->dct_method) {
00321 #ifdef DCT_ISLOW_SUPPORTED
00322 case JDCT_ISLOW:
00323 fdct->do_dct[ci] = jpeg_fdct_islow;
00324 method = JDCT_ISLOW;
00325 break;
00326 #endif
00327 #ifdef DCT_IFAST_SUPPORTED
00328 case JDCT_IFAST:
00329 fdct->do_dct[ci] = jpeg_fdct_ifast;
00330 method = JDCT_IFAST;
00331 break;
00332 #endif
00333 #ifdef DCT_FLOAT_SUPPORTED
00334 case JDCT_FLOAT:
00335 fdct->do_float_dct[ci] = jpeg_fdct_float;
00336 method = JDCT_FLOAT;
00337 break;
00338 #endif
00339 default:
00340 ERREXIT(cinfo, JERR_NOT_COMPILED);
00341 break;
00342 }
00343 break;
00344 default:
00345 ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
00346 compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
00347 break;
00348 }
00349 qtblno = compptr->quant_tbl_no;
00350
00351 if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
00352 cinfo->quant_tbl_ptrs[qtblno] == NULL)
00353 ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
00354 qtbl = cinfo->quant_tbl_ptrs[qtblno];
00355
00356
00357 switch (method) {
00358 #ifdef PROVIDE_ISLOW_TABLES
00359 case JDCT_ISLOW:
00360
00361
00362
00363 if (fdct->divisors[qtblno] == NULL) {
00364 fdct->divisors[qtblno] = (DCTELEM *)
00365 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00366 DCTSIZE2 * SIZEOF(DCTELEM));
00367 }
00368 dtbl = fdct->divisors[qtblno];
00369 for (i = 0; i < DCTSIZE2; i++) {
00370 dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
00371 }
00372 fdct->pub.forward_DCT[ci] = forward_DCT;
00373 break;
00374 #endif
00375 #ifdef DCT_IFAST_SUPPORTED
00376 case JDCT_IFAST:
00377 {
00378
00379
00380
00381
00382
00383
00384 #define CONST_BITS 14
00385 static const INT16 aanscales[DCTSIZE2] = {
00386
00387 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
00388 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
00389 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
00390 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
00391 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
00392 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
00393 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
00394 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
00395 };
00396 SHIFT_TEMPS
00397
00398 if (fdct->divisors[qtblno] == NULL) {
00399 fdct->divisors[qtblno] = (DCTELEM *)
00400 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00401 DCTSIZE2 * SIZEOF(DCTELEM));
00402 }
00403 dtbl = fdct->divisors[qtblno];
00404 for (i = 0; i < DCTSIZE2; i++) {
00405 dtbl[i] = (DCTELEM)
00406 DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
00407 (INT32) aanscales[i]),
00408 CONST_BITS-3);
00409 }
00410 }
00411 fdct->pub.forward_DCT[ci] = forward_DCT;
00412 break;
00413 #endif
00414 #ifdef DCT_FLOAT_SUPPORTED
00415 case JDCT_FLOAT:
00416 {
00417
00418
00419
00420
00421
00422
00423
00424
00425 FAST_FLOAT * fdtbl;
00426 int row, col;
00427 static const double aanscalefactor[DCTSIZE] = {
00428 1.0, 1.387039845, 1.306562965, 1.175875602,
00429 1.0, 0.785694958, 0.541196100, 0.275899379
00430 };
00431
00432 if (fdct->float_divisors[qtblno] == NULL) {
00433 fdct->float_divisors[qtblno] = (FAST_FLOAT *)
00434 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00435 DCTSIZE2 * SIZEOF(FAST_FLOAT));
00436 }
00437 fdtbl = fdct->float_divisors[qtblno];
00438 i = 0;
00439 for (row = 0; row < DCTSIZE; row++) {
00440 for (col = 0; col < DCTSIZE; col++) {
00441 fdtbl[i] = (FAST_FLOAT)
00442 (1.0 / (((double) qtbl->quantval[i] *
00443 aanscalefactor[row] * aanscalefactor[col] * 8.0)));
00444 i++;
00445 }
00446 }
00447 }
00448 fdct->pub.forward_DCT[ci] = forward_DCT_float;
00449 break;
00450 #endif
00451 default:
00452 ERREXIT(cinfo, JERR_NOT_COMPILED);
00453 break;
00454 }
00455 }
00456 }
00457
00458
00459
00460
00461
00462
00463 GLOBAL(void)
00464 jinit_forward_dct (j_compress_ptr cinfo)
00465 {
00466 my_fdct_ptr fdct;
00467 int i;
00468
00469 fdct = (my_fdct_ptr)
00470 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00471 SIZEOF(my_fdct_controller));
00472 cinfo->fdct = (struct jpeg_forward_dct *) fdct;
00473 fdct->pub.start_pass = start_pass_fdctmgr;
00474
00475
00476 for (i = 0; i < NUM_QUANT_TBLS; i++) {
00477 fdct->divisors[i] = NULL;
00478 #ifdef DCT_FLOAT_SUPPORTED
00479 fdct->float_divisors[i] = NULL;
00480 #endif
00481 }
00482 }