/// <summary> /// Master selection of decompression modules. /// This is done once at jpeg_start_decompress time. We determine /// which modules will be used and give them appropriate initialization calls. /// We also initialize the decompressor input side to begin consuming data. /// /// Since jpeg_read_header has finished, we know what is in the SOF /// and (first) SOS markers. We also have all the application parameter /// settings. /// </summary> private void master_selection() { /* Initialize dimensions and other stuff */ m_cinfo.jpeg_calc_output_dimensions(); prepare_range_limit_table(); /* Width of an output scanline must be representable as int. */ long samplesperrow = m_cinfo.m_output_width * m_cinfo.m_out_color_components; int jd_samplesperrow = (int)samplesperrow; if ((long)jd_samplesperrow != samplesperrow) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_WIDTH_OVERFLOW); } /* Initialize my private state */ m_pass_number = 0; m_using_merged_upsample = m_cinfo.use_merged_upsample(); /* Color quantizer selection */ m_quantizer_1pass = null; m_quantizer_2pass = null; /* No mode changes if not using buffered-image mode. */ if (!m_cinfo.m_quantize_colors || !m_cinfo.m_buffered_image) { m_cinfo.m_enable_1pass_quant = false; m_cinfo.m_enable_external_quant = false; m_cinfo.m_enable_2pass_quant = false; } if (m_cinfo.m_quantize_colors) { if (m_cinfo.m_raw_data_out) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NOTIMPL); } /* 2-pass quantizer only works in 3-component color space. */ if (m_cinfo.m_out_color_components != 3) { m_cinfo.m_enable_1pass_quant = true; m_cinfo.m_enable_external_quant = false; m_cinfo.m_enable_2pass_quant = false; m_cinfo.m_colormap = null; } else if (m_cinfo.m_colormap != null) { m_cinfo.m_enable_external_quant = true; } else if (m_cinfo.m_two_pass_quantize) { m_cinfo.m_enable_2pass_quant = true; } else { m_cinfo.m_enable_1pass_quant = true; } if (m_cinfo.m_enable_1pass_quant) { m_cinfo.m_cquantize = new my_1pass_cquantizer(m_cinfo); m_quantizer_1pass = m_cinfo.m_cquantize; } /* We use the 2-pass code to map to external colormaps. */ if (m_cinfo.m_enable_2pass_quant || m_cinfo.m_enable_external_quant) { m_cinfo.m_cquantize = new my_2pass_cquantizer(m_cinfo); m_quantizer_2pass = m_cinfo.m_cquantize; } /* 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 (!m_cinfo.m_raw_data_out) { if (m_using_merged_upsample) { /* does color conversion too */ m_cinfo.m_upsample = new my_merged_upsampler(m_cinfo); } else { m_cinfo.m_cconvert = new jpeg_color_deconverter(m_cinfo); m_cinfo.m_upsample = new my_upsampler(m_cinfo); } m_cinfo.m_post = new jpeg_d_post_controller(m_cinfo, m_cinfo.m_enable_2pass_quant); } /* Inverse DCT */ m_cinfo.m_idct = new jpeg_inverse_dct(m_cinfo); if (m_cinfo.m_progressive_mode) { m_cinfo.m_entropy = new phuff_entropy_decoder(m_cinfo); } else { m_cinfo.m_entropy = new huff_entropy_decoder(m_cinfo); } /* Initialize principal buffer controllers. */ bool use_c_buffer = m_cinfo.m_inputctl.HasMultipleScans() || m_cinfo.m_buffered_image; m_cinfo.m_coef = new jpeg_d_coef_controller(m_cinfo, use_c_buffer); if (!m_cinfo.m_raw_data_out) { m_cinfo.m_main = new jpeg_d_main_controller(m_cinfo); } /* Initialize input side of decompressor to consume first scan. */ m_cinfo.m_inputctl.start_input_pass(); /* If jpeg_start_decompress will read the whole file, initialize * progress monitoring appropriately. The input step is counted * as one pass. */ if (m_cinfo.m_progress != null && !m_cinfo.m_buffered_image && m_cinfo.m_inputctl.HasMultipleScans()) { /* Estimate number of scans to set pass_limit. */ int nscans; if (m_cinfo.m_progressive_mode) { /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ nscans = 2 + 3 * m_cinfo.m_num_components; } else { /* For a non progressive multiscan file, estimate 1 scan per component. */ nscans = m_cinfo.m_num_components; } m_cinfo.m_progress.Pass_counter = 0; m_cinfo.m_progress.Pass_limit = m_cinfo.m_total_iMCU_rows * nscans; m_cinfo.m_progress.Completed_passes = 0; m_cinfo.m_progress.Total_passes = (m_cinfo.m_enable_2pass_quant ? 3 : 2); /* Count the input pass as done */ m_pass_number++; } }