📄 jchuff.c
字号:
/*This programme is reedited from IJG code by Fujian Shi(fieagle@yahoo.com.cn)
* jchuff.c
* This file contains Huffman entropy encoding routines.
*
*
*/
#include "commondecls.h" /* Declarations shared with jcphuff.c */
/*
* Compute the derived values for a Huffman table.
* This routine also performs some validation checks on the table.
*
* Note this is also used by jcphuff.c.
*/
void
jpeg_make_c_derived_tbl (j_compress_ptr cinfo, int isDC,
c_derived_tbl ** pdtbl)
{
JHUFF_TBL *htbl;
c_derived_tbl *dtbl;
int p, i, l, lastp, si, maxsymbol;
char huffsize[257];
unsigned int huffcode[257];
unsigned int code;
/* 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 */
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs : cinfo->ac_huff_tbl_ptrs;
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (c_derived_tbl *)
alloc_one_row ( cinfo,SIZEOF(c_derived_tbl));
dtbl = *pdtbl;
/* Figure C.1: make table of Huffman code length for each symbol */
p = 0;
for (l = 1; l <= 16; l++) {
i = (int) htbl->bits[l];
if (i < 0 || p + i > 256) /* protect against table overrun */
exit(0);
while (i--)
huffsize[p++] = (char) l;
}
huffsize[p] = 0;
lastp = p;
/* Figure C.2: generate the codes themselves */
/* We also validate that the counts represent a legal Huffman code tree. */
code = 0;
si = huffsize[0];
p = 0;
while (huffsize[p]) {
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 (((INT32) code) >= (((INT32) 1) << si))
exit(0);
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.
*/
MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
/* 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.)
*/
maxsymbol = isDC ? 15 : 255;
for (p = 0; p < lastp; p++) {
i = htbl->huffval[p];
if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
exit(0);
dtbl->ehufco[i] = huffcode[p];
dtbl->ehufsi[i] = huffsize[p];
}
}
/* Outputting bits to the file */
/* Only the right 24 bits of put_buffer are used; the valid bits are
* left-justified in this part. At most 16 bits can be passed to emit_bits
* in one call, and we never retain more than 7 bits in put_buffer
* between calls, so 24 bits are sufficient.
*/
LOCAL(int)
emit_bits (j_compress_ptr cinfo, unsigned int code, int size)
/* Emit some bits; return 1 if successful, 0 if must suspend */
{
/* This routine is heavily used, so it's worth coding tightly. */
register INT32 put_buffer = (INT32) code;
register int put_bits = cinfo->saved.put_bits;
/* if size is 0, caller used an invalid Huffman table entry */
if (size == 0)
exit(0);
put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
put_bits += size; /* new number of bits in buffer */
put_buffer <<= 24 - put_bits; /* align incoming bits */
put_buffer |= cinfo->saved.put_buffer; /* and merge with old buffer contents */
while (put_bits >= 8) {
int c = (int) ((put_buffer >> 16) & 0xFF);
emit_byte(cinfo, c);
if (c == 0xFF) { /* need to stuff a zero byte? */
emit_byte(cinfo, 0);
}
put_buffer <<= 8;
put_bits -= 8;
}
cinfo->saved.put_buffer = put_buffer; /* update state variables */
cinfo->saved.put_bits = put_bits;
return 1;
}
void
flush_bits (j_compress_ptr cinfo)
{
if (! emit_bits(cinfo, 0x7F, 7)) /* fill any partial byte with ones */
exit(0);
}
/* Encode a single block's worth of coefficients */
void
encode_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl)
{
register int temp, temp2;
register int nbits;
register int k, r, i;
/* Encode the DC coefficient difference per section F.1.2.1 */
temp = temp2 = block[0] - last_dc_val;
cinfo->saved.last_dc_val=block[0];
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 */
nbits = 0;
while (temp) {
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 > 11)
exit(0);
/* Emit the Huffman-coded symbol for the number of bits */
if (! emit_bits(cinfo, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
exit(0);
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (nbits) /* emit_bits rejects calls with size 0 */
if (! emit_bits(cinfo, (unsigned int) temp2, nbits))
exit(0);
/* Encode the AC coefficients per section F.1.2.2 */
r = 0; /* r = run length of zeros */
for (k = 1; k < DCTSIZE2; k++) {
if ((temp = block[jpeg_natural_order[k]]) == 0) {
r++;
} else {
/* if run length > 15, must emit special run-length-16 codes (0xF0) */
while (r > 15) {
if (! emit_bits(cinfo, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
exit(0);
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))
nbits++;
/* Check for out-of-range coefficient values */
if (nbits > 10)
exit(0);
/* Emit Huffman symbol for run length / number of bits */
i = (r << 4) + nbits;
if (! emit_bits(cinfo, actbl->ehufco[i], actbl->ehufsi[i]))
exit(0);
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (! emit_bits(cinfo, (unsigned int) temp2, nbits))
exit(0);
r = 0;
}
}
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0)
if (! emit_bits(cinfo, actbl->ehufco[0], actbl->ehufsi[0]))
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -