jpeg_init_read_tile_scanline(j_decompress_ptr cinfo, huffman_index *index, int *start_x, int *start_y, int *width, int *height) { int lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; int lines_per_iMCU_col = cinfo->max_h_samp_factor * DCTSIZE; int row_offset = *start_y / lines_per_iMCU_row; int col_left_boundary = ((*start_x / lines_per_iMCU_col) / index->MCU_sample_size) * index->MCU_sample_size; int col_right_boundary = jdiv_round_up(*start_x + *width, lines_per_iMCU_col); cinfo->coef->MCU_columns_to_skip = *start_x / lines_per_iMCU_col - col_left_boundary; *height = (*start_y - row_offset * lines_per_iMCU_row) + *height; *start_x = col_left_boundary * lines_per_iMCU_col; *start_y = row_offset * lines_per_iMCU_row; cinfo->image_width = jmin(cinfo->original_image_width, col_right_boundary * lines_per_iMCU_col) - col_left_boundary * lines_per_iMCU_col; cinfo->input_iMCU_row = row_offset; cinfo->output_iMCU_row = row_offset; jinit_color_deconverter(cinfo); jpeg_calc_output_dimensions(cinfo); jinit_upsampler(cinfo); (*cinfo->master->prepare_for_output_pass) (cinfo); if (cinfo->progressive_mode) (*cinfo->entropy->start_pass) (cinfo); else jpeg_decompress_per_scan_setup(cinfo); int sample_size = DCTSIZE / cinfo->min_DCT_scaled_size; *height = jdiv_round_up(*height, sample_size); *width = cinfo->output_width; cinfo->output_scanline = lines_per_iMCU_row * row_offset / sample_size; cinfo->inputctl->consume_input = cinfo->coef->consume_data; cinfo->inputctl->consume_input_build_huffman_index = cinfo->coef->consume_data_build_huffman_index; cinfo->entropy->index = index; cinfo->input_iMCU_row = row_offset; cinfo->output_iMCU_row = row_offset; cinfo->coef->MCU_column_left_boundary = col_left_boundary; cinfo->coef->MCU_column_right_boundary = col_right_boundary; cinfo->coef->column_left_boundary = col_left_boundary / index->MCU_sample_size; cinfo->coef->column_right_boundary = jdiv_round_up(col_right_boundary, index->MCU_sample_size); }
LOCAL void master_selection (j_decompress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; boolean use_c_buffer; long samplesperrow; JDIMENSION jd_samplesperrow; /* Initialize dimensions and other stuff */ jpeg_calc_output_dimensions(cinfo); prepare_range_limit_table(cinfo); /* Width of an output scanline must be representable as JDIMENSION. */ samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; jd_samplesperrow = (JDIMENSION) samplesperrow; if ((long) jd_samplesperrow != samplesperrow) ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); /* Initialize my private state */ master->pass_number = 0; master->using_merged_upsample = use_merged_upsample(cinfo); /* Color quantizer selection */ master->quantizer_1pass = NULL; master->quantizer_2pass = NULL; /* No mode changes if not using buffered-image mode. */ if (! cinfo->quantize_colors || ! cinfo->buffered_image) { cinfo->enable_1pass_quant = FALSE; cinfo->enable_external_quant = FALSE; cinfo->enable_2pass_quant = FALSE; } if (cinfo->quantize_colors) { if (cinfo->raw_data_out) ERREXIT(cinfo, JERR_NOTIMPL); /* 2-pass quantizer only works in 3-component color space. */ if (cinfo->out_color_components != 3) { cinfo->enable_1pass_quant = TRUE; cinfo->enable_external_quant = FALSE; cinfo->enable_2pass_quant = FALSE; cinfo->colormap = NULL; } else if (cinfo->colormap != NULL) { cinfo->enable_external_quant = TRUE; } else if (cinfo->two_pass_quantize) { cinfo->enable_2pass_quant = TRUE; } else { cinfo->enable_1pass_quant = TRUE; } if (cinfo->enable_1pass_quant) { #ifdef QUANT_1PASS_SUPPORTED jinit_1pass_quantizer(cinfo); master->quantizer_1pass = cinfo->cquantize; #else ERREXIT(cinfo, JERR_NOT_COMPILED); #endif } /* We use the 2-pass code to map to external colormaps. */ if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { #ifdef QUANT_2PASS_SUPPORTED jinit_2pass_quantizer(cinfo); master->quantizer_2pass = cinfo->cquantize; #else ERREXIT(cinfo, JERR_NOT_COMPILED); #endif } /* If both quantizers are initialized, the 2-pass one is left active; * this is necessary for starting with quantization to an external map. */ } /* Post-processing: in particular, color conversion first */ if (! cinfo->raw_data_out) { if (master->using_merged_upsample) { #ifdef UPSAMPLE_MERGING_SUPPORTED jinit_merged_upsampler(cinfo); /* does color conversion too */ #else ERREXIT(cinfo, JERR_NOT_COMPILED); #endif } else { jinit_color_deconverter(cinfo); jinit_upsampler(cinfo); } jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); } /* Inverse DCT */ jinit_inverse_dct(cinfo); /* Entropy decoding: either Huffman or arithmetic coding. */ if (cinfo->arith_code) { ERREXIT(cinfo, JERR_ARITH_NOTIMPL); } else { if (cinfo->progressive_mode) { #ifdef D_PROGRESSIVE_SUPPORTED jinit_phuff_decoder(cinfo); #else ERREXIT(cinfo, JERR_NO_PROGRESSIVE); #endif } else jinit_huff_decoder(cinfo); } /* Initialize principal buffer controllers. */ use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; jinit_d_coef_controller(cinfo, use_c_buffer); if (! cinfo->raw_data_out) jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); /* We can now tell the memory manager to allocate virtual arrays. */ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); /* Initialize input side of decompressor to consume first scan. */ (*cinfo->inputctl->start_input_pass) (cinfo); #ifdef D_MULTISCAN_FILES_SUPPORTED /* If jpeg_start_decompress will read the whole file, initialize * progress monitoring appropriately. The input step is counted * as one pass. */ if (cinfo->progress != NULL && ! cinfo->buffered_image && cinfo->inputctl->has_multiple_scans) { int nscans; /* Estimate number of scans to set pass_limit. */ if (cinfo->progressive_mode) { /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ nscans = 2 + 3 * cinfo->num_components; } else { /* For a nonprogressive multiscan file, estimate 1 scan per component. */ nscans = cinfo->num_components; } cinfo->progress->pass_counter = 0L; cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; cinfo->progress->completed_passes = 0; cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); /* Count the input pass as done */ master->pass_number++; } #endif /* D_MULTISCAN_FILES_SUPPORTED */ }