Derived data constructed for each Huffman table
        /*
        * Code for extracting next Huffman-coded symbol from input bit stream.
        * Again, this is time-critical and we make the main paths be macros.
        *
        * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
        * without looping.  Usually, more than 95% of the Huffman codes will be 8
        * or fewer bits long.  The few overlength codes are handled with a loop,
        * which need not be inline code.
        *
        * Notes about the HUFF_DECODE macro:
        * 1. Near the end of the data segment, we may fail to get enough bits
        *    for a lookahead.  In that case, we do it the hard way.
        * 2. If the lookahead table contains no entry, the next code must be
        *    more than HUFF_LOOKAHEAD bits long.
        * 3. jpeg_huff_decode returns -1 if forced to suspend.
        */
        protected static bool HUFF_DECODE(out int result, ref bitread_working_state state, d_derived_tbl htbl, ref int get_buffer, ref int bits_left)
        {
            int nb = 0;
            bool doSlow = false;

            if (bits_left < JpegConstants.HUFF_LOOKAHEAD)
            {
                if (!jpeg_fill_bit_buffer(ref state, get_buffer, bits_left, 0))
                {
                    result = -1;
                    return false;
                }

                get_buffer = state.get_buffer;
                bits_left = state.bits_left;
                if (bits_left < JpegConstants.HUFF_LOOKAHEAD)
                {
                    nb = 1;
                    doSlow = true;
                }
            }

            if (!doSlow)
            {
                int look = PEEK_BITS(JpegConstants.HUFF_LOOKAHEAD, get_buffer, bits_left);
                if ((nb = htbl.look_nbits[look]) != 0)
                {
                    DROP_BITS(nb, ref bits_left);
                    result = htbl.look_sym[look];
                    return true;
                }

                nb = JpegConstants.HUFF_LOOKAHEAD + 1;
            }

            result = jpeg_huff_decode(ref state, get_buffer, bits_left, htbl, nb);
            if (result < 0)
                return false;

            get_buffer = state.get_buffer;
            bits_left = state.bits_left;

            return true;
        }
        /* Out-of-line case for Huffman code fetching */
        protected static int jpeg_huff_decode(ref bitread_working_state state, int get_buffer, int bits_left, d_derived_tbl htbl, int min_bits)
        {
            /* HUFF_DECODE has determined that the code is at least min_bits */
            /* bits long, so fetch that many bits in one swoop. */
            int l = min_bits;
            if (!CHECK_BIT_BUFFER(ref state, l, ref get_buffer, ref bits_left))
                return -1;

            int code = GET_BITS(l, get_buffer, ref bits_left);

            /* Collect the rest of the Huffman code one bit at a time. */
            /* This is per Figure F.16 in the JPEG spec. */

            while (code > htbl.maxcode[l])
            {
                code <<= 1;
                if (!CHECK_BIT_BUFFER(ref state, 1, ref get_buffer, ref bits_left))
                    return -1;

                code |= GET_BITS(1, get_buffer, ref bits_left);
                l++;
            }

            /* Unload the local registers */
            state.get_buffer = get_buffer;
            state.bits_left = bits_left;

            /* With garbage input we may reach the sentinel value l = 17. */

            if (l > 16)
            {
                state.cinfo.WARNMS(J_MESSAGE_CODE.JWRN_HUFF_BAD_CODE);
                /* fake a zero as the safest result */
                return 0;
            }

            return htbl.pub.Huffval[code + htbl.valoffset[l]];
        }
        /* Out-of-line case for Huffman code fetching */
        protected static int jpeg_huff_decode(ref bitread_working_state state, int get_buffer, int bits_left, d_derived_tbl htbl, int min_bits)
        {
            /* HUFF_DECODE has determined that the code is at least min_bits */
            /* bits long, so fetch that many bits in one swoop. */
            int l = min_bits;

            if (!CHECK_BIT_BUFFER(ref state, l, ref get_buffer, ref bits_left))
            {
                return(-1);
            }

            int code = GET_BITS(l, get_buffer, ref bits_left);

            /* Collect the rest of the Huffman code one bit at a time. */
            /* This is per Figure F.16 in the JPEG spec. */

            while (code > htbl.maxcode[l])
            {
                code <<= 1;
                if (!CHECK_BIT_BUFFER(ref state, 1, ref get_buffer, ref bits_left))
                {
                    return(-1);
                }

                code |= GET_BITS(1, get_buffer, ref bits_left);
                l++;
            }

            /* Unload the local registers */
            state.get_buffer = get_buffer;
            state.bits_left  = bits_left;

            /* With garbage input we may reach the sentinel value l = 17. */

            if (l > 16)
            {
                state.cinfo.WARNMS(J_MESSAGE_CODE.JWRN_HUFF_BAD_CODE);
                /* fake a zero as the safest result */
                return(0);
            }

            return(htbl.pub.Huffval[code + htbl.valoffset[l]]);
        }
        /// <summary>
        /// Expand a Huffman table definition into the derived format
        /// This routine also performs some validation checks on the table.
        /// </summary>
        protected void jpeg_make_d_derived_tbl(bool isDC, int tblno, ref d_derived_tbl dtbl)
        {
            /* Note that huffsize[] and huffcode[] are filled in code-length order,
            * paralleling the order of the symbols themselves in htbl.huffval[].
            */

            /* Find the input Huffman table */
            if (tblno < 0 || tblno >= JpegConstants.NUM_HUFF_TBLS)
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);

            JHUFF_TBL htbl = isDC ? m_cinfo.m_dc_huff_tbl_ptrs[tblno] : m_cinfo.m_ac_huff_tbl_ptrs[tblno];
            if (htbl == null)
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);

            /* Allocate a workspace if we haven't already done so. */
            if (dtbl == null)
                dtbl = new d_derived_tbl();

            dtbl.pub = htbl;       /* fill in back link */

            /* Figure C.1: make table of Huffman code length for each symbol */

            int p = 0;
            char[] huffsize = new char[257];
            for (int l = 1; l <= 16; l++)
            {
                int i = htbl.Bits[l];
                if (i < 0 || p + i> 256)    /* protect against table overrun */
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);

                while ((i--) != 0)
                    huffsize[p++] = (char) l;
            }
            huffsize[p] = (char)0;
            int numsymbols = p;

            /* Figure C.2: generate the codes themselves */
            /* We also validate that the counts represent a legal Huffman code tree. */

            int code = 0;
            int si = huffsize[0];
            int[] huffcode = new int[257];
            p = 0;
            while (huffsize[p] != 0)
            {
                while (((int)huffsize[p]) == si)
                {
                    huffcode[p++] = code;
                    code++;
                }

                /* code is now 1 more than the last code used for codelength si; but
                * it must still fit in si bits, since no code is allowed to be all ones.
                */
                if (code >= (1 << si))
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                code <<= 1;
                si++;
            }

            /* Figure F.15: generate decoding tables for bit-sequential decoding */

            p = 0;
            for (int l = 1; l <= 16; l++)
            {
                if (htbl.Bits[l] != 0)
                {
                    /* valoffset[l] = huffval[] index of 1st symbol of code length l,
                    * minus the minimum code of length l
                    */
                    dtbl.valoffset[l] = p - huffcode[p];
                    p += htbl.Bits[l];
                    dtbl.maxcode[l] = huffcode[p - 1]; /* maximum code of length l */
                }
                else
                {
                    /* -1 if no codes of this length */
                    dtbl.maxcode[l] = -1;
                }
            }
            dtbl.maxcode[17] = 0xFFFFF; /* ensures jpeg_huff_decode terminates */

            /* Compute lookahead tables to speed up decoding.
            * First we set all the table entries to 0, indicating "too long";
            * then we iterate through the Huffman codes that are short enough and
            * fill in all the entries that correspond to bit sequences starting
            * with that code.
            */

            Array.Clear(dtbl.look_nbits, 0, dtbl.look_nbits.Length);
            p = 0;
            for (int l = 1; l <= JpegConstants.HUFF_LOOKAHEAD; l++)
            {
                for (int i = 1; i <= htbl.Bits[l]; i++, p++)
                {
                    /* l = current code's length, p = its index in huffcode[] & huffval[]. */
                    /* Generate left-justified code followed by all possible bit sequences */
                    int lookbits = huffcode[p] << (JpegConstants.HUFF_LOOKAHEAD - l);
                    for (int ctr = 1 << (JpegConstants.HUFF_LOOKAHEAD - l); ctr > 0; ctr--)
                    {
                        dtbl.look_nbits[lookbits] = l;
                        dtbl.look_sym[lookbits] = htbl.Huffval[p];
                        lookbits++;
                    }
                }
            }

            /* Validate symbols as being reasonable.
            * For AC tables, we make no check, but accept all byte values 0..255.
            * For DC tables, we require the symbols to be in range 0..15.
            * (Tighter bounds could be applied depending on the data depth and mode,
            * but this is sufficient to ensure safe decoding.)
            */
            if (isDC)
            {
                for (int i = 0; i < numsymbols; i++)
                {
                    int sym = htbl.Huffval[i];
                    if (sym < 0 || sym> 15)
                        m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }
            }
        }
        /*
         * Code for extracting next Huffman-coded symbol from input bit stream.
         * Again, this is time-critical and we make the main paths be macros.
         *
         * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
         * without looping.  Usually, more than 95% of the Huffman codes will be 8
         * or fewer bits long.  The few overlength codes are handled with a loop,
         * which need not be inline code.
         *
         * Notes about the HUFF_DECODE macro:
         * 1. Near the end of the data segment, we may fail to get enough bits
         *    for a lookahead.  In that case, we do it the hard way.
         * 2. If the lookahead table contains no entry, the next code must be
         *    more than HUFF_LOOKAHEAD bits long.
         * 3. jpeg_huff_decode returns -1 if forced to suspend.
         */
        protected static bool HUFF_DECODE(out int result, ref bitread_working_state state, d_derived_tbl htbl, ref int get_buffer, ref int bits_left)
        {
            int  nb     = 0;
            bool doSlow = false;

            if (bits_left < JpegConstants.HUFF_LOOKAHEAD)
            {
                if (!jpeg_fill_bit_buffer(ref state, get_buffer, bits_left, 0))
                {
                    result = -1;
                    return(false);
                }

                get_buffer = state.get_buffer;
                bits_left  = state.bits_left;
                if (bits_left < JpegConstants.HUFF_LOOKAHEAD)
                {
                    nb     = 1;
                    doSlow = true;
                }
            }

            if (!doSlow)
            {
                int look = PEEK_BITS(JpegConstants.HUFF_LOOKAHEAD, get_buffer, bits_left);
                if ((nb = htbl.look_nbits[look]) != 0)
                {
                    DROP_BITS(nb, ref bits_left);
                    result = htbl.look_sym[look];
                    return(true);
                }

                nb = JpegConstants.HUFF_LOOKAHEAD + 1;
            }

            result = jpeg_huff_decode(ref state, get_buffer, bits_left, htbl, nb);
            if (result < 0)
            {
                return(false);
            }

            get_buffer = state.get_buffer;
            bits_left  = state.bits_left;

            return(true);
        }
        /// <summary>
        /// Expand a Huffman table definition into the derived format
        /// This routine also performs some validation checks on the table.
        /// </summary>
        protected void jpeg_make_d_derived_tbl(bool isDC, int tblno, ref d_derived_tbl dtbl)
        {
            /* Note that huffsize[] and huffcode[] are filled in code-length order,
             * paralleling the order of the symbols themselves in htbl.huffval[].
             */

            /* Find the input Huffman table */
            if (tblno < 0 || tblno >= JpegConstants.NUM_HUFF_TBLS)
            {
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);
            }

            JHUFF_TBL htbl = isDC ? m_cinfo.m_dc_huff_tbl_ptrs[tblno] : m_cinfo.m_ac_huff_tbl_ptrs[tblno];

            if (htbl == null)
            {
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);
            }

            /* Allocate a workspace if we haven't already done so. */
            if (dtbl == null)
            {
                dtbl = new d_derived_tbl();
            }

            dtbl.pub = htbl;       /* fill in back link */

            /* Figure C.1: make table of Huffman code length for each symbol */

            int p = 0;

            char[] huffsize = new char[257];
            for (int l = 1; l <= 16; l++)
            {
                int i = htbl.Bits[l];
                if (i < 0 || p + i > 256)    /* protect against table overrun */
                {
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }

                while ((i--) != 0)
                {
                    huffsize[p++] = (char)l;
                }
            }
            huffsize[p] = (char)0;
            int numsymbols = p;

            /* Figure C.2: generate the codes themselves */
            /* We also validate that the counts represent a legal Huffman code tree. */

            int code = 0;
            int si   = huffsize[0];

            int[] huffcode = new int[257];
            p = 0;
            while (huffsize[p] != 0)
            {
                while (((int)huffsize[p]) == si)
                {
                    huffcode[p++] = code;
                    code++;
                }

                /* code is now 1 more than the last code used for codelength si; but
                 * it must still fit in si bits, since no code is allowed to be all ones.
                 */
                if (code >= (1 << si))
                {
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }
                code <<= 1;
                si++;
            }

            /* Figure F.15: generate decoding tables for bit-sequential decoding */

            p = 0;
            for (int l = 1; l <= 16; l++)
            {
                if (htbl.Bits[l] != 0)
                {
                    /* valoffset[l] = huffval[] index of 1st symbol of code length l,
                     * minus the minimum code of length l
                     */
                    dtbl.valoffset[l] = p - huffcode[p];
                    p += htbl.Bits[l];
                    dtbl.maxcode[l] = huffcode[p - 1]; /* maximum code of length l */
                }
                else
                {
                    /* -1 if no codes of this length */
                    dtbl.maxcode[l] = -1;
                }
            }
            dtbl.maxcode[17] = 0xFFFFF; /* ensures jpeg_huff_decode terminates */

            /* Compute lookahead tables to speed up decoding.
             * First we set all the table entries to 0, indicating "too long";
             * then we iterate through the Huffman codes that are short enough and
             * fill in all the entries that correspond to bit sequences starting
             * with that code.
             */

            Array.Clear(dtbl.look_nbits, 0, dtbl.look_nbits.Length);
            p = 0;
            for (int l = 1; l <= JpegConstants.HUFF_LOOKAHEAD; l++)
            {
                for (int i = 1; i <= htbl.Bits[l]; i++, p++)
                {
                    /* l = current code's length, p = its index in huffcode[] & huffval[]. */
                    /* Generate left-justified code followed by all possible bit sequences */
                    int lookbits = huffcode[p] << (JpegConstants.HUFF_LOOKAHEAD - l);
                    for (int ctr = 1 << (JpegConstants.HUFF_LOOKAHEAD - l); ctr > 0; ctr--)
                    {
                        dtbl.look_nbits[lookbits] = l;
                        dtbl.look_sym[lookbits]   = htbl.Huffval[p];
                        lookbits++;
                    }
                }
            }

            /* Validate symbols as being reasonable.
             * For AC tables, we make no check, but accept all byte values 0..255.
             * For DC tables, we require the symbols to be in range 0..15.
             * (Tighter bounds could be applied depending on the data depth and mode,
             * but this is sufficient to ensure safe decoding.)
             */
            if (isDC)
            {
                for (int i = 0; i < numsymbols; i++)
                {
                    int sym = htbl.Huffval[i];
                    if (sym < 0 || sym > 15)
                    {
                        m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                    }
                }
            }
        }
        /// <summary>
        /// Initialize for a Huffman-compressed scan.
        /// </summary>
        public override void start_pass()
        {
            /* Validate scan parameters */
            bool bad = false;
            bool is_DC_band = (m_cinfo.m_Ss == 0);
            if (is_DC_band)
            {
                if (m_cinfo.m_Se != 0)
                    bad = true;
            }
            else
            {
                /* need not check Ss/Se < 0 since they came from unsigned bytes */
                if (m_cinfo.m_Ss > m_cinfo.m_Se || m_cinfo.m_Se >= JpegConstants.DCTSIZE2)
                    bad = true;

                /* AC scans may have only one component */
                if (m_cinfo.m_comps_in_scan != 1)
                    bad = true;
            }

            if (m_cinfo.m_Ah != 0)
            {
                /* Successive approximation refinement scan: must have Al = Ah-1. */
                if (m_cinfo.m_Al != m_cinfo.m_Ah - 1)
                    bad = true;
            }

            if (m_cinfo.m_Al > 13)
            {
                /* need not check for < 0 */
                bad = true;
            }

            /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
             * but the spec doesn't say so, and we try to be liberal about what we
             * accept.  Note: large Al values could result in out-of-range DC
             * coefficients during early scans, leading to bizarre displays due to
             * overflows in the IDCT math.  But we won't crash.
             */
            if (bad)
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_PROGRESSION, m_cinfo.m_Ss, m_cinfo.m_Se, m_cinfo.m_Ah, m_cinfo.m_Al);

            /* Update progression status, and verify that scan order is legal.
             * Note that inter-scan inconsistencies are treated as warnings
             * not fatal errors ... not clear if this is right way to behave.
             */
            for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
            {
                int cindex = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]].Component_index;
                if (!is_DC_band && m_cinfo.m_coef_bits[cindex][0] < 0) /* AC without prior DC scan */
                    m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_BOGUS_PROGRESSION, cindex, 0);

                for (int coefi = m_cinfo.m_Ss; coefi <= m_cinfo.m_Se; coefi++)
                {
                    int expected = m_cinfo.m_coef_bits[cindex][coefi];
                    if (expected < 0)
                        expected = 0;

                    if (m_cinfo.m_Ah != expected)
                        m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_BOGUS_PROGRESSION, cindex, coefi);

                    m_cinfo.m_coef_bits[cindex][coefi] = m_cinfo.m_Al;
                }
            }

            /* Select MCU decoding routine */
            if (m_cinfo.m_Ah == 0)
            {
                if (is_DC_band)
                    m_decoder = MCUDecoder.mcu_DC_first_decoder;
                else
                    m_decoder = MCUDecoder.mcu_AC_first_decoder;
            }
            else
            {
                if (is_DC_band)
                    m_decoder = MCUDecoder.mcu_DC_refine_decoder;
                else
                    m_decoder = MCUDecoder.mcu_AC_refine_decoder;
            }

            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]];
                /* Make sure requested tables are present, and compute derived tables.
                 * We may build same derived table more than once, but it's not expensive.
                 */
                if (is_DC_band)
                {
                    if (m_cinfo.m_Ah == 0)
                    {
                        /* DC refinement needs no table */
                        jpeg_make_d_derived_tbl(true, componentInfo.Dc_tbl_no, ref m_derived_tbls[componentInfo.Dc_tbl_no]);
                    }
                }
                else
                {
                    jpeg_make_d_derived_tbl(false, componentInfo.Ac_tbl_no, ref m_derived_tbls[componentInfo.Ac_tbl_no]);

                    /* remember the single active table */
                    m_ac_derived_tbl = m_derived_tbls[componentInfo.Ac_tbl_no];
                }

                /* Initialize DC predictions to 0 */
                m_saved.last_dc_val[ci] = 0;
            }

            /* Initialize bitread state variables */
            m_bitstate.bits_left = 0;
            m_bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
            m_insufficient_data = false;

            /* Initialize private state variables */
            m_saved.EOBRUN = 0;

            /* Initialize restart counter */
            m_restarts_to_go = m_cinfo.m_restart_interval;
        }
예제 #8
0
        /// <summary>
        /// Initialize for a Huffman-compressed scan.
        /// </summary>
        public override void start_pass()
        {
            /* Validate scan parameters */
            bool bad        = false;
            bool is_DC_band = (m_cinfo.m_Ss == 0);

            if (is_DC_band)
            {
                if (m_cinfo.m_Se != 0)
                {
                    bad = true;
                }
            }
            else
            {
                /* need not check Ss/Se < 0 since they came from unsigned bytes */
                if (m_cinfo.m_Ss > m_cinfo.m_Se || m_cinfo.m_Se >= JpegConstants.DCTSIZE2)
                {
                    bad = true;
                }

                /* AC scans may have only one component */
                if (m_cinfo.m_comps_in_scan != 1)
                {
                    bad = true;
                }
            }

            if (m_cinfo.m_Ah != 0)
            {
                /* Successive approximation refinement scan: must have Al = Ah-1. */
                if (m_cinfo.m_Al != m_cinfo.m_Ah - 1)
                {
                    bad = true;
                }
            }

            if (m_cinfo.m_Al > 13)
            {
                /* need not check for < 0 */
                bad = true;
            }

            /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
             * but the spec doesn't say so, and we try to be liberal about what we
             * accept.  Note: large Al values could result in out-of-range DC
             * coefficients during early scans, leading to bizarre displays due to
             * overflows in the IDCT math.  But we won't crash.
             */
            if (bad)
            {
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_PROGRESSION, m_cinfo.m_Ss, m_cinfo.m_Se, m_cinfo.m_Ah, m_cinfo.m_Al);
            }

            /* Update progression status, and verify that scan order is legal.
             * Note that inter-scan inconsistencies are treated as warnings
             * not fatal errors ... not clear if this is right way to behave.
             */
            for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
            {
                int cindex = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]].Component_index;
                if (!is_DC_band && m_cinfo.m_coef_bits[cindex][0] < 0) /* AC without prior DC scan */
                {
                    m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_BOGUS_PROGRESSION, cindex, 0);
                }

                for (int coefi = m_cinfo.m_Ss; coefi <= m_cinfo.m_Se; coefi++)
                {
                    int expected = m_cinfo.m_coef_bits[cindex][coefi];
                    if (expected < 0)
                    {
                        expected = 0;
                    }

                    if (m_cinfo.m_Ah != expected)
                    {
                        m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_BOGUS_PROGRESSION, cindex, coefi);
                    }

                    m_cinfo.m_coef_bits[cindex][coefi] = m_cinfo.m_Al;
                }
            }

            /* Select MCU decoding routine */
            if (m_cinfo.m_Ah == 0)
            {
                if (is_DC_band)
                {
                    m_decoder = MCUDecoder.mcu_DC_first_decoder;
                }
                else
                {
                    m_decoder = MCUDecoder.mcu_AC_first_decoder;
                }
            }
            else
            {
                if (is_DC_band)
                {
                    m_decoder = MCUDecoder.mcu_DC_refine_decoder;
                }
                else
                {
                    m_decoder = MCUDecoder.mcu_AC_refine_decoder;
                }
            }

            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]];

                /* Make sure requested tables are present, and compute derived tables.
                 * We may build same derived table more than once, but it's not expensive.
                 */
                if (is_DC_band)
                {
                    if (m_cinfo.m_Ah == 0)
                    {
                        /* DC refinement needs no table */
                        jpeg_make_d_derived_tbl(true, componentInfo.Dc_tbl_no, ref m_derived_tbls[componentInfo.Dc_tbl_no]);
                    }
                }
                else
                {
                    jpeg_make_d_derived_tbl(false, componentInfo.Ac_tbl_no, ref m_derived_tbls[componentInfo.Ac_tbl_no]);

                    /* remember the single active table */
                    m_ac_derived_tbl = m_derived_tbls[componentInfo.Ac_tbl_no];
                }

                /* Initialize DC predictions to 0 */
                m_saved.last_dc_val[ci] = 0;
            }

            /* Initialize bitread state variables */
            m_bitstate.bits_left  = 0;
            m_bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
            m_insufficient_data   = false;

            /* Initialize private state variables */
            m_saved.EOBRUN = 0;

            /* Initialize restart counter */
            m_restarts_to_go = m_cinfo.m_restart_interval;
        }
예제 #9
0
        /// <summary>
        /// Initialize for a Huffman-compressed scan.
        /// </summary>
        public override void start_pass()
        {
            if (m_cinfo.m_progressive_mode)
            {
                bool bad = false;
                /* Validate progressive scan parameters */
                if (m_cinfo.m_Ss == 0)
                {
                    if (m_cinfo.m_Se != 0)
                        bad = true;
                }
                else
                {
                    /* need not check Ss/Se < 0 since they came from unsigned bytes */
                    if (m_cinfo.m_Se < m_cinfo.m_Ss || m_cinfo.m_Se > m_cinfo.lim_Se)
                        bad = true;

                    /* AC scans may have only one component */
                    if (m_cinfo.m_comps_in_scan != 1)
                        bad = true;
                }

                if (m_cinfo.m_Ah != 0)
                {
                    /* Successive approximation refinement scan: must have Al = Ah-1. */
                    if (m_cinfo.m_Ah - 1 != m_cinfo.m_Al)
                        bad = true;
                }

                if (m_cinfo.m_Al > 13)
                {
                    /* need not check for < 0 */
                    /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
                     * but the spec doesn't say so, and we try to be liberal about what we
                     * accept.  Note: large Al values could result in out-of-range DC
                     * coefficients during early scans, leading to bizarre displays due to
                     * overflows in the IDCT math.  But we won't crash.
                     */
                    bad = true;
                }

                if (bad)
                {
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_PROGRESSION,
                        m_cinfo.m_Ss, m_cinfo.m_Se, m_cinfo.m_Ah, m_cinfo.m_Al);
                }

                /* Update progression status, and verify that scan order is legal.
                 * Note that inter-scan inconsistencies are treated as warnings
                 * not fatal errors ... not clear if this is right way to behave.
                 */
                for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
                {
                    int cindex = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]].Component_index;
                    if (m_cinfo.m_Ss != 0 && m_cinfo.m_coef_bits[cindex][0] < 0)
                    {
                        /* AC without prior DC scan */
                        m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_BOGUS_PROGRESSION, cindex, 0);
                    }

                    for (int coefi = m_cinfo.m_Ss; coefi <= m_cinfo.m_Se; coefi++)
                    {
                        int expected = m_cinfo.m_coef_bits[cindex][coefi];
                        if (expected < 0)
                            expected = 0;

                        if (m_cinfo.m_Ah != expected)
                            m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_BOGUS_PROGRESSION, cindex, coefi);

                        m_cinfo.m_coef_bits[cindex][coefi] = m_cinfo.m_Al;
                    }
                }

                /* Select MCU decoding routine */
                if (m_cinfo.m_Ah == 0)
                {
                    if (m_cinfo.m_Ss == 0)
                        decode_mcu = decode_mcu_DC_first;
                    else
                        decode_mcu = decode_mcu_AC_first;
                }
                else
                {
                    if (m_cinfo.m_Ss == 0)
                        decode_mcu = decode_mcu_DC_refine;
                    else
                        decode_mcu = decode_mcu_AC_refine;
                }

                for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
                {
                    jpeg_component_info compptr = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]];

                    /* Make sure requested tables are present, and compute derived tables.
                     * We may build same derived table more than once, but it's not expensive.
                     */
                    if (m_cinfo.m_Ss == 0)
                    {
                        if (m_cinfo.m_Ah == 0)
                        {
                            /* DC refinement needs no table */
                            int tbl = compptr.Dc_tbl_no;
                            jpeg_make_d_derived_tbl(true, tbl, ref derived_tbls[tbl]);
                        }
                    }
                    else
                    {
                        int tbl = compptr.Ac_tbl_no;
                        jpeg_make_d_derived_tbl(false, tbl, ref derived_tbls[tbl]);

                        /* remember the single active table */
                        ac_derived_tbl = derived_tbls[tbl];
                    }

                    /* Initialize DC predictions to 0 */
                    m_saved.last_dc_val[ci] = 0;
                }

                /* Initialize private state variables */
                m_saved.EOBRUN = 0;
            }
            else
            {
                /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
                 * This ought to be an error condition, but we make it a warning because
                 * there are some baseline files out there with all zeroes in these bytes.
                 */
                if (m_cinfo.m_Ss != 0 || m_cinfo.m_Ah != 0 || m_cinfo.m_Al != 0 ||
                    ((m_cinfo.is_baseline || m_cinfo.m_Se < JpegConstants.DCTSIZE2) &&
                    m_cinfo.m_Se != m_cinfo.lim_Se))
                {
                    m_cinfo.WARNMS(J_MESSAGE_CODE.JWRN_NOT_SEQUENTIAL);
                }

                /* Select MCU decoding routine */
                /* We retain the hard-coded case for full-size blocks.
                 * This is not necessary, but it appears that this version is slightly
                 * more performant in the given implementation.
                 * With an improved implementation we would prefer a single optimized
                 * function.
                 */
                if (m_cinfo.lim_Se != JpegConstants.DCTSIZE2 - 1)
                    decode_mcu = decode_mcu_sub;
                else
                    decode_mcu = decode_mcu_full;

                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]];

                    /* Compute derived values for Huffman tables */
                    /* We may do this more than once for a table, but it's not expensive */

                    int tbl = componentInfo.Dc_tbl_no;
                    jpeg_make_d_derived_tbl(true, tbl, ref m_dc_derived_tbls[tbl]);

                    if (m_cinfo.lim_Se != 0)
                    {
                        /* AC needs no table when not present */
                        tbl = componentInfo.Ac_tbl_no;
                        jpeg_make_d_derived_tbl(false, tbl, ref m_ac_derived_tbls[tbl]);
                    }

                    /* Initialize DC predictions to 0 */
                    m_saved.last_dc_val[ci] = 0;
                }

                /* Precalculate decoding info for each block in an MCU of this scan */
                for (int blkn = 0; blkn < m_cinfo.m_blocks_in_MCU; blkn++)
                {
                    int ci = m_cinfo.m_MCU_membership[blkn];
                    jpeg_component_info componentInfo = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]];

                    /* Precalculate which table to use for each block */
                    m_dc_cur_tbls[blkn] = m_dc_derived_tbls[componentInfo.Dc_tbl_no];
                    m_ac_cur_tbls[blkn] = m_ac_derived_tbls[componentInfo.Ac_tbl_no];

                    /* Decide whether we really care about the coefficient values */
                    if (componentInfo.component_needed)
                    {
                        ci = componentInfo.DCT_v_scaled_size;
                        int i = componentInfo.DCT_h_scaled_size;
                        switch (m_cinfo.lim_Se)
                        {
                            case (1 * 1 - 1):
                                coef_limit[blkn] = 1;
                                break;

                            case (2 * 2 - 1):
                                if (ci <= 0 || ci > 2)
                                    ci = 2;

                                if (i <= 0 || i > 2)
                                    i = 2;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order2[ci - 1][i - 1];
                                break;

                            case (3 * 3 - 1):
                                if (ci <= 0 || ci > 3)
                                    ci = 3;

                                if (i <= 0 || i > 3)
                                    i = 3;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order3[ci - 1][i - 1];
                                break;

                            case (4 * 4 - 1):
                                if (ci <= 0 || ci > 4)
                                    ci = 4;

                                if (i <= 0 || i > 4)
                                    i = 4;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order4[ci - 1][i - 1];
                                break;

                            case (5 * 5 - 1):
                                if (ci <= 0 || ci > 5)
                                    ci = 5;

                                if (i <= 0 || i > 5)
                                    i = 5;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order5[ci - 1][i - 1];
                                break;

                            case (6 * 6 - 1):
                                if (ci <= 0 || ci > 6)
                                    ci = 6;

                                if (i <= 0 || i > 6)
                                    i = 6;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order6[ci - 1][i - 1];
                                break;

                            case (7 * 7 - 1):
                                if (ci <= 0 || ci > 7)
                                    ci = 7;

                                if (i <= 0 || i > 7)
                                    i = 7;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order7[ci - 1][i - 1];
                                break;

                            default:
                                if (ci <= 0 || ci > 8)
                                    ci = 8;

                                if (i <= 0 || i > 8)
                                    i = 8;

                                coef_limit[blkn] = 1 + jpeg_zigzag_order[ci - 1][i - 1];
                                break;
                        }
                    }
                    else
                    {
                        coef_limit[blkn] = 0;
                    }
                }

                /* Initialize bitread state variables */
                m_bitstate.bits_left = 0;
                m_bitstate.get_buffer = 0;
                m_insufficient_data = false;

                /* Initialize restart counter */
                m_restarts_to_go = m_cinfo.m_restart_interval;
            }
        }