Exemplo n.º 1
0
 // Emit (or just count) a Huffman symbol.
 static void emit_symbol(phuff_entropy_encoder entropy, int tbl_no, int symbol)
 {
     if (entropy.gather_statistics)
     {
         entropy.count_ptrs[tbl_no][symbol]++;
     }
     else
     {
         c_derived_tbl tbl = entropy.derived_tbls[tbl_no];
         emit_bits(entropy, tbl.ehufco[symbol], tbl.ehufsi[symbol]);
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Expand a Huffman table definition into the derived format
        /// Compute the derived values for a Huffman table.
        /// This routine also performs some validation checks on the table.
        /// </summary>
        protected void jpeg_make_c_derived_tbl(bool isDC, int tblno, ref c_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 c_derived_tbl();
            }

            /* 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 lastp = 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];

            p = 0;
            int[] huffcode = new int[257];
            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 C.3: generate encoding tables */
            /* These are code and size indexed by symbol value */

            /* Set all codeless symbols to have code length 0;
             * this lets us detect duplicate VAL entries here, and later
             * allows emit_bits to detect any attempt to emit such symbols.
             */
            Array.Clear(dtbl.ehufsi, 0, dtbl.ehufsi.Length);

            /* This is also a convenient place to check for out-of-range
             * and duplicated VAL entries.  We allow 0..255 for AC symbols
             * but only 0..15 for DC.  (We could constrain them further
             * based on data depth and mode, but this seems enough.)
             */
            int maxsymbol = isDC ? 15 : 255;

            for (p = 0; p < lastp; p++)
            {
                int i = htbl.Huffval[p];
                if (i < 0 || i > maxsymbol || dtbl.ehufsi[i] != 0)
                {
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }

                dtbl.ehufco[i] = huffcode[p];
                dtbl.ehufsi[i] = huffsize[p];
            }
        }
        /// <summary>
        /// Expand a Huffman table definition into the derived format
        /// Compute the derived values for a Huffman table.
        /// This routine also performs some validation checks on the table.
        /// </summary>
        protected void jpeg_make_c_derived_tbl(bool isDC, int tblno, ref c_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 c_derived_tbl();

            /* 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 lastp = 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];
            p = 0;
            int[] huffcode = new int[257];
            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 C.3: generate encoding tables */
            /* These are code and size indexed by symbol value */

            /* Set all codeless symbols to have code length 0;
            * this lets us detect duplicate VAL entries here, and later
            * allows emit_bits to detect any attempt to emit such symbols.
            */
            Array.Clear(dtbl.ehufsi, 0, dtbl.ehufsi.Length);

            /* This is also a convenient place to check for out-of-range
            * and duplicated VAL entries.  We allow 0..255 for AC symbols
            * but only 0..15 for DC.  (We could constrain them further
            * based on data depth and mode, but this seems enough.)
            */
            int maxsymbol = isDC ? 15 : 255;

            for (p = 0; p < lastp; p++)
            {
                int i = htbl.Huffval[p];
                if (i < 0 || i> maxsymbol || dtbl.ehufsi[i] != 0)
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);

                dtbl.ehufco[i] = huffcode[p];
                dtbl.ehufsi[i] = huffsize[p];
            }
        }
Exemplo n.º 4
0
		// Expand a Huffman table definition into the derived format
		// Compute the derived values for a Huffman table.
		// This routine also performs some validation checks on the table.
		static void jpeg_make_c_derived_tbl(jpeg_compress cinfo, bool isDC, int tblno, ref c_derived_tbl pdtbl)
		{
			// 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>=NUM_HUFF_TBLS) ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);
			JHUFF_TBL htbl=isDC?cinfo.dc_huff_tbl_ptrs[tblno]:cinfo.ac_huff_tbl_ptrs[tblno];
			if(htbl==null) ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);

			// Allocate a workspace if we haven't already done so.
			if(pdtbl==null)
			{
				try
				{
					pdtbl=new c_derived_tbl();
				}
				catch
				{
					ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
				}
			}

			c_derived_tbl dtbl=pdtbl;

			// Figure C.1: make table of Huffman code length for each symbol
			byte[] huffsize=new byte[257]; 
			int p=0;
			for(byte l=1; l<=16; l++)
			{
				int i=htbl.bits[l];
				// protect against table overrun
				if(i<0||(p+i)>256) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
				while((i--)!=0) huffsize[p++]=l;
			}
			huffsize[p]=0;
			int lastp=p;

			// Figure C.2: generate the codes themselves
			// We also validate that the counts represent a legal Huffman code tree.
			uint[] huffcode=new uint[257];
			uint code=0;
			int si=huffsize[0];
			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(((int)code)>=(1<<si)) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
				code<<=1;
				si++;
			}

			// Figure C.3: generate encoding tables
			// These are code and size indexed by symbol value

			// Set all codeless symbols to have code length 0;
			// this lets us detect duplicate VAL entries here, and later
			// allows emit_bits to detect any attempt to emit such symbols.
			for(int i=0; i<256; i++) dtbl.ehufsi[i]=0;

			// This is also a convenient place to check for out-of-range
			// and duplicated VAL entries. We allow 0..255 for AC symbols
			// but only 0..16 for DC. (We could constrain them further
			// based on data depth and mode, but this seems enough.)
			int maxsymbol=isDC?16:255;

			for(p=0; p<lastp; p++)
			{
				int i=htbl.huffval[p];
				if(i<0||i>maxsymbol||dtbl.ehufsi[i]!=0) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
				dtbl.ehufco[i]=huffcode[p];
				dtbl.ehufsi[i]=huffsize[p];
			}
		}
Exemplo n.º 5
0
        /// <summary>
        /// Encode a single block's worth of coefficients
        /// </summary>
        private bool encode_one_block(savable_state state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl)
        {
            /* Encode the DC coefficient difference per section F.1.2.1 */
            int temp  = block[0] - last_dc_val;
            int temp2 = temp;

            if (temp < 0)
            {
                temp = -temp;       /* temp is abs value of input */
                /* For a negative input, want temp2 = bitwise complement of abs(input) */
                /* This code assumes we are on a two's complement machine */
                temp2--;
            }

            /* Find the number of bits needed for the magnitude of the coefficient */
            int nbits = 0;

            while (temp != 0)
            {
                nbits++;
                temp >>= 1;
            }

            /* Check for out-of-range coefficient values.
             * Since we're encoding a difference, the range limit is twice as much.
             */
            if (nbits > MAX_HUFFMAN_COEF_BITS + 1)
            {
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF);
            }

            /* Emit the Huffman-coded symbol for the number of bits */
            if (!emit_bits(state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits]))
            {
                return(false);
            }

            /* Emit that number of bits of the value, if positive, */
            /* or the complement of its magnitude, if negative. */
            if (nbits != 0)
            {
                /* emit_bits rejects calls with size 0 */
                if (!emit_bits(state, temp2, nbits))
                {
                    return(false);
                }
            }

            /* Encode the AC coefficients per section F.1.2.2 */
            int r = 0;          /* r = run length of zeros */

            for (int k = 1; k < JpegConstants.DCTSIZE2; k++)
            {
                temp = block[JpegUtils.jpeg_natural_order[k]];
                if (temp == 0)
                {
                    r++;
                }
                else
                {
                    /* if run length > 15, must emit special run-length-16 codes (0xF0) */
                    while (r > 15)
                    {
                        if (!emit_bits(state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0]))
                        {
                            return(false);
                        }
                        r -= 16;
                    }

                    temp2 = temp;
                    if (temp < 0)
                    {
                        temp = -temp;       /* temp is abs value of input */
                        /* This code assumes we are on a two's complement machine */
                        temp2--;
                    }

                    /* Find the number of bits needed for the magnitude of the coefficient */
                    nbits = 1;      /* there must be at least one 1 bit */
                    while ((temp >>= 1) != 0)
                    {
                        nbits++;
                    }

                    /* Check for out-of-range coefficient values */
                    if (nbits > MAX_HUFFMAN_COEF_BITS)
                    {
                        m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF);
                    }

                    /* Emit Huffman symbol for run length / number of bits */
                    int i = (r << 4) + nbits;
                    if (!emit_bits(state, actbl.ehufco[i], actbl.ehufsi[i]))
                    {
                        return(false);
                    }

                    /* Emit that number of bits of the value, if positive, */
                    /* or the complement of its magnitude, if negative. */
                    if (!emit_bits(state, temp2, nbits))
                    {
                        return(false);
                    }

                    r = 0;
                }
            }

            /* If the last coef(s) were zero, emit an end-of-block code */
            if (r > 0)
            {
                if (!emit_bits(state, actbl.ehufco[0], actbl.ehufsi[0]))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Encode a single block's worth of coefficients
        /// </summary>
        private bool encode_one_block(savable_state state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl)
        {
            /* Encode the DC coefficient difference per section F.1.2.1 */
            int temp = block[0] - last_dc_val;
            int temp2 = temp;
            if (temp < 0)
            {
                temp = -temp;       /* temp is abs value of input */
                /* For a negative input, want temp2 = bitwise complement of abs(input) */
                /* This code assumes we are on a two's complement machine */
                temp2--;
            }

            /* Find the number of bits needed for the magnitude of the coefficient */
            int nbits = 0;
            while (temp != 0)
            {
                nbits++;
                temp >>= 1;
            }

            /* Check for out-of-range coefficient values.
             * Since we're encoding a difference, the range limit is twice as much.
             */
            if (nbits > MAX_HUFFMAN_COEF_BITS + 1)
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF);

            /* Emit the Huffman-coded symbol for the number of bits */
            if (!emit_bits(state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits]))
                return false;

            /* Emit that number of bits of the value, if positive, */
            /* or the complement of its magnitude, if negative. */
            if (nbits != 0)
            {
                /* emit_bits rejects calls with size 0 */
                if (!emit_bits(state, temp2, nbits))
                    return false;
            }

            /* Encode the AC coefficients per section F.1.2.2 */
            int r = 0;          /* r = run length of zeros */
            for (int k = 1; k < JpegConstants.DCTSIZE2; k++)
            {
                temp = block[JpegUtils.jpeg_natural_order[k]];
                if (temp == 0)
                {
                    r++;
                }
                else
                {
                    /* if run length > 15, must emit special run-length-16 codes (0xF0) */
                    while (r > 15)
                    {
                        if (!emit_bits(state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0]))
                            return false;
                        r -= 16;
                    }

                    temp2 = temp;
                    if (temp < 0)
                    {
                        temp = -temp;       /* temp is abs value of input */
                        /* This code assumes we are on a two's complement machine */
                        temp2--;
                    }

                    /* Find the number of bits needed for the magnitude of the coefficient */
                    nbits = 1;      /* there must be at least one 1 bit */
                    while ((temp >>= 1) != 0)
                        nbits++;

                    /* Check for out-of-range coefficient values */
                    if (nbits > MAX_HUFFMAN_COEF_BITS)
                        m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF);

                    /* Emit Huffman symbol for run length / number of bits */
                    int i = (r << 4) + nbits;
                    if (!emit_bits(state, actbl.ehufco[i], actbl.ehufsi[i]))
                        return false;

                    /* Emit that number of bits of the value, if positive, */
                    /* or the complement of its magnitude, if negative. */
                    if (!emit_bits(state, temp2, nbits))
                        return false;

                    r = 0;
                }
            }

            /* If the last coef(s) were zero, emit an end-of-block code */
            if (r > 0)
            {
                if (!emit_bits(state, actbl.ehufco[0], actbl.ehufsi[0]))
                    return false;
            }

            return true;
        }
Exemplo n.º 7
0
        // Huffman coding optimization.
        //
        // We first scan the supplied data and count the number of uses of each symbol
        // that is to be Huffman-coded. (This process MUST agree with the code above.)
        // Then we build a Huffman coding tree for the observed counts.
        // Symbols which are not needed at all for the particular image are not
        // assigned any code, which saves space in the DHT marker as well as in
        // the compressed data.
#if ENTROPY_OPT_SUPPORTED
        // Trial-encode one nMCU's worth of Huffman-compressed differences.
        // No data is actually output, so no suspension return is possible.
        static uint encode_mcus_gather_ls(jpeg_compress cinfo, int[][][] diff_buf, uint MCU_row_num, uint MCU_col_num, uint nMCU)
        {
            jpeg_lossless_c_codec losslsc = (jpeg_lossless_c_codec)cinfo.coef;
            lhuff_entropy_encoder entropy = (lhuff_entropy_encoder)losslsc.entropy_private;

            // Take care of restart intervals if needed
            if (cinfo.restart_interval != 0)
            {
                if (entropy.restarts_to_go == 0)
                {
                    entropy.restarts_to_go = cinfo.restart_interval;                                         // Update restart state
                }
                entropy.restarts_to_go--;
            }

            // Set input pointer locations based on MCU_col_num
            for (int ptrn = 0; ptrn < entropy.num_input_ptrs; ptrn++)
            {
                int ci        = entropy.input_ptr_info[ptrn].ci;
                int yoffset   = entropy.input_ptr_info[ptrn].yoffset;
                int MCU_width = entropy.input_ptr_info[ptrn].MCU_width;
                entropy.input_ptr[ptrn]     = diff_buf[ci][MCU_row_num + yoffset];
                entropy.input_ptr_ind[ptrn] = (int)MCU_col_num * MCU_width;
            }

            for (uint mcu_num = 0; mcu_num < nMCU; mcu_num++)
            {
                // Inner loop handles the samples in the MCU
                for (int sampn = 0; sampn < cinfo.block_in_MCU; sampn++)
                {
                    c_derived_tbl dctbl  = entropy.cur_tbls[sampn];
                    int[]         counts = entropy.cur_counts[sampn];

                    // Encode the difference per section H.1.2.2

                    // Input the sample difference
                    int temp3 = entropy.input_ptr_index[sampn];
                    int temp  = entropy.input_ptr[temp3][entropy.input_ptr_ind[temp3]++];

                    if ((temp & 0x8000) != 0)
                    {                            // instead of temp < 0
                        temp = (-temp) & 0x7FFF; // absolute value, mod 2^16
                        if (temp == 0)
                        {
                            temp = 0x8000;                                      // special case: magnitude = 32768
                        }
                    }
                    else
                    {
                        temp &= 0x7FFF;                                                 // abs value mod 2^16
                    }
                    // Find the number of bits needed for the magnitude of the difference
                    int nbits = 0;
                    while (temp != 0)
                    {
                        nbits++;
                        temp >>= 1;
                    }

                    // Check for out-of-range difference values.
                    if (nbits > MAX_DIFF_BITS)
                    {
                        ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_DIFF);
                    }

                    // Count the Huffman symbol for the number of bits
                    counts[nbits]++;
                }
            }

            return(nMCU);
        }
Exemplo n.º 8
0
        // Encode and output one nMCU's worth of Huffman-compressed differences.
        static uint encode_mcus_huff_ls(jpeg_compress cinfo, int[][][] diff_buf, uint MCU_row_num, uint MCU_col_num, uint nMCU)
        {
            jpeg_lossless_c_codec losslsc = (jpeg_lossless_c_codec)cinfo.coef;
            lhuff_entropy_encoder entropy = (lhuff_entropy_encoder)losslsc.entropy_private;

            // Load up working state
            working_state_ls state;

            state.output_bytes     = cinfo.dest.output_bytes;
            state.next_output_byte = cinfo.dest.next_output_byte;
            state.free_in_buffer   = cinfo.dest.free_in_buffer;
            state.cur   = entropy.saved;
            state.cinfo = cinfo;

            // Emit restart marker if needed
            if (cinfo.restart_interval != 0)
            {
                if (entropy.restarts_to_go == 0)
                {
                    if (!emit_restart(ref state, entropy.next_restart_num))
                    {
                        return(0);
                    }
                }
            }

            // Set input pointer locations based on MCU_col_num
            for (int ptrn = 0; ptrn < entropy.num_input_ptrs; ptrn++)
            {
                int ci        = entropy.input_ptr_info[ptrn].ci;
                int yoffset   = entropy.input_ptr_info[ptrn].yoffset;
                int MCU_width = entropy.input_ptr_info[ptrn].MCU_width;
                entropy.input_ptr[ptrn]     = diff_buf[ci][MCU_row_num + yoffset];
                entropy.input_ptr_ind[ptrn] = (int)MCU_col_num * MCU_width;
            }

            for (uint mcu_num = 0; mcu_num < nMCU; mcu_num++)
            {
                // Inner loop handles the samples in the MCU
                for (int sampn = 0; sampn < cinfo.block_in_MCU; sampn++)
                {
                    c_derived_tbl dctbl = entropy.cur_tbls[sampn];

                    // Encode the difference per section H.1.2.2

                    // Input the sample difference
                    int temp3 = entropy.input_ptr_index[sampn];
                    int temp  = entropy.input_ptr[temp3][entropy.input_ptr_ind[temp3]++];

                    int temp2;
                    if ((temp & 0x8000) != 0)
                    {                            // instead of temp < 0
                        temp = (-temp) & 0x7FFF; // absolute value, mod 2^16
                        if (temp == 0)
                        {
                            temp2 = temp = 0x8000;                              // special case: magnitude = 32768
                        }
                        temp2 = ~temp;                                          // one's complement of magnitude
                    }
                    else
                    {
                        temp &= 0x7FFF;                         // abs value mod 2^16
                        temp2 = temp;                           // magnitude
                    }

                    // Find the number of bits needed for the magnitude of the difference
                    int nbits = 0;
                    while (temp != 0)
                    {
                        nbits++;
                        temp >>= 1;
                    }

                    // Check for out-of-range difference values.
                    if (nbits > MAX_DIFF_BITS)
                    {
                        ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_DIFF);
                    }

                    // Emit the Huffman-coded symbol for the number of bits
                    if (!emit_bits(ref state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits]))
                    {
                        return(mcu_num);
                    }

                    // Emit that number of bits of the value, if positive,
                    // or the complement of its magnitude, if negative.
                    if (nbits != 0 &&                           // emit_bits rejects calls with size 0
                        nbits != 16)                            // special case: no bits should be emitted
                    {
                        if (!emit_bits(ref state, (uint)temp2, nbits))
                        {
                            return(mcu_num);
                        }
                    }
                }

                // Completed MCU, so update state
                cinfo.dest.output_bytes     = state.output_bytes;
                cinfo.dest.next_output_byte = state.next_output_byte;
                cinfo.dest.free_in_buffer   = state.free_in_buffer;
                entropy.saved = state.cur;

                // Update restart-interval state too
                if (cinfo.restart_interval != 0)
                {
                    if (entropy.restarts_to_go == 0)
                    {
                        entropy.restarts_to_go = cinfo.restart_interval;
                        entropy.next_restart_num++;
                        entropy.next_restart_num &= 7;
                    }
                    entropy.restarts_to_go--;
                }
            }

            return(nMCU);
        }
Exemplo n.º 9
0
        // Expand a Huffman table definition into the derived format
        // Compute the derived values for a Huffman table.
        // This routine also performs some validation checks on the table.
        static void jpeg_make_c_derived_tbl(jpeg_compress cinfo, bool isDC, int tblno, ref c_derived_tbl pdtbl)
        {
            // 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 >= NUM_HUFF_TBLS)
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);
            }
            JHUFF_TBL htbl = isDC?cinfo.dc_huff_tbl_ptrs[tblno]:cinfo.ac_huff_tbl_ptrs[tblno];

            if (htbl == null)
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno);
            }

            // Allocate a workspace if we haven't already done so.
            if (pdtbl == null)
            {
                try
                {
                    pdtbl = new c_derived_tbl();
                }
                catch
                {
                    ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
                }
            }

            c_derived_tbl dtbl = pdtbl;

            // Figure C.1: make table of Huffman code length for each symbol
            byte[] huffsize = new byte[257];
            int    p        = 0;

            for (byte l = 1; l <= 16; l++)
            {
                int i = htbl.bits[l];
                // protect against table overrun
                if (i < 0 || (p + i) > 256)
                {
                    ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }
                while ((i--) != 0)
                {
                    huffsize[p++] = l;
                }
            }
            huffsize[p] = 0;
            int lastp = p;

            // Figure C.2: generate the codes themselves
            // We also validate that the counts represent a legal Huffman code tree.
            uint[] huffcode = new uint[257];
            uint   code     = 0;
            int    si       = huffsize[0];

            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 (((int)code) >= (1 << si))
                {
                    ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }
                code <<= 1;
                si++;
            }

            // Figure C.3: generate encoding tables
            // These are code and size indexed by symbol value

            // Set all codeless symbols to have code length 0;
            // this lets us detect duplicate VAL entries here, and later
            // allows emit_bits to detect any attempt to emit such symbols.
            for (int i = 0; i < 256; i++)
            {
                dtbl.ehufsi[i] = 0;
            }

            // This is also a convenient place to check for out-of-range
            // and duplicated VAL entries. We allow 0..255 for AC symbols
            // but only 0..16 for DC. (We could constrain them further
            // based on data depth and mode, but this seems enough.)
            int maxsymbol = isDC?16:255;

            for (p = 0; p < lastp; p++)
            {
                int i = htbl.huffval[p];
                if (i < 0 || i > maxsymbol || dtbl.ehufsi[i] != 0)
                {
                    ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE);
                }
                dtbl.ehufco[i] = huffcode[p];
                dtbl.ehufsi[i] = huffsize[p];
            }
        }
Exemplo n.º 10
0
		// Encode a single block's worth of coefficients
		static bool encode_one_block(ref working_state_sq state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl)
		{
			// Encode the DC coefficient difference per section F.1.2.1
			int temp=block[0]-last_dc_val;
			int temp2=temp;

			if(temp<0)
			{
				temp=-temp; // temp is abs value of input
				// For a negative input, want temp2 = bitwise complement of abs(input)
				// This code assumes we are on a two's complement machine
				temp2--;
			}

			// Find the number of bits needed for the magnitude of the coefficient
			int nbits=0;
			while(temp!=0)
			{
				nbits++;
				temp>>=1;
			}

			// Check for out-of-range coefficient values.
			// Since we're encoding a difference, the range limit is twice as much.
			if(nbits>MAX_COEF_BITS+1) ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF);

			// Emit the Huffman-coded symbol for the number of bits
			if(!emit_bits(ref state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits])) return false;

			// Emit that number of bits of the value, if positive,
			// or the complement of its magnitude, if negative.
			if(nbits!=0)			// emit_bits rejects calls with size 0
			{
				if(!emit_bits(ref state, (uint)temp2, nbits)) return false;
			}

			// Encode the AC coefficients per section F.1.2.2
			int r=0; // r = run length of zeros

			for(int k=1; k<DCTSIZE2; k++)
			{
				temp=block[jpeg_natural_order[k]];
				if(temp==0)
				{
					r++;
					continue;
				}
				// if run length > 15, must emit special run-length-16 codes (0xF0)
				while(r>15)
				{
					if(!emit_bits(ref state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0])) return false;
					r-=16;
				}

				temp2=temp;
				if(temp<0)
				{
					temp=-temp; // temp is abs value of input
					// This code assumes we are on a two's complement machine
					temp2--;
				}

				// Find the number of bits needed for the magnitude of the coefficient
				nbits=1; // there must be at least one 1 bit
				while((temp>>=1)!=0) nbits++;

				// Check for out-of-range coefficient values
				if(nbits>MAX_COEF_BITS) ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF);

				// Emit Huffman symbol for run length / number of bits
				int i=(r<<4)+nbits;
				if(!emit_bits(ref state, actbl.ehufco[i], actbl.ehufsi[i])) return false;

				// Emit that number of bits of the value, if positive,
				// or the complement of its magnitude, if negative.
				if(!emit_bits(ref state, (uint)temp2, nbits)) return false;

				r=0;
			}

			// If the last coef(s) were zero, emit an end-of-block code
			if(r>0)
			{
				if(!emit_bits(ref state, actbl.ehufco[0], actbl.ehufsi[0])) return false;
			}

			return true;
		}
Exemplo n.º 11
0
        // Encode a single block's worth of coefficients
        static bool encode_one_block(ref working_state_sq state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl)
        {
            // Encode the DC coefficient difference per section F.1.2.1
            int temp  = block[0] - last_dc_val;
            int temp2 = temp;

            if (temp < 0)
            {
                temp = -temp;               // temp is abs value of input
                // For a negative input, want temp2 = bitwise complement of abs(input)
                // This code assumes we are on a two's complement machine
                temp2--;
            }

            // Find the number of bits needed for the magnitude of the coefficient
            int nbits = 0;

            while (temp != 0)
            {
                nbits++;
                temp >>= 1;
            }

            // Check for out-of-range coefficient values.
            // Since we're encoding a difference, the range limit is twice as much.
            if (nbits > MAX_COEF_BITS + 1)
            {
                ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF);
            }

            // Emit the Huffman-coded symbol for the number of bits
            if (!emit_bits(ref state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits]))
            {
                return(false);
            }

            // Emit that number of bits of the value, if positive,
            // or the complement of its magnitude, if negative.
            if (nbits != 0)                             // emit_bits rejects calls with size 0
            {
                if (!emit_bits(ref state, (uint)temp2, nbits))
                {
                    return(false);
                }
            }

            // Encode the AC coefficients per section F.1.2.2
            int r = 0;           // r = run length of zeros

            for (int k = 1; k < DCTSIZE2; k++)
            {
                temp = block[jpeg_natural_order[k]];
                if (temp == 0)
                {
                    r++;
                    continue;
                }
                // if run length > 15, must emit special run-length-16 codes (0xF0)
                while (r > 15)
                {
                    if (!emit_bits(ref state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0]))
                    {
                        return(false);
                    }
                    r -= 16;
                }

                temp2 = temp;
                if (temp < 0)
                {
                    temp = -temp;                   // temp is abs value of input
                    // This code assumes we are on a two's complement machine
                    temp2--;
                }

                // Find the number of bits needed for the magnitude of the coefficient
                nbits = 1;               // there must be at least one 1 bit
                while ((temp >>= 1) != 0)
                {
                    nbits++;
                }

                // Check for out-of-range coefficient values
                if (nbits > MAX_COEF_BITS)
                {
                    ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF);
                }

                // Emit Huffman symbol for run length / number of bits
                int i = (r << 4) + nbits;
                if (!emit_bits(ref state, actbl.ehufco[i], actbl.ehufsi[i]))
                {
                    return(false);
                }

                // Emit that number of bits of the value, if positive,
                // or the complement of its magnitude, if negative.
                if (!emit_bits(ref state, (uint)temp2, nbits))
                {
                    return(false);
                }

                r = 0;
            }

            // If the last coef(s) were zero, emit an end-of-block code
            if (r > 0)
            {
                if (!emit_bits(ref state, actbl.ehufco[0], actbl.ehufsi[0]))
                {
                    return(false);
                }
            }

            return(true);
        }