コード例 #1
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        static CONSUME_INPUT decompress_data_d_diff(jpeg_decompress cinfo, byte[][][] output_buf, int[] output_buf_ind)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = (d_diff_controller)losslsd.diff_private;

            // Loop to process as much as one whole iMCU row
            for (uint yoffset = diff.MCU_vert_offset; yoffset < diff.MCU_rows_per_iMCU_row; yoffset++)
            {
                // Process restart marker if needed; may have to suspend
                if (cinfo.restart_interval != 0)
                {
                    if (diff.restart_rows_to_go == 0)
                    {
                        if (!process_restart_d_diff(cinfo))
                        {
                            return(CONSUME_INPUT.JPEG_SUSPENDED);
                        }
                    }
                }

                uint MCU_col_num = diff.MCU_ctr;               // index of current MCU within row

                // Try to fetch an MCU-row (or remaining portion of suspended MCU-row).
                uint MCU_count = losslsd.entropy_decode_mcus(cinfo, diff.diff_buf, yoffset, MCU_col_num, cinfo.MCUs_per_row - MCU_col_num);
                if (MCU_count != cinfo.MCUs_per_row - MCU_col_num)
                {
                    // Suspension forced; update state counters and exit
                    diff.MCU_vert_offset = yoffset;
                    diff.MCU_ctr        += MCU_count;
                    return(CONSUME_INPUT.JPEG_SUSPENDED);
                }

                // Account for restart interval (no-op if not using restarts)
                diff.restart_rows_to_go--;

                // Completed an MCU row, but perhaps not an iMCU row
                diff.MCU_ctr = 0;
            }

            uint last_iMCU_row = cinfo.total_iMCU_rows - 1;

            // Undifference and scale each scanline of the disassembled MCU-row
            // separately. We do not process dummy samples at the end of a scanline
            // or dummy rows at the end of the image.
            for (int comp = 0; comp < cinfo.comps_in_scan; comp++)
            {
                jpeg_component_info compptr = cinfo.cur_comp_info[comp];
                int ci   = compptr.component_index;
                int stop = cinfo.input_iMCU_row == last_iMCU_row?compptr.last_row_height:compptr.v_samp_factor;
                for (int row = 0, prev_row = compptr.v_samp_factor - 1; row < stop; prev_row = row, row++)
                {
                    losslsd.predict_undifference[ci](cinfo, ci, diff.diff_buf[ci][row], diff.undiff_buf[ci][prev_row], diff.undiff_buf[ci][row], compptr.width_in_blocks);
                    losslsd.scaler_scale(cinfo, diff.undiff_buf[ci][row], output_buf[ci][output_buf_ind[ci] + row], compptr.width_in_blocks);
                }
            }

            // Completed the iMCU row, advance counters for next one.
            //
            // NB: output_data will increment output_iMCU_row.
            // This counter is not needed for the single-pass case
            // or the input side of the multi-pass case.
            if (++(cinfo.input_iMCU_row) < cinfo.total_iMCU_rows)
            {
                start_iMCU_row_d_diff(cinfo);
                return(CONSUME_INPUT.JPEG_ROW_COMPLETED);
            }

            // Completed the scan
            cinfo.inputctl.finish_input_pass(cinfo);
            return(CONSUME_INPUT.JPEG_SCAN_COMPLETED);
        }