mirror of
https://github.com/aaronsgiles/JPEGView.git
synced 2024-06-01 03:41:27 +00:00
1 line
20 KiB
C
1 line
20 KiB
C
|
/*
* jdhuff.c
*
* Copyright (C) 1991-1994, 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.
*
* Much of the complexity here has to do with supporting input suspension.
* If the data source module demands suspension, we want to be able to back
* up to the start of the current MCU. To do this, we copy state variables
* into local working storage, and update them back to the permanent JPEG
* objects only upon successful completion of an MCU.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Expanded entropy decoder object for Huffman decoding.
*
* The savable_state subrecord contains fields that change within an MCU,
* but must not be updated permanently until we complete the MCU.
*/
typedef struct {
INT32 get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state;
typedef struct {
struct jpeg_entropy_decoder pub; /* public fields */
savable_state saved; /* Bit buffer & DC state at start of MCU */
/* These fields are NOT loaded into local working state. */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
boolean printed_eod; /* flag to suppress extra end-of-data msgs */
} huff_entropy_decoder;
typedef huff_entropy_decoder * huff_entropy_ptr;
/* Working state while scanning an MCU.
* This struct contains all the fields that are needed by subroutines.
*/
typedef struct {
int unread_marker; /* nonzero if we have hit a marker */
const JOCTET * next_input_byte; /* => next byte to read from source */
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
savable_state cur; /* Current bit buffer & DC state */
j_decompress_ptr cinfo; /* fill_bit_buffer needs access to this */
} working_state;
/* Forward declarations */
LOCAL void fix_huff_tbl JPP((JDHUFF_TBL * htbl));
/*
* Initialize for a Huffman-compressed scan.
*/
METHODDEF void
start_pass (j_decompress_ptr cinfo)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci, dctbl, actbl;
jpeg_component_info * compptr;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no;
actbl = compptr->ac_tbl_no;
/* Make sure requested tables are present */
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
cinfo->dc_huff_tbl_ptrs[dctbl] == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
if (actbl < 0 || actbl >= NUM_HUFF_TBLS ||
cinfo->ac_huff_tbl_ptrs[actbl] == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
/* 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((JDHUFF_TBL *) cinfo->dc_huff_tbl_ptrs[dctbl]);
fix_huff_tbl((JDHUFF_TBL *) cinfo->ac_huff_tbl_ptrs[actbl]);
/* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0;
}
/* Initialize private state variables */
entropy->saved.bits_left = 0;
entropy->printed_eod = FALSE;
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
LOCAL void
fix_huff_tbl (JDHUFF_TBL * htbl)
/* Compute the derived values for a Huffman table */
{
int p, i, l, si;
int lookbits, ctr;
char huffsize[257];
unsigned int huffcode[257];
unsigned int 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->pub.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
|