BitMiracle.LibJpeg.Classic.jpeg_decompress_struct.jpeg_calc_output_dimensions C# (CSharp) Method

jpeg_calc_output_dimensions() public method

Pre-calculate output image dimensions and related values for current decompression parameters.
This is allowed for possible use by application. Hence it mustn't do anything that can't be done twice. Also note that it may be called before the master module is initialized!
public jpeg_calc_output_dimensions ( ) : void
return void
        public void jpeg_calc_output_dimensions()
        {
            // Do computations that are needed before master selection phase
            // This function is used for full decompression.
            /* Prevent application from calling me at wrong times */
            if (m_global_state != JpegState.DSTATE_READY)
                ERREXIT(J_MESSAGE_CODE.JERR_BAD_STATE, (int)m_global_state);

            /* Compute core output image dimensions and DCT scaling choices. */
            m_inputctl.jpeg_core_output_dimensions();

            /* In selecting the actual DCT scaling for each component, we try to
            * scale up the chroma components via IDCT scaling rather than upsampling.
            * This saves time if the upsampler gets to use 1:1 scaling.
            * Note this code adapts subsampling ratios which are powers of 2.
            */
            for (int ci = 0; ci < m_num_components; ci++)
            {
                int ssize = 1;

                jpeg_component_info compptr = m_comp_info[ci];
                while (min_DCT_h_scaled_size * ssize <= 
                    (m_do_fancy_upsampling ? JpegConstants.DCTSIZE : JpegConstants.DCTSIZE / 2) &&
                    (m_max_h_samp_factor % (compptr.H_samp_factor * ssize * 2)) == 0)
                {
                    ssize = ssize * 2;
                }

                compptr.DCT_h_scaled_size = min_DCT_h_scaled_size * ssize;

                ssize = 1;
                while (min_DCT_v_scaled_size * ssize <=
                   (m_do_fancy_upsampling ? JpegConstants.DCTSIZE : JpegConstants.DCTSIZE / 2) &&
                   (m_max_v_samp_factor % (compptr.V_samp_factor * ssize * 2)) == 0)
                {
                    ssize = ssize * 2;
                }
                compptr.DCT_v_scaled_size = min_DCT_v_scaled_size * ssize;

                /* We don't support IDCT ratios larger than 2. */
                if (compptr.DCT_h_scaled_size > compptr.DCT_v_scaled_size * 2)
                    compptr.DCT_h_scaled_size = compptr.DCT_v_scaled_size * 2;
                else if (compptr.DCT_v_scaled_size > compptr.DCT_h_scaled_size * 2)
                    compptr.DCT_v_scaled_size = compptr.DCT_h_scaled_size * 2;
            }

            /* Recompute downsampled dimensions of components;
            * application needs to know these if using raw downsampled data.
            */
            for (int ci = 0; ci < m_num_components; ci++)
            {
                /* Size in samples, after IDCT scaling */
                m_comp_info[ci].downsampled_width = (int)JpegUtils.jdiv_round_up(
                    m_image_width * m_comp_info[ci].H_samp_factor * m_comp_info[ci].DCT_h_scaled_size,
                    m_max_h_samp_factor * block_size);

                m_comp_info[ci].downsampled_height = (int)JpegUtils.jdiv_round_up(
                    m_image_height * m_comp_info[ci].V_samp_factor * m_comp_info[ci].DCT_v_scaled_size,
                    m_max_v_samp_factor * block_size);
            }

            /* Report number of components in selected colorspace. */
            /* Probably this should be in the color conversion module... */
            switch (m_out_color_space)
            {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                    m_out_color_components = 1;
                    break;

                case J_COLOR_SPACE.JCS_RGB:
                case J_COLOR_SPACE.JCS_BG_RGB:
                    m_out_color_components = JpegConstants.RGB_PIXELSIZE;
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                case J_COLOR_SPACE.JCS_BG_YCC:
                    m_out_color_components = 3;
                    break;

                case J_COLOR_SPACE.JCS_CMYK:
                case J_COLOR_SPACE.JCS_YCCK:
                    m_out_color_components = 4;
                    break;

                default:
                    /* else must be same colorspace as in file */
                    m_out_color_components = m_num_components;
                    break;
            }

            m_output_components = (m_quantize_colors ? 1 : m_out_color_components);

            /* See if upsampler will want to emit more than one row at a time */
            if (use_merged_upsample())
                m_rec_outbuf_height = m_max_v_samp_factor;
            else
                m_rec_outbuf_height = 1;
        }

Usage Example

Example #1
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;
        }