예제 #1
0
        /// <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++;
            }
        }