Beispiel #1
0
        // 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);
        }
Beispiel #2
0
        // 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);
        }