BitMiracle.LibJpeg.Classic.Internal.jpeg_d_coef_controller.decompress_onepass C# (CSharp) Method

decompress_onepass() private method

Decompress and return some data in the single-pass case. Always attempts to emit one fully interleaved MCU row ("iMCU" row). Input and output must run in lockstep since we have only a one-MCU buffer. Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. NB: output_buf contains a plane for each component in image, which we index according to the component's SOF position.
private decompress_onepass ( ComponentBuffer output_buf ) : ReadResult
output_buf ComponentBuffer
return ReadResult
        private ReadResult decompress_onepass(ComponentBuffer[] output_buf)
        {
            int last_MCU_col = m_cinfo.m_MCUs_per_row - 1;
            int last_iMCU_row = m_cinfo.m_total_iMCU_rows - 1;

            /* Loop to process as much as one whole iMCU row */
            for (int yoffset = m_MCU_vert_offset; yoffset < m_MCU_rows_per_iMCU_row; yoffset++)
            {
                for (int MCU_col_num = m_MCU_ctr; MCU_col_num <= last_MCU_col; MCU_col_num++)
                {
                    /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
                    if (m_cinfo.lim_Se != 0)
                    {
                        /* can bypass in DC only case */
                        for (int i = 0; i < m_cinfo.m_blocks_in_MCU; i++)
                            Array.Clear(m_MCU_buffer[i].data, 0, m_MCU_buffer[i].data.Length);
                    }

                    if (!m_cinfo.m_entropy.decode_mcu(m_MCU_buffer))
                    {
                        /* Suspension forced; update state counters and exit */
                        m_MCU_vert_offset = yoffset;
                        m_MCU_ctr = MCU_col_num;
                        return ReadResult.JPEG_SUSPENDED;
                    }

                    /* Determine where data should go in output_buf and do the IDCT thing.
                     * We skip dummy blocks at the right and bottom edges (but blkn gets
                     * incremented past them!).  Note the inner loop relies on having
                     * allocated the MCU_buffer[] blocks sequentially.
                     */
                    int blkn = 0;           /* index of current DCT block within MCU */
                    for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
                    {
                        jpeg_component_info componentInfo = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]];

                        /* Don't bother to IDCT an uninteresting component. */
                        if (!componentInfo.component_needed)
                        {
                            blkn += componentInfo.MCU_blocks;
                            continue;
                        }

                        int useful_width = (MCU_col_num < last_MCU_col) ? componentInfo.MCU_width : componentInfo.last_col_width;
                        int outputIndex = yoffset * componentInfo.DCT_v_scaled_size;
                        int start_col = MCU_col_num * componentInfo.MCU_sample_width;
                        for (int yindex = 0; yindex < componentInfo.MCU_height; yindex++)
                        {
                            if (m_cinfo.m_input_iMCU_row < last_iMCU_row || yoffset + yindex < componentInfo.last_row_height)
                            {
                                int output_col = start_col;
                                for (int xindex = 0; xindex < useful_width; xindex++)
                                {
                                    m_cinfo.m_idct.inverse(componentInfo.Component_index,
                                        m_MCU_buffer[blkn + xindex].data, output_buf[componentInfo.Component_index],
                                        outputIndex, output_col);

                                    output_col += componentInfo.DCT_h_scaled_size;
                                }
                            }

                            blkn += componentInfo.MCU_width;
                            outputIndex += componentInfo.DCT_v_scaled_size;
                        }
                    }
                }

                /* Completed an MCU row, but perhaps not an iMCU row */
                m_MCU_ctr = 0;
            }

            /* Completed the iMCU row, advance counters for next one */
            m_cinfo.m_output_iMCU_row++;
            m_cinfo.m_input_iMCU_row++;
            if (m_cinfo.m_input_iMCU_row < m_cinfo.m_total_iMCU_rows)
            {
                start_iMCU_row();
                return ReadResult.JPEG_ROW_COMPLETED;
            }

            /* Completed the scan */
            m_cinfo.m_inputctl.finish_input_pass();
            return ReadResult.JPEG_SCAN_COMPLETED;
        }