michael@0: /* michael@0: * jdmaster.c michael@0: * michael@0: * This file was part of the Independent JPEG Group's software: michael@0: * Copyright (C) 1991-1997, Thomas G. Lane. michael@0: * Modified 2002-2009 by Guido Vollbeding. michael@0: * libjpeg-turbo Modifications: michael@0: * Copyright (C) 2009-2011, D. R. Commander. michael@0: * For conditions of distribution and use, see the accompanying README file. michael@0: * michael@0: * This file contains master control logic for the JPEG decompressor. michael@0: * These routines are concerned with selecting the modules to be executed michael@0: * and with determining the number of passes and the work to be done in each michael@0: * pass. michael@0: */ michael@0: michael@0: #define JPEG_INTERNALS michael@0: #include "jinclude.h" michael@0: #include "jpeglib.h" michael@0: #include "jpegcomp.h" michael@0: michael@0: michael@0: /* Private state */ michael@0: michael@0: typedef struct { michael@0: struct jpeg_decomp_master pub; /* public fields */ michael@0: michael@0: int pass_number; /* # of passes completed */ michael@0: michael@0: boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ michael@0: michael@0: /* Saved references to initialized quantizer modules, michael@0: * in case we need to switch modes. michael@0: */ michael@0: struct jpeg_color_quantizer * quantizer_1pass; michael@0: struct jpeg_color_quantizer * quantizer_2pass; michael@0: } my_decomp_master; michael@0: michael@0: typedef my_decomp_master * my_master_ptr; michael@0: michael@0: michael@0: /* michael@0: * Determine whether merged upsample/color conversion should be used. michael@0: * CRUCIAL: this must match the actual capabilities of jdmerge.c! michael@0: */ michael@0: michael@0: LOCAL(boolean) michael@0: use_merged_upsample (j_decompress_ptr cinfo) michael@0: { michael@0: #ifdef UPSAMPLE_MERGING_SUPPORTED michael@0: /* Merging is the equivalent of plain box-filter upsampling */ michael@0: if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) michael@0: return FALSE; michael@0: /* jdmerge.c only supports YCC=>RGB color conversion */ michael@0: if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || michael@0: (cinfo->out_color_space != JCS_RGB && michael@0: cinfo->out_color_space != JCS_EXT_RGB && michael@0: cinfo->out_color_space != JCS_EXT_RGBX && michael@0: cinfo->out_color_space != JCS_EXT_BGR && michael@0: cinfo->out_color_space != JCS_EXT_BGRX && michael@0: cinfo->out_color_space != JCS_EXT_XBGR && michael@0: cinfo->out_color_space != JCS_EXT_XRGB && michael@0: cinfo->out_color_space != JCS_EXT_RGBA && michael@0: cinfo->out_color_space != JCS_EXT_BGRA && michael@0: cinfo->out_color_space != JCS_EXT_ABGR && michael@0: cinfo->out_color_space != JCS_EXT_ARGB) || michael@0: cinfo->out_color_components != rgb_pixelsize[cinfo->out_color_space]) michael@0: return FALSE; michael@0: /* and it only handles 2h1v or 2h2v sampling ratios */ michael@0: if (cinfo->comp_info[0].h_samp_factor != 2 || michael@0: cinfo->comp_info[1].h_samp_factor != 1 || michael@0: cinfo->comp_info[2].h_samp_factor != 1 || michael@0: cinfo->comp_info[0].v_samp_factor > 2 || michael@0: cinfo->comp_info[1].v_samp_factor != 1 || michael@0: cinfo->comp_info[2].v_samp_factor != 1) michael@0: return FALSE; michael@0: /* furthermore, it doesn't work if we've scaled the IDCTs differently */ michael@0: if (cinfo->comp_info[0]._DCT_scaled_size != cinfo->_min_DCT_scaled_size || michael@0: cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size || michael@0: cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size) michael@0: return FALSE; michael@0: /* ??? also need to test for upsample-time rescaling, when & if supported */ michael@0: return TRUE; /* by golly, it'll work... */ michael@0: #else michael@0: return FALSE; michael@0: #endif michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Compute output image dimensions and related values. michael@0: * NOTE: this is exported for possible use by application. michael@0: * Hence it mustn't do anything that can't be done twice. michael@0: */ michael@0: michael@0: #if JPEG_LIB_VERSION >= 80 michael@0: GLOBAL(void) michael@0: #else michael@0: LOCAL(void) michael@0: #endif michael@0: jpeg_core_output_dimensions (j_decompress_ptr cinfo) michael@0: /* Do computations that are needed before master selection phase. michael@0: * This function is used for transcoding and full decompression. michael@0: */ michael@0: { michael@0: #ifdef IDCT_SCALING_SUPPORTED michael@0: int ci; michael@0: jpeg_component_info *compptr; michael@0: michael@0: /* Compute actual output image dimensions and DCT scaling choices. */ michael@0: if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom) { michael@0: /* Provide 1/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 1; michael@0: cinfo->_min_DCT_v_scaled_size = 1; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 2) { michael@0: /* Provide 2/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 2L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 2L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 2; michael@0: cinfo->_min_DCT_v_scaled_size = 2; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 3) { michael@0: /* Provide 3/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 3L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 3L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 3; michael@0: cinfo->_min_DCT_v_scaled_size = 3; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 4) { michael@0: /* Provide 4/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 4L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 4L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 4; michael@0: cinfo->_min_DCT_v_scaled_size = 4; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 5) { michael@0: /* Provide 5/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 5L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 5L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 5; michael@0: cinfo->_min_DCT_v_scaled_size = 5; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 6) { michael@0: /* Provide 6/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 6L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 6L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 6; michael@0: cinfo->_min_DCT_v_scaled_size = 6; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 7) { michael@0: /* Provide 7/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 7L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 7L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 7; michael@0: cinfo->_min_DCT_v_scaled_size = 7; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 8) { michael@0: /* Provide 8/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 8L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 8L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 8; michael@0: cinfo->_min_DCT_v_scaled_size = 8; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 9) { michael@0: /* Provide 9/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 9L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 9L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 9; michael@0: cinfo->_min_DCT_v_scaled_size = 9; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 10) { michael@0: /* Provide 10/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 10L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 10L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 10; michael@0: cinfo->_min_DCT_v_scaled_size = 10; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 11) { michael@0: /* Provide 11/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 11L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 11L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 11; michael@0: cinfo->_min_DCT_v_scaled_size = 11; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 12) { michael@0: /* Provide 12/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 12L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 12L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 12; michael@0: cinfo->_min_DCT_v_scaled_size = 12; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 13) { michael@0: /* Provide 13/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 13L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 13L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 13; michael@0: cinfo->_min_DCT_v_scaled_size = 13; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 14) { michael@0: /* Provide 14/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 14L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 14L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 14; michael@0: cinfo->_min_DCT_v_scaled_size = 14; michael@0: } else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 15) { michael@0: /* Provide 15/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 15L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 15L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 15; michael@0: cinfo->_min_DCT_v_scaled_size = 15; michael@0: } else { michael@0: /* Provide 16/block_size scaling */ michael@0: cinfo->output_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * 16L, (long) DCTSIZE); michael@0: cinfo->output_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * 16L, (long) DCTSIZE); michael@0: cinfo->_min_DCT_h_scaled_size = 16; michael@0: cinfo->_min_DCT_v_scaled_size = 16; michael@0: } michael@0: michael@0: /* Recompute dimensions of components */ michael@0: for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; michael@0: ci++, compptr++) { michael@0: compptr->_DCT_h_scaled_size = cinfo->_min_DCT_h_scaled_size; michael@0: compptr->_DCT_v_scaled_size = cinfo->_min_DCT_v_scaled_size; michael@0: } michael@0: michael@0: #else /* !IDCT_SCALING_SUPPORTED */ michael@0: michael@0: /* Hardwire it to "no scaling" */ michael@0: cinfo->output_width = cinfo->image_width; michael@0: cinfo->output_height = cinfo->image_height; michael@0: /* jdinput.c has already initialized DCT_scaled_size, michael@0: * and has computed unscaled downsampled_width and downsampled_height. michael@0: */ michael@0: michael@0: #endif /* IDCT_SCALING_SUPPORTED */ michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Compute output image dimensions and related values. michael@0: * NOTE: this is exported for possible use by application. michael@0: * Hence it mustn't do anything that can't be done twice. michael@0: * Also note that it may be called before the master module is initialized! michael@0: */ michael@0: michael@0: GLOBAL(void) michael@0: jpeg_calc_output_dimensions (j_decompress_ptr cinfo) michael@0: /* Do computations that are needed before master selection phase */ michael@0: { michael@0: #ifdef IDCT_SCALING_SUPPORTED michael@0: int ci; michael@0: jpeg_component_info *compptr; michael@0: #endif michael@0: michael@0: /* Prevent application from calling me at wrong times */ michael@0: if (cinfo->global_state != DSTATE_READY) michael@0: ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); michael@0: michael@0: /* Compute core output image dimensions and DCT scaling choices. */ michael@0: jpeg_core_output_dimensions(cinfo); michael@0: michael@0: #ifdef IDCT_SCALING_SUPPORTED michael@0: michael@0: /* In selecting the actual DCT scaling for each component, we try to michael@0: * scale up the chroma components via IDCT scaling rather than upsampling. michael@0: * This saves time if the upsampler gets to use 1:1 scaling. michael@0: * Note this code adapts subsampling ratios which are powers of 2. michael@0: */ michael@0: for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; michael@0: ci++, compptr++) { michael@0: int ssize = cinfo->_min_DCT_scaled_size; michael@0: while (ssize < DCTSIZE && michael@0: ((cinfo->max_h_samp_factor * cinfo->_min_DCT_scaled_size) % michael@0: (compptr->h_samp_factor * ssize * 2) == 0) && michael@0: ((cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size) % michael@0: (compptr->v_samp_factor * ssize * 2) == 0)) { michael@0: ssize = ssize * 2; michael@0: } michael@0: #if JPEG_LIB_VERSION >= 70 michael@0: compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = ssize; michael@0: #else michael@0: compptr->DCT_scaled_size = ssize; michael@0: #endif michael@0: } michael@0: michael@0: /* Recompute downsampled dimensions of components; michael@0: * application needs to know these if using raw downsampled data. michael@0: */ michael@0: for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; michael@0: ci++, compptr++) { michael@0: /* Size in samples, after IDCT scaling */ michael@0: compptr->downsampled_width = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_width * michael@0: (long) (compptr->h_samp_factor * compptr->_DCT_scaled_size), michael@0: (long) (cinfo->max_h_samp_factor * DCTSIZE)); michael@0: compptr->downsampled_height = (JDIMENSION) michael@0: jdiv_round_up((long) cinfo->image_height * michael@0: (long) (compptr->v_samp_factor * compptr->_DCT_scaled_size), michael@0: (long) (cinfo->max_v_samp_factor * DCTSIZE)); michael@0: } michael@0: michael@0: #else /* !IDCT_SCALING_SUPPORTED */ michael@0: michael@0: /* Hardwire it to "no scaling" */ michael@0: cinfo->output_width = cinfo->image_width; michael@0: cinfo->output_height = cinfo->image_height; michael@0: /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, michael@0: * and has computed unscaled downsampled_width and downsampled_height. michael@0: */ michael@0: michael@0: #endif /* IDCT_SCALING_SUPPORTED */ michael@0: michael@0: /* Report number of components in selected colorspace. */ michael@0: /* Probably this should be in the color conversion module... */ michael@0: switch (cinfo->out_color_space) { michael@0: case JCS_GRAYSCALE: michael@0: cinfo->out_color_components = 1; michael@0: break; michael@0: case JCS_RGB: michael@0: case JCS_EXT_RGB: michael@0: case JCS_EXT_RGBX: michael@0: case JCS_EXT_BGR: michael@0: case JCS_EXT_BGRX: michael@0: case JCS_EXT_XBGR: michael@0: case JCS_EXT_XRGB: michael@0: case JCS_EXT_RGBA: michael@0: case JCS_EXT_BGRA: michael@0: case JCS_EXT_ABGR: michael@0: case JCS_EXT_ARGB: michael@0: cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space]; michael@0: break; michael@0: case JCS_YCbCr: michael@0: cinfo->out_color_components = 3; michael@0: break; michael@0: case JCS_CMYK: michael@0: case JCS_YCCK: michael@0: cinfo->out_color_components = 4; michael@0: break; michael@0: default: /* else must be same colorspace as in file */ michael@0: cinfo->out_color_components = cinfo->num_components; michael@0: break; michael@0: } michael@0: cinfo->output_components = (cinfo->quantize_colors ? 1 : michael@0: cinfo->out_color_components); michael@0: michael@0: /* See if upsampler will want to emit more than one row at a time */ michael@0: if (use_merged_upsample(cinfo)) michael@0: cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; michael@0: else michael@0: cinfo->rec_outbuf_height = 1; michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Several decompression processes need to range-limit values to the range michael@0: * 0..MAXJSAMPLE; the input value may fall somewhat outside this range michael@0: * due to noise introduced by quantization, roundoff error, etc. These michael@0: * processes are inner loops and need to be as fast as possible. On most michael@0: * machines, particularly CPUs with pipelines or instruction prefetch, michael@0: * a (subscript-check-less) C table lookup michael@0: * x = sample_range_limit[x]; michael@0: * is faster than explicit tests michael@0: * if (x < 0) x = 0; michael@0: * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; michael@0: * These processes all use a common table prepared by the routine below. michael@0: * michael@0: * For most steps we can mathematically guarantee that the initial value michael@0: * of x is within MAXJSAMPLE+1 of the legal range, so a table running from michael@0: * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial michael@0: * limiting step (just after the IDCT), a wildly out-of-range value is michael@0: * possible if the input data is corrupt. To avoid any chance of indexing michael@0: * off the end of memory and getting a bad-pointer trap, we perform the michael@0: * post-IDCT limiting thus: michael@0: * x = range_limit[x & MASK]; michael@0: * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit michael@0: * samples. Under normal circumstances this is more than enough range and michael@0: * a correct output will be generated; with bogus input data the mask will michael@0: * cause wraparound, and we will safely generate a bogus-but-in-range output. michael@0: * For the post-IDCT step, we want to convert the data from signed to unsigned michael@0: * representation by adding CENTERJSAMPLE at the same time that we limit it. michael@0: * So the post-IDCT limiting table ends up looking like this: michael@0: * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, michael@0: * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), michael@0: * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), michael@0: * 0,1,...,CENTERJSAMPLE-1 michael@0: * Negative inputs select values from the upper half of the table after michael@0: * masking. michael@0: * michael@0: * We can save some space by overlapping the start of the post-IDCT table michael@0: * with the simpler range limiting table. The post-IDCT table begins at michael@0: * sample_range_limit + CENTERJSAMPLE. michael@0: * michael@0: * Note that the table is allocated in near data space on PCs; it's small michael@0: * enough and used often enough to justify this. michael@0: */ michael@0: michael@0: LOCAL(void) michael@0: prepare_range_limit_table (j_decompress_ptr cinfo) michael@0: /* Allocate and fill in the sample_range_limit table */ michael@0: { michael@0: JSAMPLE * table; michael@0: int i; michael@0: michael@0: table = (JSAMPLE *) michael@0: (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, michael@0: (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); michael@0: table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ michael@0: cinfo->sample_range_limit = table; michael@0: /* First segment of "simple" table: limit[x] = 0 for x < 0 */ michael@0: MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); michael@0: /* Main part of "simple" table: limit[x] = x */ michael@0: for (i = 0; i <= MAXJSAMPLE; i++) michael@0: table[i] = (JSAMPLE) i; michael@0: table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ michael@0: /* End of simple table, rest of first half of post-IDCT table */ michael@0: for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) michael@0: table[i] = MAXJSAMPLE; michael@0: /* Second half of post-IDCT table */ michael@0: MEMZERO(table + (2 * (MAXJSAMPLE+1)), michael@0: (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); michael@0: MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), michael@0: cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Master selection of decompression modules. michael@0: * This is done once at jpeg_start_decompress time. We determine michael@0: * which modules will be used and give them appropriate initialization calls. michael@0: * We also initialize the decompressor input side to begin consuming data. michael@0: * michael@0: * Since jpeg_read_header has finished, we know what is in the SOF michael@0: * and (first) SOS markers. We also have all the application parameter michael@0: * settings. michael@0: */ michael@0: michael@0: LOCAL(void) michael@0: master_selection (j_decompress_ptr cinfo) michael@0: { michael@0: my_master_ptr master = (my_master_ptr) cinfo->master; michael@0: boolean use_c_buffer; michael@0: long samplesperrow; michael@0: JDIMENSION jd_samplesperrow; michael@0: michael@0: /* Initialize dimensions and other stuff */ michael@0: jpeg_calc_output_dimensions(cinfo); michael@0: prepare_range_limit_table(cinfo); michael@0: michael@0: /* Width of an output scanline must be representable as JDIMENSION. */ michael@0: samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; michael@0: jd_samplesperrow = (JDIMENSION) samplesperrow; michael@0: if ((long) jd_samplesperrow != samplesperrow) michael@0: ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); michael@0: michael@0: /* Initialize my private state */ michael@0: master->pass_number = 0; michael@0: master->using_merged_upsample = use_merged_upsample(cinfo); michael@0: michael@0: /* Color quantizer selection */ michael@0: master->quantizer_1pass = NULL; michael@0: master->quantizer_2pass = NULL; michael@0: /* No mode changes if not using buffered-image mode. */ michael@0: if (! cinfo->quantize_colors || ! cinfo->buffered_image) { michael@0: cinfo->enable_1pass_quant = FALSE; michael@0: cinfo->enable_external_quant = FALSE; michael@0: cinfo->enable_2pass_quant = FALSE; michael@0: } michael@0: if (cinfo->quantize_colors) { michael@0: if (cinfo->raw_data_out) michael@0: ERREXIT(cinfo, JERR_NOTIMPL); michael@0: /* 2-pass quantizer only works in 3-component color space. */ michael@0: if (cinfo->out_color_components != 3) { michael@0: cinfo->enable_1pass_quant = TRUE; michael@0: cinfo->enable_external_quant = FALSE; michael@0: cinfo->enable_2pass_quant = FALSE; michael@0: cinfo->colormap = NULL; michael@0: } else if (cinfo->colormap != NULL) { michael@0: cinfo->enable_external_quant = TRUE; michael@0: } else if (cinfo->two_pass_quantize) { michael@0: cinfo->enable_2pass_quant = TRUE; michael@0: } else { michael@0: cinfo->enable_1pass_quant = TRUE; michael@0: } michael@0: michael@0: if (cinfo->enable_1pass_quant) { michael@0: #ifdef QUANT_1PASS_SUPPORTED michael@0: jinit_1pass_quantizer(cinfo); michael@0: master->quantizer_1pass = cinfo->cquantize; michael@0: #else michael@0: ERREXIT(cinfo, JERR_NOT_COMPILED); michael@0: #endif michael@0: } michael@0: michael@0: /* We use the 2-pass code to map to external colormaps. */ michael@0: if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { michael@0: #ifdef QUANT_2PASS_SUPPORTED michael@0: jinit_2pass_quantizer(cinfo); michael@0: master->quantizer_2pass = cinfo->cquantize; michael@0: #else michael@0: ERREXIT(cinfo, JERR_NOT_COMPILED); michael@0: #endif michael@0: } michael@0: /* If both quantizers are initialized, the 2-pass one is left active; michael@0: * this is necessary for starting with quantization to an external map. michael@0: */ michael@0: } michael@0: michael@0: /* Post-processing: in particular, color conversion first */ michael@0: if (! cinfo->raw_data_out) { michael@0: if (master->using_merged_upsample) { michael@0: #ifdef UPSAMPLE_MERGING_SUPPORTED michael@0: jinit_merged_upsampler(cinfo); /* does color conversion too */ michael@0: #else michael@0: ERREXIT(cinfo, JERR_NOT_COMPILED); michael@0: #endif michael@0: } else { michael@0: jinit_color_deconverter(cinfo); michael@0: jinit_upsampler(cinfo); michael@0: } michael@0: jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); michael@0: } michael@0: /* Inverse DCT */ michael@0: jinit_inverse_dct(cinfo); michael@0: /* Entropy decoding: either Huffman or arithmetic coding. */ michael@0: if (cinfo->arith_code) { michael@0: #ifdef D_ARITH_CODING_SUPPORTED michael@0: jinit_arith_decoder(cinfo); michael@0: #else michael@0: ERREXIT(cinfo, JERR_ARITH_NOTIMPL); michael@0: #endif michael@0: } else { michael@0: if (cinfo->progressive_mode) { michael@0: #ifdef D_PROGRESSIVE_SUPPORTED michael@0: jinit_phuff_decoder(cinfo); michael@0: #else michael@0: ERREXIT(cinfo, JERR_NOT_COMPILED); michael@0: #endif michael@0: } else michael@0: jinit_huff_decoder(cinfo); michael@0: } michael@0: michael@0: /* Initialize principal buffer controllers. */ michael@0: use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; michael@0: jinit_d_coef_controller(cinfo, use_c_buffer); michael@0: michael@0: if (! cinfo->raw_data_out) michael@0: jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); michael@0: michael@0: /* We can now tell the memory manager to allocate virtual arrays. */ michael@0: (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); michael@0: michael@0: /* Initialize input side of decompressor to consume first scan. */ michael@0: (*cinfo->inputctl->start_input_pass) (cinfo); michael@0: michael@0: #ifdef D_MULTISCAN_FILES_SUPPORTED michael@0: /* If jpeg_start_decompress will read the whole file, initialize michael@0: * progress monitoring appropriately. The input step is counted michael@0: * as one pass. michael@0: */ michael@0: if (cinfo->progress != NULL && ! cinfo->buffered_image && michael@0: cinfo->inputctl->has_multiple_scans) { michael@0: int nscans; michael@0: /* Estimate number of scans to set pass_limit. */ michael@0: if (cinfo->progressive_mode) { michael@0: /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ michael@0: nscans = 2 + 3 * cinfo->num_components; michael@0: } else { michael@0: /* For a nonprogressive multiscan file, estimate 1 scan per component. */ michael@0: nscans = cinfo->num_components; michael@0: } michael@0: cinfo->progress->pass_counter = 0L; michael@0: cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; michael@0: cinfo->progress->completed_passes = 0; michael@0: cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); michael@0: /* Count the input pass as done */ michael@0: master->pass_number++; michael@0: } michael@0: #endif /* D_MULTISCAN_FILES_SUPPORTED */ michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Per-pass setup. michael@0: * This is called at the beginning of each output pass. We determine which michael@0: * modules will be active during this pass and give them appropriate michael@0: * start_pass calls. We also set is_dummy_pass to indicate whether this michael@0: * is a "real" output pass or a dummy pass for color quantization. michael@0: * (In the latter case, jdapistd.c will crank the pass to completion.) michael@0: */ michael@0: michael@0: METHODDEF(void) michael@0: prepare_for_output_pass (j_decompress_ptr cinfo) michael@0: { michael@0: my_master_ptr master = (my_master_ptr) cinfo->master; michael@0: michael@0: if (master->pub.is_dummy_pass) { michael@0: #ifdef QUANT_2PASS_SUPPORTED michael@0: /* Final pass of 2-pass quantization */ michael@0: master->pub.is_dummy_pass = FALSE; michael@0: (*cinfo->cquantize->start_pass) (cinfo, FALSE); michael@0: (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); michael@0: (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); michael@0: #else michael@0: ERREXIT(cinfo, JERR_NOT_COMPILED); michael@0: #endif /* QUANT_2PASS_SUPPORTED */ michael@0: } else { michael@0: if (cinfo->quantize_colors && cinfo->colormap == NULL) { michael@0: /* Select new quantization method */ michael@0: if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { michael@0: cinfo->cquantize = master->quantizer_2pass; michael@0: master->pub.is_dummy_pass = TRUE; michael@0: } else if (cinfo->enable_1pass_quant) { michael@0: cinfo->cquantize = master->quantizer_1pass; michael@0: } else { michael@0: ERREXIT(cinfo, JERR_MODE_CHANGE); michael@0: } michael@0: } michael@0: (*cinfo->idct->start_pass) (cinfo); michael@0: (*cinfo->coef->start_output_pass) (cinfo); michael@0: if (! cinfo->raw_data_out) { michael@0: if (! master->using_merged_upsample) michael@0: (*cinfo->cconvert->start_pass) (cinfo); michael@0: (*cinfo->upsample->start_pass) (cinfo); michael@0: if (cinfo->quantize_colors) michael@0: (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); michael@0: (*cinfo->post->start_pass) (cinfo, michael@0: (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); michael@0: (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); michael@0: } michael@0: } michael@0: michael@0: /* Set up progress monitor's pass info if present */ michael@0: if (cinfo->progress != NULL) { michael@0: cinfo->progress->completed_passes = master->pass_number; michael@0: cinfo->progress->total_passes = master->pass_number + michael@0: (master->pub.is_dummy_pass ? 2 : 1); michael@0: /* In buffered-image mode, we assume one more output pass if EOI not michael@0: * yet reached, but no more passes if EOI has been reached. michael@0: */ michael@0: if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { michael@0: cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); michael@0: } michael@0: } michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Finish up at end of an output pass. michael@0: */ michael@0: michael@0: METHODDEF(void) michael@0: finish_output_pass (j_decompress_ptr cinfo) michael@0: { michael@0: my_master_ptr master = (my_master_ptr) cinfo->master; michael@0: michael@0: if (cinfo->quantize_colors) michael@0: (*cinfo->cquantize->finish_pass) (cinfo); michael@0: master->pass_number++; michael@0: } michael@0: michael@0: michael@0: #ifdef D_MULTISCAN_FILES_SUPPORTED michael@0: michael@0: /* michael@0: * Switch to a new external colormap between output passes. michael@0: */ michael@0: michael@0: GLOBAL(void) michael@0: jpeg_new_colormap (j_decompress_ptr cinfo) michael@0: { michael@0: my_master_ptr master = (my_master_ptr) cinfo->master; michael@0: michael@0: /* Prevent application from calling me at wrong times */ michael@0: if (cinfo->global_state != DSTATE_BUFIMAGE) michael@0: ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); michael@0: michael@0: if (cinfo->quantize_colors && cinfo->enable_external_quant && michael@0: cinfo->colormap != NULL) { michael@0: /* Select 2-pass quantizer for external colormap use */ michael@0: cinfo->cquantize = master->quantizer_2pass; michael@0: /* Notify quantizer of colormap change */ michael@0: (*cinfo->cquantize->new_color_map) (cinfo); michael@0: master->pub.is_dummy_pass = FALSE; /* just in case */ michael@0: } else michael@0: ERREXIT(cinfo, JERR_MODE_CHANGE); michael@0: } michael@0: michael@0: #endif /* D_MULTISCAN_FILES_SUPPORTED */ michael@0: michael@0: michael@0: /* michael@0: * Initialize master decompression control and select active modules. michael@0: * This is performed at the start of jpeg_start_decompress. michael@0: */ michael@0: michael@0: GLOBAL(void) michael@0: jinit_master_decompress (j_decompress_ptr cinfo) michael@0: { michael@0: my_master_ptr master; michael@0: michael@0: master = (my_master_ptr) michael@0: (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, michael@0: SIZEOF(my_decomp_master)); michael@0: cinfo->master = (struct jpeg_decomp_master *) master; michael@0: master->pub.prepare_for_output_pass = prepare_for_output_pass; michael@0: master->pub.finish_output_pass = finish_output_pass; michael@0: michael@0: master->pub.is_dummy_pass = FALSE; michael@0: michael@0: master_selection(cinfo); michael@0: }