コード例 #1
0
        static void scaler_start_pass(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            scaler scaler = (scaler)losslsd.scaler_private;

            // Downscale by the difference in the input vs. output precision. If the
            // output precision >= input precision, then do not downscale.
            int downscale = BITS_IN_JSAMPLE < cinfo.data_precision?cinfo.data_precision - BITS_IN_JSAMPLE:0;

            scaler.scale_factor = cinfo.Al - downscale;

            // Set scaler functions based on scale_factor (positive = left shift)
            if (scaler.scale_factor > 0)
            {
                losslsd.scaler_scale = simple_upscale;
            }
            else if (scaler.scale_factor < 0)
            {
                scaler.scale_factor  = -scaler.scale_factor;
                losslsd.scaler_scale = simple_downscale;
            }
            else
            {
                losslsd.scaler_scale = noscale;
            }
        }
コード例 #2
0
ファイル: jdlhuff.cs プロジェクト: mikel785/libjpeg.net
        //#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))

        // Check for a restart marker & resynchronize decoder.
        // Returns false if must suspend.
        static bool process_restart_dlhuff(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            lhuff_entropy_decoder entropy = (lhuff_entropy_decoder)losslsd.entropy_private;

            // Throw away any unused bits remaining in bit buffer;
            // include any full bytes in next_marker's count of discarded bytes
            cinfo.marker.discarded_bytes += (uint)(entropy.bitstate.bits_left / 8);
            entropy.bitstate.bits_left    = 0;

            // Advance past the RSTn marker
            if (!cinfo.marker.read_restart_marker(cinfo))
            {
                return(false);
            }

            // Reset out-of-data flag, unless read_restart_marker left us smack up
            // against a marker. In that case we will end up treating the next data
            // segment as empty, and we can avoid producing bogus output pixels by
            // leaving the flag set.
            if (cinfo.unread_marker == 0)
            {
                entropy.insufficient_data = false;
            }

            return(true);
        }
コード例 #3
0
ファイル: jdpred.cs プロジェクト: mikel785/libjpeg.net
        // Undifferencer for the first row in a scan or restart interval. The first
        // sample in the row is undifferenced using the special predictor constant
        // x=2^(P-Pt-1). The rest of the samples are undifferenced using the
        // 1-D horizontal predictor (1).
        static void jpeg_undifference_first_row(jpeg_decompress cinfo, int comp_index, int[] diff_buf, int[] prev_row, int[] undiff_buf, uint width)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;

            int Ra = (diff_buf[0] + (1 << (cinfo.data_precision - cinfo.Al - 1))) & 0xFFFF;

            undiff_buf[0] = Ra;

            for (uint xindex = 1; xindex < width; xindex++)
            {
                Ra = (diff_buf[xindex] + Ra) & 0xFFFF;
                undiff_buf[xindex] = Ra;
            }

            // Now that we have undifferenced the first row, we want to use the
            // undifferencer which corresponds to the predictor specified in the
            // scan header.
            switch (cinfo.Ss)
            {
            case 1: losslsd.predict_undifference[comp_index] = jpeg_undifference1; break;

            case 2: losslsd.predict_undifference[comp_index] = jpeg_undifference2; break;

            case 3: losslsd.predict_undifference[comp_index] = jpeg_undifference3; break;

            case 4: losslsd.predict_undifference[comp_index] = jpeg_undifference4; break;

            case 5: losslsd.predict_undifference[comp_index] = jpeg_undifference5; break;

            case 6: losslsd.predict_undifference[comp_index] = jpeg_undifference6; break;

            case 7: losslsd.predict_undifference[comp_index] = jpeg_undifference7; break;
            }
        }
コード例 #4
0
ファイル: jdpred.cs プロジェクト: mikel785/libjpeg.net
        // Module initialization routine for the undifferencer.
        static void jinit_undifferencer(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;

            losslsd.predict_start_pass      = start_pass_d_pred;
            losslsd.predict_process_restart = start_pass_d_pred;
        }
コード例 #5
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        // Reset within-iMCU-row counters for a new row (input side)
        static void start_iMCU_row_d_diff(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = (d_diff_controller)losslsd.diff_private;

            // In an interleaved scan, an MCU row is the same as an iMCU row.
            // In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
            // But at the bottom of the image, process only what's left.
            if (cinfo.comps_in_scan > 1)
            {
                diff.MCU_rows_per_iMCU_row = 1;
            }
            else
            {
                if (cinfo.input_iMCU_row < (cinfo.total_iMCU_rows - 1))
                {
                    diff.MCU_rows_per_iMCU_row = (uint)cinfo.cur_comp_info[0].v_samp_factor;
                }
                else
                {
                    diff.MCU_rows_per_iMCU_row = (uint)cinfo.cur_comp_info[0].last_row_height;
                }
            }

            diff.MCU_ctr         = 0;
            diff.MCU_vert_offset = 0;
        }
コード例 #6
0
ファイル: jdlossls.cs プロジェクト: mikel785/libjpeg.net
        // Initialize for an input processing pass.
        static void start_input_pass_ls(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;

            losslsd.entropy_start_pass(cinfo);
            losslsd.predict_start_pass(cinfo);
            losslsd.scaler_start_pass(cinfo);
            losslsd.diff_start_input_pass(cinfo);
        }
コード例 #7
0
        static void simple_downscale(jpeg_decompress cinfo, int[] diff_buf, byte[] output_buf, uint width)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            scaler scaler = (scaler)losslsd.scaler_private;

            int scale_factor = scaler.scale_factor;

            for (uint xindex = 0; xindex < width; xindex++)
            {
                output_buf[xindex] = (byte)(diff_buf[xindex] >> scale_factor);
            }
        }
コード例 #8
0
ファイル: jdlhuff.cs プロジェクト: mikel785/libjpeg.net
        // Initialize for a Huffman-compressed scan.
        static void start_pass_lhuff_decoder(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            lhuff_entropy_decoder entropy = (lhuff_entropy_decoder)losslsd.entropy_private;

            for (int ci = 0; ci < cinfo.comps_in_scan; ci++)
            {
                jpeg_component_info compptr = cinfo.cur_comp_info[ci];
                int dctbl = compptr.dc_tbl_no;

                // Make sure requested tables are present
                if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
                    cinfo.dc_huff_tbl_ptrs[dctbl] == null)
                {
                    ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, dctbl);
                }

                // Compute derived values for Huffman tables
                // We may do this more than once for a table, but it's not expensive
                jpeg_make_d_derived_tbl(cinfo, true, dctbl, ref entropy.derived_tbls[dctbl]);
            }

            // Precalculate decoding info for each sample in an MCU of this scan
            int ptrn = 0;

            for (int sampn = 0; sampn < cinfo.blocks_in_MCU;)
            {
                jpeg_component_info compptr = cinfo.cur_comp_info[cinfo.MCU_membership[sampn]];
                int ci = compptr.component_index;
                for (int yoffset = 0; yoffset < compptr.MCU_height; yoffset++, ptrn++)
                {
                    // Precalculate the setup info for each output pointer
                    entropy.output_ptr_info[ptrn].ci        = ci;
                    entropy.output_ptr_info[ptrn].yoffset   = yoffset;
                    entropy.output_ptr_info[ptrn].MCU_width = compptr.MCU_width;
                    for (int xoffset = 0; xoffset < compptr.MCU_width; xoffset++, sampn++)
                    {
                        // Precalculate the output pointer index for each sample
                        entropy.output_ptr_index[sampn] = ptrn;

                        // Precalculate which table to use for each sample
                        entropy.cur_tbls[sampn] = entropy.derived_tbls[compptr.dc_tbl_no];
                    }
                }
            }
            entropy.num_output_ptrs = ptrn;

            // Initialize bitread state variables
            entropy.bitstate.bits_left  = 0;
            entropy.bitstate.get_buffer = 0;           // unnecessary, but keeps Purify quiet
            entropy.insufficient_data   = false;
        }
コード例 #9
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        // Output some data from the full-image buffer sample in the multi-pass case.
        // Always attempts to emit one fully interleaved MCU row ("iMCU" row).
        // Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
        //
        // NB: output_buf contains a plane for each component in image.
        static CONSUME_INPUT output_data_d_diff(jpeg_decompress cinfo, byte[][][] output_buf)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = (d_diff_controller)losslsd.diff_private;
            uint last_iMCU_row            = cinfo.total_iMCU_rows - 1;

            // Force some input to be done if we are getting ahead of the input.
            while (cinfo.input_scan_number < cinfo.output_scan_number || (cinfo.input_scan_number == cinfo.output_scan_number && cinfo.input_iMCU_row <= cinfo.output_iMCU_row))
            {
                if (cinfo.inputctl.consume_input(cinfo) == CONSUME_INPUT.JPEG_SUSPENDED)
                {
                    return(CONSUME_INPUT.JPEG_SUSPENDED);
                }
            }

            // OK, output from the arrays.
            for (int ci = 0; ci < cinfo.num_components; ci++)
            {
                jpeg_component_info compptr = cinfo.comp_info[ci];

                // Align the buffer for this component.
                byte[][] buffer = diff.whole_image[ci];

                int samp_rows;
                if (cinfo.output_iMCU_row < last_iMCU_row)
                {
                    samp_rows = compptr.v_samp_factor;
                }
                else
                {
                    // NB: can't use last_row_height here; it is input-side-dependent!
                    samp_rows = (int)(compptr.height_in_blocks % compptr.v_samp_factor);
                    if (samp_rows == 0)
                    {
                        samp_rows = compptr.v_samp_factor;
                    }
                }

                for (int row = 0; row < samp_rows; row++)
                {
                    Array.Copy(buffer[cinfo.output_iMCU_row * compptr.v_samp_factor + row], output_buf[ci][row], compptr.width_in_blocks);
                }
            }

            if (++(cinfo.output_iMCU_row) < cinfo.total_iMCU_rows)
            {
                return(CONSUME_INPUT.JPEG_ROW_COMPLETED);
            }
            return(CONSUME_INPUT.JPEG_SCAN_COMPLETED);
        }
コード例 #10
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        // Initialize difference buffer controller.
        static void jinit_d_diff_controller(jpeg_decompress cinfo, bool need_full_buffer)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = null;

            try
            {
                diff = new d_diff_controller();
            }
            catch
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
            }
            losslsd.diff_private          = diff;
            losslsd.diff_start_input_pass = start_input_pass_d_diff;
            losslsd.start_output_pass     = start_output_pass_d_diff;

            // Create the [un]difference buffers.
            for (int ci = 0; ci < cinfo.num_components; ci++)
            {
                jpeg_component_info compptr = cinfo.comp_info[ci];
                diff.diff_buf[ci]   = alloc_darray(cinfo, (uint)jround_up(compptr.width_in_blocks, compptr.h_samp_factor), (uint)compptr.v_samp_factor);
                diff.undiff_buf[ci] = alloc_darray(cinfo, (uint)jround_up(compptr.width_in_blocks, compptr.h_samp_factor), (uint)compptr.v_samp_factor);
            }

            if (need_full_buffer)
            {
#if D_MULTISCAN_FILES_SUPPORTED
                // Allocate a full-image array for each component.
                for (int ci = 0; ci < cinfo.num_components; ci++)
                {
                    jpeg_component_info compptr = cinfo.comp_info[ci];
                    diff.whole_image[ci] = alloc_sarray(cinfo, (uint)jround_up(compptr.width_in_blocks, compptr.h_samp_factor), (uint)jround_up(compptr.height_in_blocks, compptr.v_samp_factor));
                }
                losslsd.consume_data    = consume_data_d_diff;
                losslsd.decompress_data = output_data_d_diff;
#else
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_NOT_COMPILED);
#endif
            }
            else
            {
                losslsd.consume_data    = dummy_consume_data_d_diff;
                losslsd.decompress_data = decompress_data_d_diff;
                diff.whole_image[0]     = null;           // flag for no arrays
            }
        }
コード例 #11
0
        static void jinit_d_scaler(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            scaler scaler = null;

            try
            {
                scaler = new scaler();
            }
            catch
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
            }

            losslsd.scaler_private    = scaler;
            losslsd.scaler_start_pass = scaler_start_pass;
        }
コード例 #12
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        // Check for a restart marker & resynchronize decoder, undifferencer.
        // Returns false if must suspend.
        static bool process_restart_d_diff(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = (d_diff_controller)losslsd.diff_private;

            if (!losslsd.entropy_process_restart(cinfo))
            {
                return(false);
            }

            losslsd.predict_process_restart(cinfo);

            // Reset restart counter
            diff.restart_rows_to_go = cinfo.restart_interval / cinfo.MCUs_per_row;

            return(true);
        }
コード例 #13
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        // Initialize for an input processing pass.
        static void start_input_pass_d_diff(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = (d_diff_controller)losslsd.diff_private;

            // Check that the restart interval is an integer multiple of the number
            // of MCU in an MCU-row.
            if (cinfo.restart_interval % cinfo.MCUs_per_row != 0)
            {
                ERREXIT2(cinfo, J_MESSAGE_CODE.JERR_BAD_RESTART, (int)cinfo.restart_interval, (int)cinfo.MCUs_per_row);
            }

            // Initialize restart counter
            diff.restart_rows_to_go = cinfo.restart_interval / cinfo.MCUs_per_row;

            cinfo.input_iMCU_row = 0;
            start_iMCU_row_d_diff(cinfo);
        }
コード例 #14
0
ファイル: jdlossls.cs プロジェクト: mikel785/libjpeg.net
        // Initialize the lossless decompression codec.
        // This is called only once, during master selection.
        static void jinit_lossless_d_codec(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = null;

            // Create subobject
            try
            {
                losslsd = new jpeg_lossless_d_codec();
            }
            catch
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
            }

            cinfo.coef = losslsd;

            // Initialize sub-modules
            // Entropy decoding: either Huffman or arithmetic coding.
            if (cinfo.arith_code)
            {
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_ARITH_NOTIMPL);
            }
            else
            {
                jinit_lhuff_decoder(cinfo);
            }

            // Undifferencer
            jinit_undifferencer(cinfo);

            // Scaler
            jinit_d_scaler(cinfo);

            bool use_c_buffer = cinfo.inputctl.has_multiple_scans || cinfo.buffered_image;

            jinit_d_diff_controller(cinfo, use_c_buffer);

            // Initialize method pointers.
            //
            // Note: consume_data, start_output_pass and decompress_data are
            // assigned in jddiffct.cs.
            losslsd.calc_output_dimensions = calc_output_dimensions_ls;
            losslsd.start_input_pass       = start_input_pass_ls;
        }
コード例 #15
0
ファイル: jdlossls.cs プロジェクト: JoshDullen/libjpeg.net
		// Initialize the lossless decompression codec.
		// This is called only once, during master selection.
		static void jinit_lossless_d_codec(jpeg_decompress cinfo)
		{
			jpeg_lossless_d_codec losslsd=null;

			// Create subobject
			try
			{
				losslsd=new jpeg_lossless_d_codec();
			}
			catch
			{
				ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
			}

			cinfo.coef=losslsd;

			// Initialize sub-modules
			// Entropy decoding: either Huffman or arithmetic coding.
			if(cinfo.arith_code)
			{
				ERREXIT(cinfo, J_MESSAGE_CODE.JERR_ARITH_NOTIMPL);
			}
			else
			{
				jinit_lhuff_decoder(cinfo);
			}

			// Undifferencer
			jinit_undifferencer(cinfo);

			// Scaler
			jinit_d_scaler(cinfo);

			bool use_c_buffer=cinfo.inputctl.has_multiple_scans||cinfo.buffered_image;
			jinit_d_diff_controller(cinfo, use_c_buffer);

			// Initialize method pointers.
			//
			// Note: consume_data, start_output_pass and decompress_data are
			// assigned in jddiffct.cs.
			losslsd.calc_output_dimensions=calc_output_dimensions_ls;
			losslsd.start_input_pass=start_input_pass_ls;
		}
コード例 #16
0
ファイル: jddiffct.cs プロジェクト: mikel785/libjpeg.net
        // Consume input data and store it in the full-image sample buffer.
        // We read as much as one fully interleaved MCU row ("iMCU" row) per call,
        // ie, v_samp_factor rows for each component in the scan.
        // Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
        static CONSUME_INPUT consume_data_d_diff(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            d_diff_controller     diff    = (d_diff_controller)losslsd.diff_private;
            uint last_iMCU_row            = cinfo.total_iMCU_rows - 1;

            byte[][][] buffer     = new byte[MAX_COMPS_IN_SCAN][][];
            int[]      buffer_ind = new int[MAX_COMPS_IN_SCAN];

            // Align the buffers for the components used in this scan.
            for (int comp = 0; comp < cinfo.comps_in_scan; comp++)
            {
                jpeg_component_info compptr = cinfo.cur_comp_info[comp];
                int ci = compptr.component_index;
                buffer[ci]     = diff.whole_image[ci];
                buffer_ind[ci] = (int)cinfo.input_iMCU_row * compptr.v_samp_factor;
            }

            return(decompress_data_d_diff(cinfo, buffer, buffer_ind));
        }
コード例 #17
0
ファイル: jdpred.cs プロジェクト: mikel785/libjpeg.net
        // Initialize for an input processing pass.
        static void start_pass_d_pred(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;

            // Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG.
            //
            // Ss is the predictor selection value (psv). Legal values for sequential
            // lossless JPEG are: 1 <= psv <= 7.
            //
            // Se and Ah are not used and should be zero.
            //
            // Al specifies the point transform (Pt). Legal values are: 0 <= Pt <= 15.
            if (cinfo.Ss < 1 || cinfo.Ss > 7 || cinfo.Se != 0 || cinfo.Ah != 0 || cinfo.Al > 15) // need not check for < 0
            {
                ERREXIT4(cinfo, J_MESSAGE_CODE.JERR_BAD_LOSSLESS, cinfo.Ss, cinfo.Se, cinfo.Ah, cinfo.Al);
            }

            // Set undifference functions to first row function
            for (int ci = 0; ci < cinfo.num_components; ci++)
            {
                losslsd.predict_undifference[ci] = jpeg_undifference_first_row;
            }
        }
コード例 #18
0
ファイル: jdlhuff.cs プロジェクト: mikel785/libjpeg.net
        // Module initialization routine for lossless Huffman entropy decoding.
        public static void jinit_lhuff_decoder(jpeg_decompress cinfo)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            lhuff_entropy_decoder entropy = null;

            try
            {
                entropy = new lhuff_entropy_decoder();
            }
            catch
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
            }
            losslsd.entropy_private         = entropy;
            losslsd.entropy_start_pass      = start_pass_lhuff_decoder;
            losslsd.entropy_process_restart = process_restart_dlhuff;
            losslsd.entropy_decode_mcus     = decode_mcus_dlhuff;

            // Mark tables unallocated
            for (int i = 0; i < NUM_HUFF_TBLS; i++)
            {
                entropy.derived_tbls[i] = null;
            }
        }
コード例 #19
0
ファイル: jdlhuff.cs プロジェクト: mikel785/libjpeg.net
        // Decode and return nMCU's worth of Huffman-compressed differences.
        // Each MCU is also disassembled and placed accordingly in diff_buf.
        //
        // MCU_col_num specifies the column of the first MCU being requested within
        // the MCU-row. This tells us where to position the output row pointers in
        // diff_buf.
        //
        // Returns the number of MCUs decoded. This may be less than nMCU if data
        // source requested suspension. In that case no changes have been made to
        // permanent state. (Exception: some output differences may already have
        // been assigned. This is harmless for this module, since we'll just
        // re-assign them on the next call.)
        static uint decode_mcus_dlhuff(jpeg_decompress cinfo, int[][][] diff_buf, uint MCU_row_num, uint MCU_col_num, uint nMCU)
        {
            jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef;
            lhuff_entropy_decoder entropy = (lhuff_entropy_decoder)losslsd.entropy_private;

            // Set output pointer locations based on MCU_col_num
            for (int ptrn = 0; ptrn < entropy.num_output_ptrs; ptrn++)
            {
                int ci        = entropy.output_ptr_info[ptrn].ci;
                int yoffset   = entropy.output_ptr_info[ptrn].yoffset;
                int MCU_width = entropy.output_ptr_info[ptrn].MCU_width;
                entropy.output_ptr[ptrn]     = diff_buf[ci][MCU_row_num + yoffset];
                entropy.output_ptr_ind[ptrn] = (int)(MCU_col_num * MCU_width);
            }

            // If we've run out of data, zero out the buffers and return.
            // By resetting the undifferencer, the output samples will be CENTERJSAMPLE.
            //
            // NB: We should find a way to do this without interacting with the
            // undifferencer module directly.
            if (entropy.insufficient_data)
            {
                for (int ptrn = 0; ptrn < entropy.num_output_ptrs; ptrn++)
                {
                    for (int i = 0; i < nMCU * entropy.output_ptr_info[ptrn].MCU_width; i++)
                    {
                        entropy.output_ptr[ptrn][entropy.output_ptr_ind[ptrn] + i] = 0;
                    }
                }

                losslsd.predict_process_restart(cinfo);
            }

            else
            {
                // Load up working state

                //was BITREAD_STATE_VARS;
                bitread_working_state br_state = new bitread_working_state();

                //was BITREAD_LOAD_STATE(cinfo, entropy.bitstate);
                br_state.cinfo           = cinfo;
                br_state.input_bytes     = cinfo.src.input_bytes;
                br_state.next_input_byte = cinfo.src.next_input_byte;
                br_state.bytes_in_buffer = cinfo.src.bytes_in_buffer;
                ulong get_buffer = entropy.bitstate.get_buffer;
                int   bits_left  = entropy.bitstate.bits_left;

                // Outer loop handles the number of MCU requested
                for (uint mcu_num = 0; mcu_num < nMCU; mcu_num++)
                {
                    // Inner loop handles the samples in the MCU
                    for (int sampn = 0; sampn < cinfo.blocks_in_MCU; sampn++)
                    {
                        d_derived_tbl dctbl = entropy.cur_tbls[sampn];
                        int           s = 0, r;

                        // Section H.2.2: decode the sample difference
                        //was HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1);
                        {
                            int  nb, look;
                            bool label = false;
                            if (bits_left < HUFF_LOOKAHEAD)
                            {
                                if (!jpeg_fill_bit_buffer(ref br_state, get_buffer, bits_left, 0))
                                {
                                    return(mcu_num);
                                }
                                get_buffer = br_state.get_buffer;
                                bits_left  = br_state.bits_left;
                                if (bits_left < HUFF_LOOKAHEAD)
                                {
                                    nb    = 1;
                                    label = true;
                                    if ((s = jpeg_huff_decode(ref br_state, get_buffer, bits_left, dctbl, nb)) < 0)
                                    {
                                        return(mcu_num);
                                    }
                                    get_buffer = br_state.get_buffer;
                                    bits_left  = br_state.bits_left;
                                }
                            }

                            if (!label)
                            {
                                //was look=PEEK_BITS(HUFF_LOOKAHEAD);
                                look = ((int)(get_buffer >> (bits_left - HUFF_LOOKAHEAD))) & ((1 << HUFF_LOOKAHEAD) - 1);
                                if ((nb = dctbl.look_nbits[look]) != 0)
                                {
                                    //was DROP_BITS(nb);
                                    bits_left -= nb;
                                    s          = dctbl.look_sym[look];
                                }
                                else
                                {
                                    nb = HUFF_LOOKAHEAD + 1;
                                    if ((s = jpeg_huff_decode(ref br_state, get_buffer, bits_left, dctbl, nb)) < 0)
                                    {
                                        return(mcu_num);
                                    }
                                    get_buffer = br_state.get_buffer;
                                    bits_left  = br_state.bits_left;
                                }
                            }
                        }

                        if (s != 0)
                        {
                            if (s == 16)
                            {
                                s = 32768;                                 // special case: always output 32768
                            }
                            else
                            {                             // normal case: fetch subsequent bits
                                //was CHECK_BIT_BUFFER(br_state, s, return mcu_num);
                                if (bits_left < s)
                                {
                                    if (!jpeg_fill_bit_buffer(ref br_state, get_buffer, bits_left, s))
                                    {
                                        return(mcu_num);
                                    }
                                    get_buffer = br_state.get_buffer; bits_left = br_state.bits_left;
                                }

                                //was r = GET_BITS(s);
                                r = ((int)(get_buffer >> (bits_left -= s))) & ((1 << s) - 1);
                                //was s=HUFF_EXTEND(r, s);
                                s = (r < (1 << (s - 1))?r + (((-1) << s) + 1):r);
                            }
                        }

                        // Output the sample difference
                        int ind = entropy.output_ptr_index[sampn];
                        entropy.output_ptr[ind][entropy.output_ptr_ind[ind]++] = (int)s;
                    }

                    // Completed MCU, so update state
                    //was BITREAD_SAVE_STATE(cinfo, entropy.bitstate);
                    cinfo.src.input_bytes       = br_state.input_bytes;
                    cinfo.src.next_input_byte   = br_state.next_input_byte;
                    cinfo.src.bytes_in_buffer   = br_state.bytes_in_buffer;
                    entropy.bitstate.get_buffer = get_buffer;
                    entropy.bitstate.bits_left  = bits_left;
                }
            }

            return(nMCU);
        }
コード例 #20
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);
        }