예제 #1
0
        /// <summary>
        /// Tunes decompressor
        /// </summary>
        /// <param name="jpeg">Stream with input compressed JPEG data</param>
        private void beforeDecompress(Stream jpeg)
        {
            m_decompressor.jpeg_stdio_src(jpeg);
            /* Read file header, set default decompression parameters */
            m_decompressor.jpeg_read_header(true);

            applyParameters(m_decompressionParameters);
            m_decompressor.jpeg_calc_output_dimensions();
        }
예제 #2
0
        private int cur_output_row;             /* next row# to write to virtual array */

        public bmp_dest_struct(jpeg_decompress_struct cinfo, bool is_os2)
        {
            this.cinfo  = cinfo;
            this.is_os2 = is_os2;

            if (cinfo.Out_color_space == J_COLOR_SPACE.JCS_GRAYSCALE)
            {
                m_putGrayRows = true;
            }
            else if (cinfo.Out_color_space == J_COLOR_SPACE.JCS_RGB)
            {
                if (cinfo.Quantize_colors)
                {
                    m_putGrayRows = true;
                }
                else
                {
                    m_putGrayRows = false;
                }
            }
            else
            {
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_COLORSPACE);
            }

            /* Calculate output image dimensions so we can allocate space */
            cinfo.jpeg_calc_output_dimensions();

            /* Determine width of rows in the BMP file (padded to 4-byte boundary). */
            row_width  = cinfo.Output_width * cinfo.Output_components;
            data_width = row_width;
            while ((row_width & 3) != 0)
            {
                row_width++;
            }

            pad_bytes = row_width - data_width;

            /* Allocate space for inversion array, prepare for write pass */
            whole_image = jpeg_common_struct.CreateSamplesArray(row_width, cinfo.Output_height);
            whole_image.ErrorProcessor = cinfo;

            cur_output_row = 0;
            if (cinfo.Progress != null)
            {
                cdjpeg_progress_mgr progress = cinfo.Progress as cdjpeg_progress_mgr;
                if (progress != null)
                {
                    /* count file input as separate pass */
                    progress.total_extra_passes++;
                }
            }

            /* Create decompressor output buffer. */
            buffer        = jpeg_common_struct.AllocJpegSamples(row_width, 1);
            buffer_height = 1;
        }
예제 #3
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++;
            }
        }