/* * jdhuff.c * * Copyright (C) 1991, 1992, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains Huffman entropy decoding routines. * These routines are invoked via the methods entropy_decode * and entropy_decoder_init/term. */ #include "jinclude.h" /* Static variables to avoid passing 'round extra parameters */ static decompress_info_ptr dcinfo; static INT32 get_buffer; /* current bit-extraction buffer */ static int bits_left; /* # of unused bits in it */ LOCAL void fix_huff_tbl (HUFF_TBL * htbl) /* Compute derived values for a Huffman table */ { int p, i, l, si; char huffsize[257]; UINT16 huffcode[257]; UINT16 code; /* Figure C.1: make table of Huffman code length for each symbol */ /* Note that this is in code-length order. */ p = 0; for (l = 1; l <= 16; l++) { for (i = 1; i <= (int) htbl->bits[l]; i++) huffsize[p++] = (char) l; } huffsize[p] = 0; /* Figure C.2: generate the codes themselves */ /* Note that this is in code-length order. */ code = 0; si = huffsize[0]; p = 0; while (huffsize[p]) { while (((int) huffsize[p]) == si) { huffcode[p++] = code; code++; } code <<= 1; si++; } /* We don't bother to fill in the encoding tables ehufco[] and ehufsi[], */ /* since they are not used for decoding. */ /* Figure F.15: generate decoding tables */ p = 0; for (l = 1; l <= 16; l++) { if (htbl->bits[l]) { htbl->valptr[l] = p; /* huffval[] index of 1st sym of code len l */ htbl->mincode[l] = huffcode[p]; /* minimum code of length l */ p += htbl->bits[l]; htbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ } else { htbl->maxcode[l] = -1; } } htbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */ } /* Extract the next N bits from the input stream (N <= 15) */ LOCAL int get_bits (int nbits) { int result; while (nbits > bits_left) { int c = JGETC(dcinfo); get_buffer <<= 8; get_buffer |= c; bits_left += 8; /* If it's 0xFF, check and discard stuffed zero byte */ if (c == 0xff) { c = JGETC(dcinfo); /* Byte stuffing */ if (c != 0) ERREXIT1(dcinfo->emethods, "Unexpected marker 0x%02x in compressed data", c); } } bits_left -= nbits; result = ((int) (get_buffer >> bits_left)) & ((1 << nbits) - 1); return result; } /* Macro to make things go at some speed! */ #define get_bit() (bits_left ? \ ((int) (get_buffer >> (--bits_left))) & 1 : \ get_bits(1)) /* Figure F.16: extract next coded symbol from input stream */ LOCAL int huff_DECODE (HUFF_TBL * htbl) { int l, p; INT32 code; code = get_bit(); l = 1; while (code > htbl->maxcode[l]) { code = (code << 1) + get_bit(); l++; } /* With garbage input we may reach the sentinel value l = 17. */ if (l > 16) { ERREXIT(dcinfo->emethods, "Corrupted data in JPEG file"); } p = (int) (htbl->valptr[l] + (code - htbl->mincode[l])); return (int) htbl->huffval[p]; } /* Figure F.12: extend sign bit */ /* NB: on some compilers this will only work for s > 0 */ #define huff_EXTEND(x, s) ((x) < (1 << ((s)-1)) ? \ (x) + (-1 << (s)) + 1 : \ (x)) /* Decode a single block's worth of coefficients */ /* Note that only the difference is returned for the DC coefficient */ LOCAL void decode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl) { int s, k, r, n; /* zero out the coefficient block */ MEMZERO((void *) block, SIZEOF(JBLOCK)); /* Section F.2.2.1: decode the DC coefficient difference */ s = huff_DECODE(dctbl); if (s) { r = get_bits(s); s = huff_EXTEND(r, s); } block[0] = s; /* Section F.2.2.2: decode the AC coefficients */ for (k = 1; k < DCTSIZE2; k++) { r = huff_DECODE(actbl); s = r & 15; n = r >> 4; if (s) { k += n; r = get_bits(s); block[k] = huff_EXTEND(r, s); } else { if (n != 15) break; k += 15; } } } /* * Initialize for a Huffman-compressed scan. * This is invoked after reading the SOS marker. */ METHODDEF void huff_decoder_init (decompress_info_ptr cinfo) { short ci; jpeg_component_info * compptr; /* Initialize static variables */ dcinfo = cinfo; bits_left = 0; for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; /* Make sure requested tables are present */ if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL || cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL) ERREXIT(cinfo->emethods, "Use of undefined Huffman table"); /* Compute derived values for Huffman tables */ /* We may do this more than once for same table, but it's not a big deal */ fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]); fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]); /* Initialize DC predictions to 0 */ cinfo->last_dc_val[ci] = 0; } /* Initialize restart stuff */ cinfo->restarts_to_go = cinfo->restart_interval; cinfo->next_restart_num = 0; } /* * Check for a restart marker & resynchronize decoder. */ LOCAL void process_restart (decompress_info_ptr cinfo) { int c, nbytes; short ci; /* Throw away any partial unread byte */ bits_left = 0; /* Scan for next JPEG marker */ nbytes = 0; do { do { /* skip any non-FF bytes */ nbytes++; c = JGETC(cinfo); } while (c != 0xFF); do { /* skip any duplicate FFs */ nbytes++; c = JGETC(cinfo); } while (c == 0xFF); } while (c == 0); /* repeat if it was a stuffed FF/00 */ if (c != (RST0 + cinfo->next_restart_num)) ERREXIT2(cinfo->emethods, "Found 0x%02x marker instead of RST%d", c, cinfo->next_restart_num); if (nbytes != 2) TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before RST%d", nbytes-2, cinfo->next_restart_num); else TRACEMS1(cinfo->emethods, 2, "RST%d", cinfo->next_restart_num); /* Re-initialize DC predictions to 0 */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) cinfo->last_dc_val[ci] = 0; /* Update restart state */ cinfo->restarts_to_go = cinfo->restart_interval; cinfo->next_restart_num++; cinfo->next_restart_num &= 7; } /* * Decode and return one MCU's worth of Huffman-compressed coefficients. */ METHODDEF void huff_decode (decompress_info_ptr cinfo, JBLOCK *MCU_data) { short blkn, ci; jpeg_component_info * compptr; /* Account for restart interval, process restart marker if needed */ if (cinfo->restart_interval) { if (cinfo->restarts_to_go == 0) process_restart(cinfo); cinfo->restarts_to_go--; } for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { ci = cinfo->MCU_membership[blkn]; compptr = cinfo->cur_comp_info[ci]; decode_one_block(MCU_data[blkn], cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no], cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]); /* Convert DC difference to actual value, update last_dc_val */ MCU_data[blkn][0] += cinfo->last_dc_val[ci]; cinfo->last_dc_val[ci] = MCU_data[blkn][0]; } } /* * Finish up at the end of a Huffman-compressed scan. */ METHODDEF void huff_decoder_term (decompress_info_ptr cinfo) { /* No work needed */ } /* * The method selection routine for Huffman entropy decoding. */ GLOBAL void jseldhuffman (decompress_info_ptr cinfo) { if (! cinfo->arith_code) { cinfo->methods->entropy_decoder_init = huff_decoder_init; cinfo->methods->entropy_decode = huff_decode; cinfo->methods->entropy_decoder_term = huff_decoder_term; } }