17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier * jdmaster.c
37dd7cddfSDavid du Colombier *
4*593dc095SDavid du Colombier * Copyright (C) 1991-1997, Thomas G. Lane.
57dd7cddfSDavid du Colombier * This file is part of the Independent JPEG Group's software.
67dd7cddfSDavid du Colombier * For conditions of distribution and use, see the accompanying README file.
77dd7cddfSDavid du Colombier *
87dd7cddfSDavid du Colombier * This file contains master control logic for the JPEG decompressor.
97dd7cddfSDavid du Colombier * These routines are concerned with selecting the modules to be executed
107dd7cddfSDavid du Colombier * and with determining the number of passes and the work to be done in each
117dd7cddfSDavid du Colombier * pass.
127dd7cddfSDavid du Colombier */
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier #define JPEG_INTERNALS
157dd7cddfSDavid du Colombier #include "jinclude.h"
167dd7cddfSDavid du Colombier #include "jpeglib.h"
177dd7cddfSDavid du Colombier
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier /* Private state */
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier typedef struct {
227dd7cddfSDavid du Colombier struct jpeg_decomp_master pub; /* public fields */
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier int pass_number; /* # of passes completed */
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
277dd7cddfSDavid du Colombier
287dd7cddfSDavid du Colombier /* Saved references to initialized quantizer modules,
297dd7cddfSDavid du Colombier * in case we need to switch modes.
307dd7cddfSDavid du Colombier */
317dd7cddfSDavid du Colombier struct jpeg_color_quantizer * quantizer_1pass;
327dd7cddfSDavid du Colombier struct jpeg_color_quantizer * quantizer_2pass;
337dd7cddfSDavid du Colombier } my_decomp_master;
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier typedef my_decomp_master * my_master_ptr;
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier /*
397dd7cddfSDavid du Colombier * Determine whether merged upsample/color conversion should be used.
407dd7cddfSDavid du Colombier * CRUCIAL: this must match the actual capabilities of jdmerge.c!
417dd7cddfSDavid du Colombier */
427dd7cddfSDavid du Colombier
437dd7cddfSDavid du Colombier LOCAL(boolean)
use_merged_upsample(j_decompress_ptr cinfo)447dd7cddfSDavid du Colombier use_merged_upsample (j_decompress_ptr cinfo)
457dd7cddfSDavid du Colombier {
467dd7cddfSDavid du Colombier #ifdef UPSAMPLE_MERGING_SUPPORTED
477dd7cddfSDavid du Colombier /* Merging is the equivalent of plain box-filter upsampling */
487dd7cddfSDavid du Colombier if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
497dd7cddfSDavid du Colombier return FALSE;
507dd7cddfSDavid du Colombier /* jdmerge.c only supports YCC=>RGB color conversion */
517dd7cddfSDavid du Colombier if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
527dd7cddfSDavid du Colombier cinfo->out_color_space != JCS_RGB ||
537dd7cddfSDavid du Colombier cinfo->out_color_components != RGB_PIXELSIZE)
547dd7cddfSDavid du Colombier return FALSE;
557dd7cddfSDavid du Colombier /* and it only handles 2h1v or 2h2v sampling ratios */
567dd7cddfSDavid du Colombier if (cinfo->comp_info[0].h_samp_factor != 2 ||
577dd7cddfSDavid du Colombier cinfo->comp_info[1].h_samp_factor != 1 ||
587dd7cddfSDavid du Colombier cinfo->comp_info[2].h_samp_factor != 1 ||
597dd7cddfSDavid du Colombier cinfo->comp_info[0].v_samp_factor > 2 ||
607dd7cddfSDavid du Colombier cinfo->comp_info[1].v_samp_factor != 1 ||
617dd7cddfSDavid du Colombier cinfo->comp_info[2].v_samp_factor != 1)
627dd7cddfSDavid du Colombier return FALSE;
637dd7cddfSDavid du Colombier /* furthermore, it doesn't work if we've scaled the IDCTs differently */
647dd7cddfSDavid du Colombier if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
657dd7cddfSDavid du Colombier cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
667dd7cddfSDavid du Colombier cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
677dd7cddfSDavid du Colombier return FALSE;
687dd7cddfSDavid du Colombier /* ??? also need to test for upsample-time rescaling, when & if supported */
697dd7cddfSDavid du Colombier return TRUE; /* by golly, it'll work... */
707dd7cddfSDavid du Colombier #else
717dd7cddfSDavid du Colombier return FALSE;
727dd7cddfSDavid du Colombier #endif
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier /*
777dd7cddfSDavid du Colombier * Compute output image dimensions and related values.
787dd7cddfSDavid du Colombier * NOTE: this is exported for possible use by application.
797dd7cddfSDavid du Colombier * Hence it mustn't do anything that can't be done twice.
807dd7cddfSDavid du Colombier * Also note that it may be called before the master module is initialized!
817dd7cddfSDavid du Colombier */
827dd7cddfSDavid du Colombier
837dd7cddfSDavid du Colombier GLOBAL(void)
jpeg_calc_output_dimensions(j_decompress_ptr cinfo)847dd7cddfSDavid du Colombier jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
857dd7cddfSDavid du Colombier /* Do computations that are needed before master selection phase */
867dd7cddfSDavid du Colombier {
87*593dc095SDavid du Colombier #ifdef IDCT_SCALING_SUPPORTED
887dd7cddfSDavid du Colombier int ci;
897dd7cddfSDavid du Colombier jpeg_component_info *compptr;
90*593dc095SDavid du Colombier #endif
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier /* Prevent application from calling me at wrong times */
937dd7cddfSDavid du Colombier if (cinfo->global_state != DSTATE_READY)
947dd7cddfSDavid du Colombier ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier #ifdef IDCT_SCALING_SUPPORTED
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier /* Compute actual output image dimensions and DCT scaling choices. */
997dd7cddfSDavid du Colombier if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
1007dd7cddfSDavid du Colombier /* Provide 1/8 scaling */
1017dd7cddfSDavid du Colombier cinfo->output_width = (JDIMENSION)
1027dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_width, 8L);
1037dd7cddfSDavid du Colombier cinfo->output_height = (JDIMENSION)
1047dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_height, 8L);
1057dd7cddfSDavid du Colombier cinfo->min_DCT_scaled_size = 1;
1067dd7cddfSDavid du Colombier } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
1077dd7cddfSDavid du Colombier /* Provide 1/4 scaling */
1087dd7cddfSDavid du Colombier cinfo->output_width = (JDIMENSION)
1097dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_width, 4L);
1107dd7cddfSDavid du Colombier cinfo->output_height = (JDIMENSION)
1117dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_height, 4L);
1127dd7cddfSDavid du Colombier cinfo->min_DCT_scaled_size = 2;
1137dd7cddfSDavid du Colombier } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
1147dd7cddfSDavid du Colombier /* Provide 1/2 scaling */
1157dd7cddfSDavid du Colombier cinfo->output_width = (JDIMENSION)
1167dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_width, 2L);
1177dd7cddfSDavid du Colombier cinfo->output_height = (JDIMENSION)
1187dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_height, 2L);
1197dd7cddfSDavid du Colombier cinfo->min_DCT_scaled_size = 4;
1207dd7cddfSDavid du Colombier } else {
1217dd7cddfSDavid du Colombier /* Provide 1/1 scaling */
1227dd7cddfSDavid du Colombier cinfo->output_width = cinfo->image_width;
1237dd7cddfSDavid du Colombier cinfo->output_height = cinfo->image_height;
1247dd7cddfSDavid du Colombier cinfo->min_DCT_scaled_size = DCTSIZE;
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier /* In selecting the actual DCT scaling for each component, we try to
1277dd7cddfSDavid du Colombier * scale up the chroma components via IDCT scaling rather than upsampling.
1287dd7cddfSDavid du Colombier * This saves time if the upsampler gets to use 1:1 scaling.
1297dd7cddfSDavid du Colombier * Note this code assumes that the supported DCT scalings are powers of 2.
1307dd7cddfSDavid du Colombier */
1317dd7cddfSDavid du Colombier for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
1327dd7cddfSDavid du Colombier ci++, compptr++) {
1337dd7cddfSDavid du Colombier int ssize = cinfo->min_DCT_scaled_size;
1347dd7cddfSDavid du Colombier while (ssize < DCTSIZE &&
1357dd7cddfSDavid du Colombier (compptr->h_samp_factor * ssize * 2 <=
1367dd7cddfSDavid du Colombier cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
1377dd7cddfSDavid du Colombier (compptr->v_samp_factor * ssize * 2 <=
1387dd7cddfSDavid du Colombier cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
1397dd7cddfSDavid du Colombier ssize = ssize * 2;
1407dd7cddfSDavid du Colombier }
1417dd7cddfSDavid du Colombier compptr->DCT_scaled_size = ssize;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier /* Recompute downsampled dimensions of components;
1457dd7cddfSDavid du Colombier * application needs to know these if using raw downsampled data.
1467dd7cddfSDavid du Colombier */
1477dd7cddfSDavid du Colombier for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
1487dd7cddfSDavid du Colombier ci++, compptr++) {
1497dd7cddfSDavid du Colombier /* Size in samples, after IDCT scaling */
1507dd7cddfSDavid du Colombier compptr->downsampled_width = (JDIMENSION)
1517dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_width *
1527dd7cddfSDavid du Colombier (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
1537dd7cddfSDavid du Colombier (long) (cinfo->max_h_samp_factor * DCTSIZE));
1547dd7cddfSDavid du Colombier compptr->downsampled_height = (JDIMENSION)
1557dd7cddfSDavid du Colombier jdiv_round_up((long) cinfo->image_height *
1567dd7cddfSDavid du Colombier (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
1577dd7cddfSDavid du Colombier (long) (cinfo->max_v_samp_factor * DCTSIZE));
1587dd7cddfSDavid du Colombier }
1597dd7cddfSDavid du Colombier
1607dd7cddfSDavid du Colombier #else /* !IDCT_SCALING_SUPPORTED */
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier /* Hardwire it to "no scaling" */
1637dd7cddfSDavid du Colombier cinfo->output_width = cinfo->image_width;
1647dd7cddfSDavid du Colombier cinfo->output_height = cinfo->image_height;
1657dd7cddfSDavid du Colombier /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
1667dd7cddfSDavid du Colombier * and has computed unscaled downsampled_width and downsampled_height.
1677dd7cddfSDavid du Colombier */
1687dd7cddfSDavid du Colombier
1697dd7cddfSDavid du Colombier #endif /* IDCT_SCALING_SUPPORTED */
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier /* Report number of components in selected colorspace. */
1727dd7cddfSDavid du Colombier /* Probably this should be in the color conversion module... */
1737dd7cddfSDavid du Colombier switch (cinfo->out_color_space) {
1747dd7cddfSDavid du Colombier case JCS_GRAYSCALE:
1757dd7cddfSDavid du Colombier cinfo->out_color_components = 1;
1767dd7cddfSDavid du Colombier break;
1777dd7cddfSDavid du Colombier case JCS_RGB:
1787dd7cddfSDavid du Colombier #if RGB_PIXELSIZE != 3
1797dd7cddfSDavid du Colombier cinfo->out_color_components = RGB_PIXELSIZE;
1807dd7cddfSDavid du Colombier break;
1817dd7cddfSDavid du Colombier #endif /* else share code with YCbCr */
1827dd7cddfSDavid du Colombier case JCS_YCbCr:
1837dd7cddfSDavid du Colombier cinfo->out_color_components = 3;
1847dd7cddfSDavid du Colombier break;
1857dd7cddfSDavid du Colombier case JCS_CMYK:
1867dd7cddfSDavid du Colombier case JCS_YCCK:
1877dd7cddfSDavid du Colombier cinfo->out_color_components = 4;
1887dd7cddfSDavid du Colombier break;
1897dd7cddfSDavid du Colombier default: /* else must be same colorspace as in file */
1907dd7cddfSDavid du Colombier cinfo->out_color_components = cinfo->num_components;
1917dd7cddfSDavid du Colombier break;
1927dd7cddfSDavid du Colombier }
1937dd7cddfSDavid du Colombier cinfo->output_components = (cinfo->quantize_colors ? 1 :
1947dd7cddfSDavid du Colombier cinfo->out_color_components);
1957dd7cddfSDavid du Colombier
1967dd7cddfSDavid du Colombier /* See if upsampler will want to emit more than one row at a time */
1977dd7cddfSDavid du Colombier if (use_merged_upsample(cinfo))
1987dd7cddfSDavid du Colombier cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
1997dd7cddfSDavid du Colombier else
2007dd7cddfSDavid du Colombier cinfo->rec_outbuf_height = 1;
2017dd7cddfSDavid du Colombier }
2027dd7cddfSDavid du Colombier
2037dd7cddfSDavid du Colombier
2047dd7cddfSDavid du Colombier /*
2057dd7cddfSDavid du Colombier * Several decompression processes need to range-limit values to the range
2067dd7cddfSDavid du Colombier * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
2077dd7cddfSDavid du Colombier * due to noise introduced by quantization, roundoff error, etc. These
2087dd7cddfSDavid du Colombier * processes are inner loops and need to be as fast as possible. On most
2097dd7cddfSDavid du Colombier * machines, particularly CPUs with pipelines or instruction prefetch,
2107dd7cddfSDavid du Colombier * a (subscript-check-less) C table lookup
2117dd7cddfSDavid du Colombier * x = sample_range_limit[x];
2127dd7cddfSDavid du Colombier * is faster than explicit tests
2137dd7cddfSDavid du Colombier * if (x < 0) x = 0;
2147dd7cddfSDavid du Colombier * else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
2157dd7cddfSDavid du Colombier * These processes all use a common table prepared by the routine below.
2167dd7cddfSDavid du Colombier *
2177dd7cddfSDavid du Colombier * For most steps we can mathematically guarantee that the initial value
2187dd7cddfSDavid du Colombier * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
2197dd7cddfSDavid du Colombier * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial
2207dd7cddfSDavid du Colombier * limiting step (just after the IDCT), a wildly out-of-range value is
2217dd7cddfSDavid du Colombier * possible if the input data is corrupt. To avoid any chance of indexing
2227dd7cddfSDavid du Colombier * off the end of memory and getting a bad-pointer trap, we perform the
2237dd7cddfSDavid du Colombier * post-IDCT limiting thus:
2247dd7cddfSDavid du Colombier * x = range_limit[x & MASK];
2257dd7cddfSDavid du Colombier * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
2267dd7cddfSDavid du Colombier * samples. Under normal circumstances this is more than enough range and
2277dd7cddfSDavid du Colombier * a correct output will be generated; with bogus input data the mask will
2287dd7cddfSDavid du Colombier * cause wraparound, and we will safely generate a bogus-but-in-range output.
2297dd7cddfSDavid du Colombier * For the post-IDCT step, we want to convert the data from signed to unsigned
2307dd7cddfSDavid du Colombier * representation by adding CENTERJSAMPLE at the same time that we limit it.
2317dd7cddfSDavid du Colombier * So the post-IDCT limiting table ends up looking like this:
2327dd7cddfSDavid du Colombier * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
2337dd7cddfSDavid du Colombier * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
2347dd7cddfSDavid du Colombier * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
2357dd7cddfSDavid du Colombier * 0,1,...,CENTERJSAMPLE-1
2367dd7cddfSDavid du Colombier * Negative inputs select values from the upper half of the table after
2377dd7cddfSDavid du Colombier * masking.
2387dd7cddfSDavid du Colombier *
2397dd7cddfSDavid du Colombier * We can save some space by overlapping the start of the post-IDCT table
2407dd7cddfSDavid du Colombier * with the simpler range limiting table. The post-IDCT table begins at
2417dd7cddfSDavid du Colombier * sample_range_limit + CENTERJSAMPLE.
2427dd7cddfSDavid du Colombier *
2437dd7cddfSDavid du Colombier * Note that the table is allocated in near data space on PCs; it's small
2447dd7cddfSDavid du Colombier * enough and used often enough to justify this.
2457dd7cddfSDavid du Colombier */
2467dd7cddfSDavid du Colombier
2477dd7cddfSDavid du Colombier LOCAL(void)
prepare_range_limit_table(j_decompress_ptr cinfo)2487dd7cddfSDavid du Colombier prepare_range_limit_table (j_decompress_ptr cinfo)
2497dd7cddfSDavid du Colombier /* Allocate and fill in the sample_range_limit table */
2507dd7cddfSDavid du Colombier {
2517dd7cddfSDavid du Colombier JSAMPLE * table;
2527dd7cddfSDavid du Colombier int i;
2537dd7cddfSDavid du Colombier
2547dd7cddfSDavid du Colombier table = (JSAMPLE *)
2557dd7cddfSDavid du Colombier (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
2567dd7cddfSDavid du Colombier (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
2577dd7cddfSDavid du Colombier table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */
2587dd7cddfSDavid du Colombier cinfo->sample_range_limit = table;
2597dd7cddfSDavid du Colombier /* First segment of "simple" table: limit[x] = 0 for x < 0 */
2607dd7cddfSDavid du Colombier MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
2617dd7cddfSDavid du Colombier /* Main part of "simple" table: limit[x] = x */
2627dd7cddfSDavid du Colombier for (i = 0; i <= MAXJSAMPLE; i++)
2637dd7cddfSDavid du Colombier table[i] = (JSAMPLE) i;
2647dd7cddfSDavid du Colombier table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
2657dd7cddfSDavid du Colombier /* End of simple table, rest of first half of post-IDCT table */
2667dd7cddfSDavid du Colombier for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
2677dd7cddfSDavid du Colombier table[i] = MAXJSAMPLE;
2687dd7cddfSDavid du Colombier /* Second half of post-IDCT table */
2697dd7cddfSDavid du Colombier MEMZERO(table + (2 * (MAXJSAMPLE+1)),
2707dd7cddfSDavid du Colombier (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
2717dd7cddfSDavid du Colombier MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
2727dd7cddfSDavid du Colombier cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
2737dd7cddfSDavid du Colombier }
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier
2767dd7cddfSDavid du Colombier /*
2777dd7cddfSDavid du Colombier * Master selection of decompression modules.
2787dd7cddfSDavid du Colombier * This is done once at jpeg_start_decompress time. We determine
2797dd7cddfSDavid du Colombier * which modules will be used and give them appropriate initialization calls.
2807dd7cddfSDavid du Colombier * We also initialize the decompressor input side to begin consuming data.
2817dd7cddfSDavid du Colombier *
2827dd7cddfSDavid du Colombier * Since jpeg_read_header has finished, we know what is in the SOF
2837dd7cddfSDavid du Colombier * and (first) SOS markers. We also have all the application parameter
2847dd7cddfSDavid du Colombier * settings.
2857dd7cddfSDavid du Colombier */
2867dd7cddfSDavid du Colombier
2877dd7cddfSDavid du Colombier LOCAL(void)
master_selection(j_decompress_ptr cinfo)2887dd7cddfSDavid du Colombier master_selection (j_decompress_ptr cinfo)
2897dd7cddfSDavid du Colombier {
2907dd7cddfSDavid du Colombier my_master_ptr master = (my_master_ptr) cinfo->master;
2917dd7cddfSDavid du Colombier boolean use_c_buffer;
2927dd7cddfSDavid du Colombier long samplesperrow;
2937dd7cddfSDavid du Colombier JDIMENSION jd_samplesperrow;
2947dd7cddfSDavid du Colombier
2957dd7cddfSDavid du Colombier /* Initialize dimensions and other stuff */
2967dd7cddfSDavid du Colombier jpeg_calc_output_dimensions(cinfo);
2977dd7cddfSDavid du Colombier prepare_range_limit_table(cinfo);
2987dd7cddfSDavid du Colombier
2997dd7cddfSDavid du Colombier /* Width of an output scanline must be representable as JDIMENSION. */
3007dd7cddfSDavid du Colombier samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
3017dd7cddfSDavid du Colombier jd_samplesperrow = (JDIMENSION) samplesperrow;
3027dd7cddfSDavid du Colombier if ((long) jd_samplesperrow != samplesperrow)
3037dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
3047dd7cddfSDavid du Colombier
3057dd7cddfSDavid du Colombier /* Initialize my private state */
3067dd7cddfSDavid du Colombier master->pass_number = 0;
3077dd7cddfSDavid du Colombier master->using_merged_upsample = use_merged_upsample(cinfo);
3087dd7cddfSDavid du Colombier
3097dd7cddfSDavid du Colombier /* Color quantizer selection */
3107dd7cddfSDavid du Colombier master->quantizer_1pass = NULL;
3117dd7cddfSDavid du Colombier master->quantizer_2pass = NULL;
3127dd7cddfSDavid du Colombier /* No mode changes if not using buffered-image mode. */
3137dd7cddfSDavid du Colombier if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
3147dd7cddfSDavid du Colombier cinfo->enable_1pass_quant = FALSE;
3157dd7cddfSDavid du Colombier cinfo->enable_external_quant = FALSE;
3167dd7cddfSDavid du Colombier cinfo->enable_2pass_quant = FALSE;
3177dd7cddfSDavid du Colombier }
3187dd7cddfSDavid du Colombier if (cinfo->quantize_colors) {
3197dd7cddfSDavid du Colombier if (cinfo->raw_data_out)
3207dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOTIMPL);
3217dd7cddfSDavid du Colombier /* 2-pass quantizer only works in 3-component color space. */
3227dd7cddfSDavid du Colombier if (cinfo->out_color_components != 3) {
3237dd7cddfSDavid du Colombier cinfo->enable_1pass_quant = TRUE;
3247dd7cddfSDavid du Colombier cinfo->enable_external_quant = FALSE;
3257dd7cddfSDavid du Colombier cinfo->enable_2pass_quant = FALSE;
3267dd7cddfSDavid du Colombier cinfo->colormap = NULL;
3277dd7cddfSDavid du Colombier } else if (cinfo->colormap != NULL) {
3287dd7cddfSDavid du Colombier cinfo->enable_external_quant = TRUE;
3297dd7cddfSDavid du Colombier } else if (cinfo->two_pass_quantize) {
3307dd7cddfSDavid du Colombier cinfo->enable_2pass_quant = TRUE;
3317dd7cddfSDavid du Colombier } else {
3327dd7cddfSDavid du Colombier cinfo->enable_1pass_quant = TRUE;
3337dd7cddfSDavid du Colombier }
3347dd7cddfSDavid du Colombier
3357dd7cddfSDavid du Colombier if (cinfo->enable_1pass_quant) {
3367dd7cddfSDavid du Colombier #ifdef QUANT_1PASS_SUPPORTED
3377dd7cddfSDavid du Colombier jinit_1pass_quantizer(cinfo);
3387dd7cddfSDavid du Colombier master->quantizer_1pass = cinfo->cquantize;
3397dd7cddfSDavid du Colombier #else
3407dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOT_COMPILED);
3417dd7cddfSDavid du Colombier #endif
3427dd7cddfSDavid du Colombier }
3437dd7cddfSDavid du Colombier
3447dd7cddfSDavid du Colombier /* We use the 2-pass code to map to external colormaps. */
3457dd7cddfSDavid du Colombier if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
3467dd7cddfSDavid du Colombier #ifdef QUANT_2PASS_SUPPORTED
3477dd7cddfSDavid du Colombier jinit_2pass_quantizer(cinfo);
3487dd7cddfSDavid du Colombier master->quantizer_2pass = cinfo->cquantize;
3497dd7cddfSDavid du Colombier #else
3507dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOT_COMPILED);
3517dd7cddfSDavid du Colombier #endif
3527dd7cddfSDavid du Colombier }
3537dd7cddfSDavid du Colombier /* If both quantizers are initialized, the 2-pass one is left active;
3547dd7cddfSDavid du Colombier * this is necessary for starting with quantization to an external map.
3557dd7cddfSDavid du Colombier */
3567dd7cddfSDavid du Colombier }
3577dd7cddfSDavid du Colombier
3587dd7cddfSDavid du Colombier /* Post-processing: in particular, color conversion first */
3597dd7cddfSDavid du Colombier if (! cinfo->raw_data_out) {
3607dd7cddfSDavid du Colombier if (master->using_merged_upsample) {
3617dd7cddfSDavid du Colombier #ifdef UPSAMPLE_MERGING_SUPPORTED
3627dd7cddfSDavid du Colombier jinit_merged_upsampler(cinfo); /* does color conversion too */
3637dd7cddfSDavid du Colombier #else
3647dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOT_COMPILED);
3657dd7cddfSDavid du Colombier #endif
3667dd7cddfSDavid du Colombier } else {
3677dd7cddfSDavid du Colombier jinit_color_deconverter(cinfo);
3687dd7cddfSDavid du Colombier jinit_upsampler(cinfo);
3697dd7cddfSDavid du Colombier }
3707dd7cddfSDavid du Colombier jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
3717dd7cddfSDavid du Colombier }
3727dd7cddfSDavid du Colombier /* Inverse DCT */
3737dd7cddfSDavid du Colombier jinit_inverse_dct(cinfo);
3747dd7cddfSDavid du Colombier /* Entropy decoding: either Huffman or arithmetic coding. */
3757dd7cddfSDavid du Colombier if (cinfo->arith_code) {
3767dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
3777dd7cddfSDavid du Colombier } else {
3787dd7cddfSDavid du Colombier if (cinfo->progressive_mode) {
3797dd7cddfSDavid du Colombier #ifdef D_PROGRESSIVE_SUPPORTED
3807dd7cddfSDavid du Colombier jinit_phuff_decoder(cinfo);
3817dd7cddfSDavid du Colombier #else
3827dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOT_COMPILED);
3837dd7cddfSDavid du Colombier #endif
3847dd7cddfSDavid du Colombier } else
3857dd7cddfSDavid du Colombier jinit_huff_decoder(cinfo);
3867dd7cddfSDavid du Colombier }
3877dd7cddfSDavid du Colombier
3887dd7cddfSDavid du Colombier /* Initialize principal buffer controllers. */
3897dd7cddfSDavid du Colombier use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
3907dd7cddfSDavid du Colombier jinit_d_coef_controller(cinfo, use_c_buffer);
3917dd7cddfSDavid du Colombier
3927dd7cddfSDavid du Colombier if (! cinfo->raw_data_out)
3937dd7cddfSDavid du Colombier jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
3947dd7cddfSDavid du Colombier
3957dd7cddfSDavid du Colombier /* We can now tell the memory manager to allocate virtual arrays. */
3967dd7cddfSDavid du Colombier (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
3977dd7cddfSDavid du Colombier
3987dd7cddfSDavid du Colombier /* Initialize input side of decompressor to consume first scan. */
3997dd7cddfSDavid du Colombier (*cinfo->inputctl->start_input_pass) (cinfo);
4007dd7cddfSDavid du Colombier
4017dd7cddfSDavid du Colombier #ifdef D_MULTISCAN_FILES_SUPPORTED
4027dd7cddfSDavid du Colombier /* If jpeg_start_decompress will read the whole file, initialize
4037dd7cddfSDavid du Colombier * progress monitoring appropriately. The input step is counted
4047dd7cddfSDavid du Colombier * as one pass.
4057dd7cddfSDavid du Colombier */
4067dd7cddfSDavid du Colombier if (cinfo->progress != NULL && ! cinfo->buffered_image &&
4077dd7cddfSDavid du Colombier cinfo->inputctl->has_multiple_scans) {
4087dd7cddfSDavid du Colombier int nscans;
4097dd7cddfSDavid du Colombier /* Estimate number of scans to set pass_limit. */
4107dd7cddfSDavid du Colombier if (cinfo->progressive_mode) {
4117dd7cddfSDavid du Colombier /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
4127dd7cddfSDavid du Colombier nscans = 2 + 3 * cinfo->num_components;
4137dd7cddfSDavid du Colombier } else {
4147dd7cddfSDavid du Colombier /* For a nonprogressive multiscan file, estimate 1 scan per component. */
4157dd7cddfSDavid du Colombier nscans = cinfo->num_components;
4167dd7cddfSDavid du Colombier }
4177dd7cddfSDavid du Colombier cinfo->progress->pass_counter = 0L;
4187dd7cddfSDavid du Colombier cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
4197dd7cddfSDavid du Colombier cinfo->progress->completed_passes = 0;
4207dd7cddfSDavid du Colombier cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
4217dd7cddfSDavid du Colombier /* Count the input pass as done */
4227dd7cddfSDavid du Colombier master->pass_number++;
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier #endif /* D_MULTISCAN_FILES_SUPPORTED */
4257dd7cddfSDavid du Colombier }
4267dd7cddfSDavid du Colombier
4277dd7cddfSDavid du Colombier
4287dd7cddfSDavid du Colombier /*
4297dd7cddfSDavid du Colombier * Per-pass setup.
4307dd7cddfSDavid du Colombier * This is called at the beginning of each output pass. We determine which
4317dd7cddfSDavid du Colombier * modules will be active during this pass and give them appropriate
4327dd7cddfSDavid du Colombier * start_pass calls. We also set is_dummy_pass to indicate whether this
4337dd7cddfSDavid du Colombier * is a "real" output pass or a dummy pass for color quantization.
434*593dc095SDavid du Colombier * (In the latter case, jdapistd.c will crank the pass to completion.)
4357dd7cddfSDavid du Colombier */
4367dd7cddfSDavid du Colombier
4377dd7cddfSDavid du Colombier METHODDEF(void)
prepare_for_output_pass(j_decompress_ptr cinfo)4387dd7cddfSDavid du Colombier prepare_for_output_pass (j_decompress_ptr cinfo)
4397dd7cddfSDavid du Colombier {
4407dd7cddfSDavid du Colombier my_master_ptr master = (my_master_ptr) cinfo->master;
4417dd7cddfSDavid du Colombier
4427dd7cddfSDavid du Colombier if (master->pub.is_dummy_pass) {
4437dd7cddfSDavid du Colombier #ifdef QUANT_2PASS_SUPPORTED
4447dd7cddfSDavid du Colombier /* Final pass of 2-pass quantization */
4457dd7cddfSDavid du Colombier master->pub.is_dummy_pass = FALSE;
4467dd7cddfSDavid du Colombier (*cinfo->cquantize->start_pass) (cinfo, FALSE);
4477dd7cddfSDavid du Colombier (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
4487dd7cddfSDavid du Colombier (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
4497dd7cddfSDavid du Colombier #else
4507dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOT_COMPILED);
4517dd7cddfSDavid du Colombier #endif /* QUANT_2PASS_SUPPORTED */
4527dd7cddfSDavid du Colombier } else {
4537dd7cddfSDavid du Colombier if (cinfo->quantize_colors && cinfo->colormap == NULL) {
4547dd7cddfSDavid du Colombier /* Select new quantization method */
4557dd7cddfSDavid du Colombier if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
4567dd7cddfSDavid du Colombier cinfo->cquantize = master->quantizer_2pass;
4577dd7cddfSDavid du Colombier master->pub.is_dummy_pass = TRUE;
4587dd7cddfSDavid du Colombier } else if (cinfo->enable_1pass_quant) {
4597dd7cddfSDavid du Colombier cinfo->cquantize = master->quantizer_1pass;
4607dd7cddfSDavid du Colombier } else {
4617dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_MODE_CHANGE);
4627dd7cddfSDavid du Colombier }
4637dd7cddfSDavid du Colombier }
4647dd7cddfSDavid du Colombier (*cinfo->idct->start_pass) (cinfo);
4657dd7cddfSDavid du Colombier (*cinfo->coef->start_output_pass) (cinfo);
4667dd7cddfSDavid du Colombier if (! cinfo->raw_data_out) {
4677dd7cddfSDavid du Colombier if (! master->using_merged_upsample)
4687dd7cddfSDavid du Colombier (*cinfo->cconvert->start_pass) (cinfo);
4697dd7cddfSDavid du Colombier (*cinfo->upsample->start_pass) (cinfo);
4707dd7cddfSDavid du Colombier if (cinfo->quantize_colors)
4717dd7cddfSDavid du Colombier (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
4727dd7cddfSDavid du Colombier (*cinfo->post->start_pass) (cinfo,
4737dd7cddfSDavid du Colombier (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
4747dd7cddfSDavid du Colombier (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
4757dd7cddfSDavid du Colombier }
4767dd7cddfSDavid du Colombier }
4777dd7cddfSDavid du Colombier
4787dd7cddfSDavid du Colombier /* Set up progress monitor's pass info if present */
4797dd7cddfSDavid du Colombier if (cinfo->progress != NULL) {
4807dd7cddfSDavid du Colombier cinfo->progress->completed_passes = master->pass_number;
4817dd7cddfSDavid du Colombier cinfo->progress->total_passes = master->pass_number +
4827dd7cddfSDavid du Colombier (master->pub.is_dummy_pass ? 2 : 1);
4837dd7cddfSDavid du Colombier /* In buffered-image mode, we assume one more output pass if EOI not
4847dd7cddfSDavid du Colombier * yet reached, but no more passes if EOI has been reached.
4857dd7cddfSDavid du Colombier */
4867dd7cddfSDavid du Colombier if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
4877dd7cddfSDavid du Colombier cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
4887dd7cddfSDavid du Colombier }
4897dd7cddfSDavid du Colombier }
4907dd7cddfSDavid du Colombier }
4917dd7cddfSDavid du Colombier
4927dd7cddfSDavid du Colombier
4937dd7cddfSDavid du Colombier /*
4947dd7cddfSDavid du Colombier * Finish up at end of an output pass.
4957dd7cddfSDavid du Colombier */
4967dd7cddfSDavid du Colombier
4977dd7cddfSDavid du Colombier METHODDEF(void)
finish_output_pass(j_decompress_ptr cinfo)4987dd7cddfSDavid du Colombier finish_output_pass (j_decompress_ptr cinfo)
4997dd7cddfSDavid du Colombier {
5007dd7cddfSDavid du Colombier my_master_ptr master = (my_master_ptr) cinfo->master;
5017dd7cddfSDavid du Colombier
5027dd7cddfSDavid du Colombier if (cinfo->quantize_colors)
5037dd7cddfSDavid du Colombier (*cinfo->cquantize->finish_pass) (cinfo);
5047dd7cddfSDavid du Colombier master->pass_number++;
5057dd7cddfSDavid du Colombier }
5067dd7cddfSDavid du Colombier
5077dd7cddfSDavid du Colombier
5087dd7cddfSDavid du Colombier #ifdef D_MULTISCAN_FILES_SUPPORTED
5097dd7cddfSDavid du Colombier
5107dd7cddfSDavid du Colombier /*
5117dd7cddfSDavid du Colombier * Switch to a new external colormap between output passes.
5127dd7cddfSDavid du Colombier */
5137dd7cddfSDavid du Colombier
5147dd7cddfSDavid du Colombier GLOBAL(void)
jpeg_new_colormap(j_decompress_ptr cinfo)5157dd7cddfSDavid du Colombier jpeg_new_colormap (j_decompress_ptr cinfo)
5167dd7cddfSDavid du Colombier {
5177dd7cddfSDavid du Colombier my_master_ptr master = (my_master_ptr) cinfo->master;
5187dd7cddfSDavid du Colombier
5197dd7cddfSDavid du Colombier /* Prevent application from calling me at wrong times */
5207dd7cddfSDavid du Colombier if (cinfo->global_state != DSTATE_BUFIMAGE)
5217dd7cddfSDavid du Colombier ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
5227dd7cddfSDavid du Colombier
5237dd7cddfSDavid du Colombier if (cinfo->quantize_colors && cinfo->enable_external_quant &&
5247dd7cddfSDavid du Colombier cinfo->colormap != NULL) {
5257dd7cddfSDavid du Colombier /* Select 2-pass quantizer for external colormap use */
5267dd7cddfSDavid du Colombier cinfo->cquantize = master->quantizer_2pass;
5277dd7cddfSDavid du Colombier /* Notify quantizer of colormap change */
5287dd7cddfSDavid du Colombier (*cinfo->cquantize->new_color_map) (cinfo);
5297dd7cddfSDavid du Colombier master->pub.is_dummy_pass = FALSE; /* just in case */
5307dd7cddfSDavid du Colombier } else
5317dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_MODE_CHANGE);
5327dd7cddfSDavid du Colombier }
5337dd7cddfSDavid du Colombier
5347dd7cddfSDavid du Colombier #endif /* D_MULTISCAN_FILES_SUPPORTED */
5357dd7cddfSDavid du Colombier
5367dd7cddfSDavid du Colombier
5377dd7cddfSDavid du Colombier /*
5387dd7cddfSDavid du Colombier * Initialize master decompression control and select active modules.
5397dd7cddfSDavid du Colombier * This is performed at the start of jpeg_start_decompress.
5407dd7cddfSDavid du Colombier */
5417dd7cddfSDavid du Colombier
5427dd7cddfSDavid du Colombier GLOBAL(void)
jinit_master_decompress(j_decompress_ptr cinfo)5437dd7cddfSDavid du Colombier jinit_master_decompress (j_decompress_ptr cinfo)
5447dd7cddfSDavid du Colombier {
5457dd7cddfSDavid du Colombier my_master_ptr master;
5467dd7cddfSDavid du Colombier
5477dd7cddfSDavid du Colombier master = (my_master_ptr)
5487dd7cddfSDavid du Colombier (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
5497dd7cddfSDavid du Colombier SIZEOF(my_decomp_master));
5507dd7cddfSDavid du Colombier cinfo->master = (struct jpeg_decomp_master *) master;
5517dd7cddfSDavid du Colombier master->pub.prepare_for_output_pass = prepare_for_output_pass;
5527dd7cddfSDavid du Colombier master->pub.finish_output_pass = finish_output_pass;
5537dd7cddfSDavid du Colombier
5547dd7cddfSDavid du Colombier master->pub.is_dummy_pass = FALSE;
5557dd7cddfSDavid du Colombier
5567dd7cddfSDavid du Colombier master_selection(cinfo);
5577dd7cddfSDavid du Colombier }
558