Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
jcmaster.c
Go to the documentation of this file.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
00018
00019
00020
00021 typedef enum {
00022 main_pass,
00023 huff_opt_pass,
00024 output_pass
00025 } c_pass_type;
00026
00027 typedef struct {
00028 struct jpeg_comp_master pub;
00029
00030 c_pass_type pass_type;
00031
00032 int pass_number;
00033 int total_passes;
00034
00035 int scan_number;
00036 } my_comp_master;
00037
00038 typedef my_comp_master * my_master_ptr;
00039
00040
00041
00042
00043
00044
00045 LOCAL(void)
00046 initial_setup (j_compress_ptr cinfo)
00047
00048 {
00049 int ci;
00050 jpeg_component_info *compptr;
00051 long samplesperrow;
00052 JDIMENSION jd_samplesperrow;
00053
00054
00055 if (cinfo->image_height <= 0 || cinfo->image_width <= 0
00056 || cinfo->num_components <= 0 || cinfo->input_components <= 0)
00057 ERREXIT(cinfo, JERR_EMPTY_IMAGE);
00058
00059
00060 if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
00061 (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
00062 ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
00063
00064
00065 samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
00066 jd_samplesperrow = (JDIMENSION) samplesperrow;
00067 if ((long) jd_samplesperrow != samplesperrow)
00068 ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
00069
00070
00071 if (cinfo->data_precision != BITS_IN_JSAMPLE)
00072 ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
00073
00074
00075 if (cinfo->num_components > MAX_COMPONENTS)
00076 ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
00077 MAX_COMPONENTS);
00078
00079
00080 cinfo->max_h_samp_factor = 1;
00081 cinfo->max_v_samp_factor = 1;
00082 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00083 ci++, compptr++) {
00084 if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
00085 compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
00086 ERREXIT(cinfo, JERR_BAD_SAMPLING);
00087 cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
00088 compptr->h_samp_factor);
00089 cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
00090 compptr->v_samp_factor);
00091 }
00092
00093
00094 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00095 ci++, compptr++) {
00096
00097 compptr->component_index = ci;
00098
00099 compptr->DCT_scaled_size = DCTSIZE;
00100
00101 compptr->width_in_blocks = (JDIMENSION)
00102 jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
00103 (long) (cinfo->max_h_samp_factor * DCTSIZE));
00104 compptr->height_in_blocks = (JDIMENSION)
00105 jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
00106 (long) (cinfo->max_v_samp_factor * DCTSIZE));
00107
00108 compptr->downsampled_width = (JDIMENSION)
00109 jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
00110 (long) cinfo->max_h_samp_factor);
00111 compptr->downsampled_height = (JDIMENSION)
00112 jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
00113 (long) cinfo->max_v_samp_factor);
00114
00115 compptr->component_needed = TRUE;
00116 }
00117
00118
00119
00120
00121 cinfo->total_iMCU_rows = (JDIMENSION)
00122 jdiv_round_up((long) cinfo->image_height,
00123 (long) (cinfo->max_v_samp_factor*DCTSIZE));
00124 }
00125
00126
00127 #ifdef C_MULTISCAN_FILES_SUPPORTED
00128
00129 LOCAL(void)
00130 validate_script (j_compress_ptr cinfo)
00131
00132
00133
00134 {
00135 const jpeg_scan_info * scanptr;
00136 int scanno, ncomps, ci, coefi, thisi;
00137 int Ss, Se, Ah, Al;
00138 boolean component_sent[MAX_COMPONENTS];
00139 #ifdef C_PROGRESSIVE_SUPPORTED
00140 int * last_bitpos_ptr;
00141 int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
00142
00143 #endif
00144
00145 if (cinfo->num_scans <= 0)
00146 ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
00147
00148
00149
00150
00151 scanptr = cinfo->scan_info;
00152 if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
00153 #ifdef C_PROGRESSIVE_SUPPORTED
00154 cinfo->progressive_mode = TRUE;
00155 last_bitpos_ptr = & last_bitpos[0][0];
00156 for (ci = 0; ci < cinfo->num_components; ci++)
00157 for (coefi = 0; coefi < DCTSIZE2; coefi++)
00158 *last_bitpos_ptr++ = -1;
00159 #else
00160 ERREXIT(cinfo, JERR_NOT_COMPILED);
00161 #endif
00162 } else {
00163 cinfo->progressive_mode = FALSE;
00164 for (ci = 0; ci < cinfo->num_components; ci++)
00165 component_sent[ci] = FALSE;
00166 }
00167
00168 for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
00169
00170 ncomps = scanptr->comps_in_scan;
00171 if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
00172 ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
00173 for (ci = 0; ci < ncomps; ci++) {
00174 thisi = scanptr->component_index[ci];
00175 if (thisi < 0 || thisi >= cinfo->num_components)
00176 ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
00177
00178 if (ci > 0 && thisi <= scanptr->component_index[ci-1])
00179 ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
00180 }
00181
00182 Ss = scanptr->Ss;
00183 Se = scanptr->Se;
00184 Ah = scanptr->Ah;
00185 Al = scanptr->Al;
00186 if (cinfo->progressive_mode) {
00187 #ifdef C_PROGRESSIVE_SUPPORTED
00188
00189
00190
00191
00192
00193
00194
00195 #if BITS_IN_JSAMPLE == 8
00196 #define MAX_AH_AL 10
00197 #else
00198 #define MAX_AH_AL 13
00199 #endif
00200 if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
00201 Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
00202 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00203 if (Ss == 0) {
00204 if (Se != 0)
00205 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00206 } else {
00207 if (ncomps != 1)
00208 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00209 }
00210 for (ci = 0; ci < ncomps; ci++) {
00211 last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
00212 if (Ss != 0 && last_bitpos_ptr[0] < 0)
00213 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00214 for (coefi = Ss; coefi <= Se; coefi++) {
00215 if (last_bitpos_ptr[coefi] < 0) {
00216
00217 if (Ah != 0)
00218 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00219 } else {
00220
00221 if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
00222 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00223 }
00224 last_bitpos_ptr[coefi] = Al;
00225 }
00226 }
00227 #endif
00228 } else {
00229
00230 if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
00231 ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
00232
00233 for (ci = 0; ci < ncomps; ci++) {
00234 thisi = scanptr->component_index[ci];
00235 if (component_sent[thisi])
00236 ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
00237 component_sent[thisi] = TRUE;
00238 }
00239 }
00240 }
00241
00242
00243 if (cinfo->progressive_mode) {
00244 #ifdef C_PROGRESSIVE_SUPPORTED
00245
00246
00247
00248
00249
00250 for (ci = 0; ci < cinfo->num_components; ci++) {
00251 if (last_bitpos[ci][0] < 0)
00252 ERREXIT(cinfo, JERR_MISSING_DATA);
00253 }
00254 #endif
00255 } else {
00256 for (ci = 0; ci < cinfo->num_components; ci++) {
00257 if (! component_sent[ci])
00258 ERREXIT(cinfo, JERR_MISSING_DATA);
00259 }
00260 }
00261 }
00262
00263 #endif
00264
00265
00266 LOCAL(void)
00267 select_scan_parameters (j_compress_ptr cinfo)
00268
00269 {
00270 int ci;
00271
00272 #ifdef C_MULTISCAN_FILES_SUPPORTED
00273 if (cinfo->scan_info != NULL) {
00274
00275 my_master_ptr master = (my_master_ptr) cinfo->master;
00276 const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
00277
00278 cinfo->comps_in_scan = scanptr->comps_in_scan;
00279 for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
00280 cinfo->cur_comp_info[ci] =
00281 &cinfo->comp_info[scanptr->component_index[ci]];
00282 }
00283 cinfo->Ss = scanptr->Ss;
00284 cinfo->Se = scanptr->Se;
00285 cinfo->Ah = scanptr->Ah;
00286 cinfo->Al = scanptr->Al;
00287 }
00288 else
00289 #endif
00290 {
00291
00292 if (cinfo->num_components > MAX_COMPS_IN_SCAN)
00293 ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
00294 MAX_COMPS_IN_SCAN);
00295 cinfo->comps_in_scan = cinfo->num_components;
00296 for (ci = 0; ci < cinfo->num_components; ci++) {
00297 cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
00298 }
00299 cinfo->Ss = 0;
00300 cinfo->Se = DCTSIZE2-1;
00301 cinfo->Ah = 0;
00302 cinfo->Al = 0;
00303 }
00304 }
00305
00306
00307 LOCAL(void)
00308 per_scan_setup (j_compress_ptr cinfo)
00309
00310
00311 {
00312 int ci, mcublks, tmp;
00313 jpeg_component_info *compptr;
00314
00315 if (cinfo->comps_in_scan == 1) {
00316
00317
00318 compptr = cinfo->cur_comp_info[0];
00319
00320
00321 cinfo->MCUs_per_row = compptr->width_in_blocks;
00322 cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
00323
00324
00325 compptr->MCU_width = 1;
00326 compptr->MCU_height = 1;
00327 compptr->MCU_blocks = 1;
00328 compptr->MCU_sample_width = DCTSIZE;
00329 compptr->last_col_width = 1;
00330
00331
00332
00333 tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
00334 if (tmp == 0) tmp = compptr->v_samp_factor;
00335 compptr->last_row_height = tmp;
00336
00337
00338 cinfo->blocks_in_MCU = 1;
00339 cinfo->MCU_membership[0] = 0;
00340
00341 } else {
00342
00343
00344 if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
00345 ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
00346 MAX_COMPS_IN_SCAN);
00347
00348
00349 cinfo->MCUs_per_row = (JDIMENSION)
00350 jdiv_round_up((long) cinfo->image_width,
00351 (long) (cinfo->max_h_samp_factor*DCTSIZE));
00352 cinfo->MCU_rows_in_scan = (JDIMENSION)
00353 jdiv_round_up((long) cinfo->image_height,
00354 (long) (cinfo->max_v_samp_factor*DCTSIZE));
00355
00356 cinfo->blocks_in_MCU = 0;
00357
00358 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00359 compptr = cinfo->cur_comp_info[ci];
00360
00361 compptr->MCU_width = compptr->h_samp_factor;
00362 compptr->MCU_height = compptr->v_samp_factor;
00363 compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
00364 compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
00365
00366 tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
00367 if (tmp == 0) tmp = compptr->MCU_width;
00368 compptr->last_col_width = tmp;
00369 tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
00370 if (tmp == 0) tmp = compptr->MCU_height;
00371 compptr->last_row_height = tmp;
00372
00373 mcublks = compptr->MCU_blocks;
00374 if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
00375 ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
00376 while (mcublks-- > 0) {
00377 cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
00378 }
00379 }
00380
00381 }
00382
00383
00384
00385 if (cinfo->restart_in_rows > 0) {
00386 long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
00387 cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 METHODDEF(void)
00401 prepare_for_pass (j_compress_ptr cinfo)
00402 {
00403 my_master_ptr master = (my_master_ptr) cinfo->master;
00404
00405 switch (master->pass_type) {
00406 case main_pass:
00407
00408
00409
00410 select_scan_parameters(cinfo);
00411 per_scan_setup(cinfo);
00412 if (! cinfo->raw_data_in) {
00413 (*cinfo->cconvert->start_pass) (cinfo);
00414 (*cinfo->downsample->start_pass) (cinfo);
00415 (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
00416 }
00417 (*cinfo->fdct->start_pass) (cinfo);
00418 (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
00419 (*cinfo->coef->start_pass) (cinfo,
00420 (master->total_passes > 1 ?
00421 JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
00422 (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
00423 if (cinfo->optimize_coding) {
00424
00425 master->pub.call_pass_startup = FALSE;
00426 } else {
00427
00428 master->pub.call_pass_startup = TRUE;
00429 }
00430 break;
00431 #ifdef ENTROPY_OPT_SUPPORTED
00432 case huff_opt_pass:
00433
00434 select_scan_parameters(cinfo);
00435 per_scan_setup(cinfo);
00436 if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
00437 (*cinfo->entropy->start_pass) (cinfo, TRUE);
00438 (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
00439 master->pub.call_pass_startup = FALSE;
00440 break;
00441 }
00442
00443
00444
00445 master->pass_type = output_pass;
00446 master->pass_number++;
00447
00448 #endif
00449 case output_pass:
00450
00451
00452 if (! cinfo->optimize_coding) {
00453 select_scan_parameters(cinfo);
00454 per_scan_setup(cinfo);
00455 }
00456 (*cinfo->entropy->start_pass) (cinfo, FALSE);
00457 (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
00458
00459 if (master->scan_number == 0)
00460 (*cinfo->marker->write_frame_header) (cinfo);
00461 (*cinfo->marker->write_scan_header) (cinfo);
00462 master->pub.call_pass_startup = FALSE;
00463 break;
00464 default:
00465 ERREXIT(cinfo, JERR_NOT_COMPILED);
00466 }
00467
00468 master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
00469
00470
00471 if (cinfo->progress != NULL) {
00472 cinfo->progress->completed_passes = master->pass_number;
00473 cinfo->progress->total_passes = master->total_passes;
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 METHODDEF(void)
00489 pass_startup (j_compress_ptr cinfo)
00490 {
00491 cinfo->master->call_pass_startup = FALSE;
00492
00493 (*cinfo->marker->write_frame_header) (cinfo);
00494 (*cinfo->marker->write_scan_header) (cinfo);
00495 }
00496
00497
00498
00499
00500
00501
00502 METHODDEF(void)
00503 finish_pass_master (j_compress_ptr cinfo)
00504 {
00505 my_master_ptr master = (my_master_ptr) cinfo->master;
00506
00507
00508
00509
00510 (*cinfo->entropy->finish_pass) (cinfo);
00511
00512
00513 switch (master->pass_type) {
00514 case main_pass:
00515
00516
00517
00518 master->pass_type = output_pass;
00519 if (! cinfo->optimize_coding)
00520 master->scan_number++;
00521 break;
00522 case huff_opt_pass:
00523
00524 master->pass_type = output_pass;
00525 break;
00526 case output_pass:
00527
00528 if (cinfo->optimize_coding)
00529 master->pass_type = huff_opt_pass;
00530 master->scan_number++;
00531 break;
00532 }
00533
00534 master->pass_number++;
00535 }
00536
00537
00538
00539
00540
00541
00542 GLOBAL(void)
00543 jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
00544 {
00545 my_master_ptr master;
00546
00547 master = (my_master_ptr)
00548 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00549 SIZEOF(my_comp_master));
00550 cinfo->master = (struct jpeg_comp_master *) master;
00551 master->pub.prepare_for_pass = prepare_for_pass;
00552 master->pub.pass_startup = pass_startup;
00553 master->pub.finish_pass = finish_pass_master;
00554 master->pub.is_last_pass = FALSE;
00555
00556
00557 initial_setup(cinfo);
00558
00559 if (cinfo->scan_info != NULL) {
00560 #ifdef C_MULTISCAN_FILES_SUPPORTED
00561 validate_script(cinfo);
00562 #else
00563 ERREXIT(cinfo, JERR_NOT_COMPILED);
00564 #endif
00565 } else {
00566 cinfo->progressive_mode = FALSE;
00567 cinfo->num_scans = 1;
00568 }
00569
00570 if (cinfo->progressive_mode)
00571 cinfo->optimize_coding = TRUE;
00572
00573
00574 if (transcode_only) {
00575
00576 if (cinfo->optimize_coding)
00577 master->pass_type = huff_opt_pass;
00578 else
00579 master->pass_type = output_pass;
00580 } else {
00581
00582 master->pass_type = main_pass;
00583 }
00584 master->scan_number = 0;
00585 master->pass_number = 0;
00586 if (cinfo->optimize_coding)
00587 master->total_passes = cinfo->num_scans * 2;
00588 else
00589 master->total_passes = cinfo->num_scans;
00590 }