|
Packit |
700f92 |
/* This file is part of libmspack.
|
|
Packit |
700f92 |
* (C) 2003-2010 Stuart Caie.
|
|
Packit |
700f92 |
*
|
|
Packit |
700f92 |
* libmspack is free software; you can redistribute it and/or modify it under
|
|
Packit |
700f92 |
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
|
Packit |
700f92 |
*
|
|
Packit |
700f92 |
* For further details, see the file COPYING.LIB distributed with libmspack
|
|
Packit |
700f92 |
*/
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
#ifndef MSPACK_READHUFF_H
|
|
Packit |
700f92 |
#define MSPACK_READHUFF_H 1
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* This implements a fast Huffman tree decoding system.
|
|
Packit |
700f92 |
*/
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
#if !(defined(BITS_ORDER_MSB) || defined(BITS_ORDER_LSB))
|
|
Packit |
700f92 |
# error "readhuff.h is used in conjunction with readbits.h, include that first"
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
#if !(defined(TABLEBITS) && defined(MAXSYMBOLS))
|
|
Packit |
700f92 |
# error "define TABLEBITS(tbl) and MAXSYMBOLS(tbl) before using readhuff.h"
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
#if !(defined(HUFF_TABLE) && defined(HUFF_LEN))
|
|
Packit |
700f92 |
# error "define HUFF_TABLE(tbl) and HUFF_LEN(tbl) before using readhuff.h"
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
#ifndef HUFF_ERROR
|
|
Packit |
700f92 |
# error "define HUFF_ERROR before using readhuff.h"
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
#ifndef HUFF_MAXBITS
|
|
Packit |
700f92 |
# define HUFF_MAXBITS 16
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* Decodes the next huffman symbol from the input bitstream into var.
|
|
Packit |
700f92 |
* Do not use this macro on a table unless build_decode_table() succeeded.
|
|
Packit |
700f92 |
*/
|
|
Packit |
700f92 |
#define READ_HUFFSYM(tbl, var) do { \
|
|
Packit |
700f92 |
ENSURE_BITS(HUFF_MAXBITS); \
|
|
Packit |
700f92 |
sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl))); \
|
|
Packit |
700f92 |
if (sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl); \
|
|
Packit |
700f92 |
(var) = sym; \
|
|
Packit |
700f92 |
i = HUFF_LEN(tbl, sym); \
|
|
Packit |
700f92 |
REMOVE_BITS(i); \
|
|
Packit |
700f92 |
} while (0)
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
#ifdef BITS_ORDER_LSB
|
|
Packit |
700f92 |
# define HUFF_TRAVERSE(tbl) do { \
|
|
Packit |
700f92 |
i = TABLEBITS(tbl) - 1; \
|
|
Packit |
700f92 |
do { \
|
|
Packit |
700f92 |
if (i++ > HUFF_MAXBITS) HUFF_ERROR; \
|
|
Packit |
700f92 |
sym = HUFF_TABLE(tbl, \
|
|
Packit |
700f92 |
(sym << 1) | ((bit_buffer >> i) & 1)); \
|
|
Packit |
700f92 |
} while (sym >= MAXSYMBOLS(tbl)); \
|
|
Packit |
700f92 |
} while (0)
|
|
Packit |
700f92 |
#else
|
|
Packit |
700f92 |
#define HUFF_TRAVERSE(tbl) do { \
|
|
Packit |
700f92 |
i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl)); \
|
|
Packit |
700f92 |
do { \
|
|
Packit |
700f92 |
if ((i >>= 1) == 0) HUFF_ERROR; \
|
|
Packit |
700f92 |
sym = HUFF_TABLE(tbl, \
|
|
Packit |
700f92 |
(sym << 1) | ((bit_buffer & i) ? 1 : 0)); \
|
|
Packit |
700f92 |
} while (sym >= MAXSYMBOLS(tbl)); \
|
|
Packit |
700f92 |
} while (0)
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* make_decode_table(nsyms, nbits, length[], table[])
|
|
Packit |
700f92 |
*
|
|
Packit |
700f92 |
* This function was originally coded by David Tritscher.
|
|
Packit |
700f92 |
* It builds a fast huffman decoding table from
|
|
Packit |
700f92 |
* a canonical huffman code lengths table.
|
|
Packit |
700f92 |
*
|
|
Packit |
700f92 |
* nsyms = total number of symbols in this huffman tree.
|
|
Packit |
700f92 |
* nbits = any symbols with a code length of nbits or less can be decoded
|
|
Packit |
700f92 |
* in one lookup of the table.
|
|
Packit |
700f92 |
* length = A table to get code lengths from [0 to nsyms-1]
|
|
Packit |
700f92 |
* table = The table to fill up with decoded symbols and pointers.
|
|
Packit |
700f92 |
* Should be ((1<
|
|
Packit |
700f92 |
*
|
|
Packit |
700f92 |
* Returns 0 for OK or 1 for error
|
|
Packit |
700f92 |
*/
|
|
Packit |
700f92 |
static int make_decode_table(unsigned int nsyms, unsigned int nbits,
|
|
Packit |
700f92 |
unsigned char *length, unsigned short *table)
|
|
Packit |
700f92 |
{
|
|
Packit |
700f92 |
register unsigned short sym, next_symbol;
|
|
Packit |
700f92 |
register unsigned int leaf, fill;
|
|
Packit |
700f92 |
#ifdef BITS_ORDER_LSB
|
|
Packit |
700f92 |
register unsigned int reverse;
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
register unsigned char bit_num;
|
|
Packit |
700f92 |
unsigned int pos = 0; /* the current position in the decode table */
|
|
Packit |
700f92 |
unsigned int table_mask = 1 << nbits;
|
|
Packit |
700f92 |
unsigned int bit_mask = table_mask >> 1; /* don't do 0 length codes */
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* fill entries for codes short enough for a direct mapping */
|
|
Packit |
700f92 |
for (bit_num = 1; bit_num <= nbits; bit_num++) {
|
|
Packit |
700f92 |
for (sym = 0; sym < nsyms; sym++) {
|
|
Packit |
700f92 |
if (length[sym] != bit_num) continue;
|
|
Packit |
700f92 |
#ifdef BITS_ORDER_MSB
|
|
Packit |
700f92 |
leaf = pos;
|
|
Packit |
700f92 |
#else
|
|
Packit |
700f92 |
/* reverse the significant bits */
|
|
Packit |
700f92 |
fill = length[sym]; reverse = pos >> (nbits - fill); leaf = 0;
|
|
Packit |
700f92 |
do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
if((pos += bit_mask) > table_mask) return 1; /* table overrun */
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* fill all possible lookups of this symbol with the symbol itself */
|
|
Packit |
700f92 |
#ifdef BITS_ORDER_MSB
|
|
Packit |
700f92 |
for (fill = bit_mask; fill-- > 0;) table[leaf++] = sym;
|
|
Packit |
700f92 |
#else
|
|
Packit |
700f92 |
fill = bit_mask; next_symbol = 1 << bit_num;
|
|
Packit |
700f92 |
do { table[leaf] = sym; leaf += next_symbol; } while (--fill);
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
bit_mask >>= 1;
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* exit with success if table is now complete */
|
|
Packit |
700f92 |
if (pos == table_mask) return 0;
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* mark all remaining table entries as unused */
|
|
Packit |
700f92 |
for (sym = pos; sym < table_mask; sym++) {
|
|
Packit |
700f92 |
#ifdef BITS_ORDER_MSB
|
|
Packit |
700f92 |
table[sym] = 0xFFFF;
|
|
Packit |
700f92 |
#else
|
|
Packit |
700f92 |
reverse = sym; leaf = 0; fill = nbits;
|
|
Packit |
700f92 |
do { leaf <<= 1; leaf |= reverse & 1; reverse >>= 1; } while (--fill);
|
|
Packit |
700f92 |
table[leaf] = 0xFFFF;
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* next_symbol = base of allocation for long codes */
|
|
Packit |
700f92 |
next_symbol = ((table_mask >> 1) < nsyms) ? nsyms : (table_mask >> 1);
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* give ourselves room for codes to grow by up to 16 more bits.
|
|
Packit |
700f92 |
* codes now start at bit nbits+16 and end at (nbits+16-codelength) */
|
|
Packit |
700f92 |
pos <<= 16;
|
|
Packit |
700f92 |
table_mask <<= 16;
|
|
Packit |
700f92 |
bit_mask = 1 << 15;
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
for (bit_num = nbits+1; bit_num <= HUFF_MAXBITS; bit_num++) {
|
|
Packit |
700f92 |
for (sym = 0; sym < nsyms; sym++) {
|
|
Packit |
700f92 |
if (length[sym] != bit_num) continue;
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
#ifdef BITS_ORDER_MSB
|
|
Packit |
700f92 |
leaf = pos >> 16;
|
|
Packit |
700f92 |
#else
|
|
Packit |
700f92 |
/* leaf = the first nbits of the code, reversed */
|
|
Packit |
700f92 |
reverse = pos >> 16; leaf = 0; fill = nbits;
|
|
Packit |
700f92 |
do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
|
|
Packit |
700f92 |
#endif
|
|
Packit |
700f92 |
for (fill = 0; fill < (bit_num - nbits); fill++) {
|
|
Packit |
700f92 |
/* if this path hasn't been taken yet, 'allocate' two entries */
|
|
Packit |
700f92 |
if (table[leaf] == 0xFFFF) {
|
|
Packit |
700f92 |
table[(next_symbol << 1) ] = 0xFFFF;
|
|
Packit |
700f92 |
table[(next_symbol << 1) + 1 ] = 0xFFFF;
|
|
Packit |
700f92 |
table[leaf] = next_symbol++;
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* follow the path and select either left or right for next bit */
|
|
Packit |
700f92 |
leaf = table[leaf] << 1;
|
|
Packit |
700f92 |
if ((pos >> (15-fill)) & 1) leaf++;
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
table[leaf] = sym;
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
bit_mask >>= 1;
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
|
|
Packit |
700f92 |
/* full table? */
|
|
Packit |
700f92 |
return (pos == table_mask) ? 0 : 1;
|
|
Packit |
700f92 |
}
|
|
Packit |
700f92 |
#endif
|