// Emit a DHT marker static void emit_dht(jpeg_compress cinfo, int index, bool is_ac) { JHUFF_TBL htbl=null; if(is_ac) { htbl=cinfo.ac_huff_tbl_ptrs[index]; index+=0x10; // output index has AC bit set } else htbl=cinfo.dc_huff_tbl_ptrs[index]; if(htbl==null) ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, index); if(!htbl.sent_table) { emit_marker(cinfo, JPEG_MARKER.M_DHT); int length=0; for(int i=1; i<=16; i++) length+=htbl.bits[i]; emit_2bytes(cinfo, length+2+1+16); emit_byte(cinfo, index); for(int i=1; i<=16; i++) emit_byte(cinfo, htbl.bits[i]); for(int i=0; i<length; i++) emit_byte(cinfo, htbl.huffval[i]); htbl.sent_table=true; } }
/// <summary> /// Finish up a statistics-gathering pass and create the new Huffman tables. /// </summary> private void finish_pass_gather_phuff() { /* Flush out buffered data (all we care about is counting the EOB symbol) */ emit_eobrun(); /* It's important not to apply jpeg_gen_optimal_table more than once * per table, because it clobbers the input frequency counts! */ bool[] did = new bool [JpegConstants.NUM_HUFF_TBLS]; bool is_DC_band = (m_cinfo.m_Ss == 0); for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++) { jpeg_component_info componentInfo = m_cinfo.Component_info[m_cinfo.m_cur_comp_info[ci]]; int tbl = componentInfo.Ac_tbl_no; if (is_DC_band) { if (m_cinfo.m_Ah != 0) /* DC refinement needs no table */ { continue; } tbl = componentInfo.Dc_tbl_no; } if (!did[tbl]) { JHUFF_TBL htblptr = null; if (is_DC_band) { if (m_cinfo.m_dc_huff_tbl_ptrs[tbl] == null) { m_cinfo.m_dc_huff_tbl_ptrs[tbl] = new JHUFF_TBL(); } htblptr = m_cinfo.m_dc_huff_tbl_ptrs[tbl]; } else { if (m_cinfo.m_ac_huff_tbl_ptrs[tbl] == null) { m_cinfo.m_ac_huff_tbl_ptrs[tbl] = new JHUFF_TBL(); } htblptr = m_cinfo.m_ac_huff_tbl_ptrs[tbl]; } jpeg_gen_optimal_table(htblptr, m_count_ptrs[tbl]); did[tbl] = true; } } }
public static JHUFF_TBL jpeg_alloc_huff_table(jpeg_common cinfo) { JHUFF_TBL tbl = null; try { tbl = new JHUFF_TBL(); tbl.sent_table = false; // make sure this is false in any new table } catch { ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4); } return(tbl); }
/// <summary> /// Emit a DHT marker /// </summary> private void emit_dht(int index, bool is_ac) { JHUFF_TBL htbl = m_cinfo.m_dc_huff_tbl_ptrs[index]; if (is_ac) { htbl = m_cinfo.m_ac_huff_tbl_ptrs[index]; index += 0x10; /* output index has AC bit set */ } if (htbl == null) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, index); } if (!htbl.Sent_table) { emit_marker(JPEG_MARKER.DHT); int length = 0; for (int i = 1; i <= 16; i++) { length += htbl.Bits[i]; } emit_2bytes(length + 2 + 1 + 16); emit_byte(index); for (int i = 1; i <= 16; i++) { emit_byte(htbl.Bits[i]); } for (int i = 0; i < length; i++) { emit_byte(htbl.Huffval[i]); } htbl.Sent_table = true; } }
/// <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> /// Generate the best Huffman code table for the given counts, fill htbl. /// /// The JPEG standard requires that no symbol be assigned a codeword of all /// one bits (so that padding bits added at the end of a compressed segment /// can't look like a valid code). Because of the canonical ordering of /// codewords, this just means that there must be an unused slot in the /// longest codeword length category. Section K.2 of the JPEG spec suggests /// reserving such a slot by pretending that symbol 256 is a valid symbol /// with count 1. In theory that's not optimal; giving it count zero but /// including it in the symbol set anyway should give a better Huffman code. /// But the theoretically better code actually seems to come out worse in /// practice, because it produces more all-ones bytes (which incur stuffed /// zero bytes in the final file). In any case the difference is tiny. /// /// The JPEG standard requires Huffman codes to be no more than 16 bits long. /// If some symbols have a very small but nonzero probability, the Huffman tree /// must be adjusted to meet the code length restriction. We currently use /// the adjustment method suggested in JPEG section K.2. This method is *not* /// optimal; it may not choose the best possible limited-length code. But /// typically only very-low-frequency symbols will be given less-than-optimal /// lengths, so the code is almost optimal. Experimental comparisons against /// an optimal limited-length-code algorithm indicate that the difference is /// microscopic --- usually less than a hundredth of a percent of total size. /// So the extra complexity of an optimal algorithm doesn't seem worthwhile. /// </summary> protected void jpeg_gen_optimal_table(JHUFF_TBL htbl, long[] freq) { byte[] bits = new byte[MAX_CLEN + 1]; /* bits[k] = # of symbols with code length k */ int[] codesize = new int[257]; /* codesize[k] = code length of symbol k */ int[] others = new int[257]; /* next symbol in current branch of tree */ int c1, c2; int p, i, j; long v; /* This algorithm is explained in section K.2 of the JPEG standard */ for (i = 0; i < 257; i++) { others[i] = -1; /* init links to empty */ } freq[256] = 1; /* make sure 256 has a nonzero count */ /* Including the pseudo-symbol 256 in the Huffman procedure guarantees * that no real symbol is given code-value of all ones, because 256 * will be placed last in the largest codeword category. */ /* Huffman's basic algorithm to assign optimal code lengths to symbols */ for (;;) { /* Find the smallest nonzero frequency, set c1 = its symbol */ /* In case of ties, take the larger symbol number */ c1 = -1; v = 1000000000L; for (i = 0; i <= 256; i++) { if (freq[i] != 0 && freq[i] <= v) { v = freq[i]; c1 = i; } } /* Find the next smallest nonzero frequency, set c2 = its symbol */ /* In case of ties, take the larger symbol number */ c2 = -1; v = 1000000000L; for (i = 0; i <= 256; i++) { if (freq[i] != 0 && freq[i] <= v && i != c1) { v = freq[i]; c2 = i; } } /* Done if we've merged everything into one frequency */ if (c2 < 0) { break; } /* Else merge the two counts/trees */ freq[c1] += freq[c2]; freq[c2] = 0; /* Increment the codesize of everything in c1's tree branch */ codesize[c1]++; while (others[c1] >= 0) { c1 = others[c1]; codesize[c1]++; } others[c1] = c2; /* chain c2 onto c1's tree branch */ /* Increment the codesize of everything in c2's tree branch */ codesize[c2]++; while (others[c2] >= 0) { c2 = others[c2]; codesize[c2]++; } } /* Now count the number of symbols of each code length */ for (i = 0; i <= 256; i++) { if (codesize[i] != 0) { /* The JPEG standard seems to think that this can't happen, */ /* but I'm paranoid... */ if (codesize[i] > MAX_CLEN) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_HUFF_CLEN_OVERFLOW); } bits[codesize[i]]++; } } /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure * Huffman procedure assigned any such lengths, we must adjust the coding. * Here is what the JPEG spec says about how this next bit works: * Since symbols are paired for the longest Huffman code, the symbols are * removed from this length category two at a time. The prefix for the pair * (which is one bit shorter) is allocated to one of the pair; then, * skipping the BITS entry for that prefix length, a code word from the next * shortest nonzero BITS entry is converted into a prefix for two code words * one bit longer. */ for (i = MAX_CLEN; i > 16; i--) { while (bits[i] > 0) { j = i - 2; /* find length of new prefix to be used */ while (bits[j] == 0) { j--; } bits[i] -= 2; /* remove two symbols */ bits[i - 1]++; /* one goes in this length */ bits[j + 1] += 2; /* two new symbols in this length */ bits[j]--; /* symbol of this length is now a prefix */ } } /* Remove the count for the pseudo-symbol 256 from the largest codelength */ while (bits[i] == 0) /* find largest codelength still in use */ { i--; } bits[i]--; /* Return final symbol counts (only for lengths 0..16) */ Buffer.BlockCopy(bits, 0, htbl.Bits, 0, htbl.Bits.Length); /* Return a list of the symbols sorted by code length */ /* It's not real clear to me why we don't need to consider the codelength * changes made above, but the JPEG spec seems to think this works. */ p = 0; for (i = 1; i <= MAX_CLEN; i++) { for (j = 0; j <= 255; j++) { if (codesize[j] == i) { htbl.Huffval[p] = (byte)j; p++; } } } /* Set sent_table false so updated table will be written to JPEG file. */ htbl.Sent_table = false; }
/// <summary> /// Generate the best Huffman code table for the given counts, fill htbl. /// /// The JPEG standard requires that no symbol be assigned a codeword of all /// one bits (so that padding bits added at the end of a compressed segment /// can't look like a valid code). Because of the canonical ordering of /// codewords, this just means that there must be an unused slot in the /// longest codeword length category. Section K.2 of the JPEG spec suggests /// reserving such a slot by pretending that symbol 256 is a valid symbol /// with count 1. In theory that's not optimal; giving it count zero but /// including it in the symbol set anyway should give a better Huffman code. /// But the theoretically better code actually seems to come out worse in /// practice, because it produces more all-ones bytes (which incur stuffed /// zero bytes in the final file). In any case the difference is tiny. /// /// The JPEG standard requires Huffman codes to be no more than 16 bits long. /// If some symbols have a very small but nonzero probability, the Huffman tree /// must be adjusted to meet the code length restriction. We currently use /// the adjustment method suggested in JPEG section K.2. This method is *not* /// optimal; it may not choose the best possible limited-length code. But /// typically only very-low-frequency symbols will be given less-than-optimal /// lengths, so the code is almost optimal. Experimental comparisons against /// an optimal limited-length-code algorithm indicate that the difference is /// microscopic --- usually less than a hundredth of a percent of total size. /// So the extra complexity of an optimal algorithm doesn't seem worthwhile. /// </summary> protected void jpeg_gen_optimal_table(JHUFF_TBL htbl, long[] freq) { byte[] bits = new byte[MAX_CLEN + 1]; /* bits[k] = # of symbols with code length k */ int[] codesize = new int[257]; /* codesize[k] = code length of symbol k */ int[] others = new int[257]; /* next symbol in current branch of tree */ int c1, c2; int p, i, j; long v; /* This algorithm is explained in section K.2 of the JPEG standard */ for (i = 0; i < 257; i++) others[i] = -1; /* init links to empty */ freq[256] = 1; /* make sure 256 has a nonzero count */ /* Including the pseudo-symbol 256 in the Huffman procedure guarantees * that no real symbol is given code-value of all ones, because 256 * will be placed last in the largest codeword category. */ /* Huffman's basic algorithm to assign optimal code lengths to symbols */ for (;;) { /* Find the smallest nonzero frequency, set c1 = its symbol */ /* In case of ties, take the larger symbol number */ c1 = -1; v = 1000000000L; for (i = 0; i <= 256; i++) { if (freq[i] != 0 && freq[i] <= v) { v = freq[i]; c1 = i; } } /* Find the next smallest nonzero frequency, set c2 = its symbol */ /* In case of ties, take the larger symbol number */ c2 = -1; v = 1000000000L; for (i = 0; i <= 256; i++) { if (freq[i] != 0 && freq[i] <= v && i != c1) { v = freq[i]; c2 = i; } } /* Done if we've merged everything into one frequency */ if (c2 < 0) break; /* Else merge the two counts/trees */ freq[c1] += freq[c2]; freq[c2] = 0; /* Increment the codesize of everything in c1's tree branch */ codesize[c1]++; while (others[c1] >= 0) { c1 = others[c1]; codesize[c1]++; } others[c1] = c2; /* chain c2 onto c1's tree branch */ /* Increment the codesize of everything in c2's tree branch */ codesize[c2]++; while (others[c2] >= 0) { c2 = others[c2]; codesize[c2]++; } } /* Now count the number of symbols of each code length */ for (i = 0; i <= 256; i++) { if (codesize[i] != 0) { /* The JPEG standard seems to think that this can't happen, */ /* but I'm paranoid... */ if (codesize[i] > MAX_CLEN) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_HUFF_CLEN_OVERFLOW); bits[codesize[i]]++; } } /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure * Huffman procedure assigned any such lengths, we must adjust the coding. * Here is what the JPEG spec says about how this next bit works: * Since symbols are paired for the longest Huffman code, the symbols are * removed from this length category two at a time. The prefix for the pair * (which is one bit shorter) is allocated to one of the pair; then, * skipping the BITS entry for that prefix length, a code word from the next * shortest nonzero BITS entry is converted into a prefix for two code words * one bit longer. */ for (i = MAX_CLEN; i > 16; i--) { while (bits[i] > 0) { j = i - 2; /* find length of new prefix to be used */ while (bits[j] == 0) j--; bits[i] -= 2; /* remove two symbols */ bits[i - 1]++; /* one goes in this length */ bits[j + 1] += 2; /* two new symbols in this length */ bits[j]--; /* symbol of this length is now a prefix */ } } /* Remove the count for the pseudo-symbol 256 from the largest codelength */ while (bits[i] == 0) /* find largest codelength still in use */ i--; bits[i]--; /* Return final symbol counts (only for lengths 0..16) */ Buffer.BlockCopy(bits, 0, htbl.Bits, 0, htbl.Bits.Length); /* Return a list of the symbols sorted by code length */ /* It's not real clear to me why we don't need to consider the codelength * changes made above, but the JPEG spec seems to think this works. */ p = 0; for (i = 1; i <= MAX_CLEN; i++) { for (j = 0; j <= 255; j++) { if (codesize[j] == i) { htbl.Huffval[p] = (byte) j; p++; } } } /* Set sent_table false so updated table will be written to JPEG file. */ htbl.Sent_table = false; }
/// <summary> /// Process a DHT marker /// </summary> private bool get_dht() { int length; if (!m_cinfo.m_src.GetTwoBytes(out length)) { return(false); } length -= 2; byte[] bits = new byte[17]; byte[] huffval = new byte[256]; while (length > 16) { int index; if (!m_cinfo.m_src.GetByte(out index)) { return(false); } m_cinfo.TRACEMS(1, J_MESSAGE_CODE.JTRC_DHT, index); bits[0] = 0; int count = 0; for (int i = 1; i <= 16; i++) { int temp = 0; if (!m_cinfo.m_src.GetByte(out temp)) { return(false); } bits[i] = (byte)temp; count += bits[i]; } length -= 1 + 16; m_cinfo.TRACEMS(2, J_MESSAGE_CODE.JTRC_HUFFBITS, bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7], bits[8]); m_cinfo.TRACEMS(2, J_MESSAGE_CODE.JTRC_HUFFBITS, bits[9], bits[10], bits[11], bits[12], bits[13], bits[14], bits[15], bits[16]); /* Here we just do minimal validation of the counts to avoid walking * off the end of our table space. huff_entropy_decoder will check more carefully. */ if (count > 256 || count > length) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } for (int i = 0; i < count; i++) { int temp = 0; if (!m_cinfo.m_src.GetByte(out temp)) { return(false); } huffval[i] = (byte)temp; } length -= count; JHUFF_TBL htblptr = null; if ((index & 0x10) != 0) { /* AC table definition */ index -= 0x10; if (m_cinfo.m_ac_huff_tbl_ptrs[index] == null) { m_cinfo.m_ac_huff_tbl_ptrs[index] = new JHUFF_TBL(); } htblptr = m_cinfo.m_ac_huff_tbl_ptrs[index]; } else { /* DC table definition */ if (m_cinfo.m_dc_huff_tbl_ptrs[index] == null) { m_cinfo.m_dc_huff_tbl_ptrs[index] = new JHUFF_TBL(); } htblptr = m_cinfo.m_dc_huff_tbl_ptrs[index]; } if (index < 0 || index >= JpegConstants.NUM_HUFF_TBLS) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_DHT_INDEX, index); } Buffer.BlockCopy(bits, 0, htblptr.Bits, 0, htblptr.Bits.Length); Buffer.BlockCopy(huffval, 0, htblptr.Huffval, 0, htblptr.Huffval.Length); } if (length != 0) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_LENGTH); } 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); } } } }
// 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_d_derived_tbl(jpeg_decompress cinfo, bool isDC, int tblno, ref d_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 d_derived_tbl(); } catch { ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4); } } d_derived_tbl dtbl = pdtbl; dtbl.pub = htbl; // fill in back link // 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 = (int)htbl.bits[l]; if (i < 0 || p + i > 256) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); // protect against table overrun } while ((i--) != 0) { huffsize[p++] = l; } } huffsize[p] = 0; int numsymbols = 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 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] = (int)p - (int)huffcode[p]; p += htbl.bits[l]; dtbl.maxcode[l] = (int)huffcode[p - 1]; // maximum code of length l } else { dtbl.maxcode[l] = -1; // -1 if no codes of this length } } 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. for (int i = 0; i < dtbl.look_nbits.Length; i++) { dtbl.look_nbits[i] = 0; } p = 0; for (int l = 1; l <= HUFF_LOOKAHEAD; l++) { for (int i = 1; i <= (int)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 = ((int)huffcode[p]) << (HUFF_LOOKAHEAD - l); for (int ctr = 1 << (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..16. // (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 > 16) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } } } }