Jump-lookup for Huffman coding

speeds up those codes that are not part of the main lookup.
This gives a 10 % speedup for a photographic image.

Change-Id: Ief54b0ad77db790a01314402ad351b40ac9a7be4
This commit is contained in:
Jyrki Alakuijala 2013-06-27 08:58:56 +02:00 committed by skal
parent c34307abda
commit 699d80ea6b
3 changed files with 16 additions and 2 deletions

View File

@ -165,6 +165,10 @@ static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree,
VP8LSetBitPos(br, bitpos + lut_bits);
return tree->lut_symbol_[lut_ix];
}
node += tree->lut_jump_[lut_ix];
bitpos += HUFF_LUT_BITS;
bits >>= HUFF_LUT_BITS;
// Decode the value from a binary tree.
assert(node != NULL);
while (HuffmanTreeNodeIsNotLeaf(node)) {

View File

@ -63,6 +63,7 @@ static int TreeInit(HuffmanTree* const tree, int num_leaves) {
TreeNodeInit(tree->root_); // Initialize root.
tree->num_nodes_ = 1;
memset(tree->lut_bits_, 255, sizeof(tree->lut_bits_));
memset(tree->lut_jump_, 0, sizeof(tree->lut_jump_));
return 1;
}
@ -154,16 +155,21 @@ static int ReverseBitsShort(int bits, int num_bits) {
static int TreeAddSymbol(HuffmanTree* const tree,
int symbol, int code, int code_length) {
int step = HUFF_LUT_BITS;
int base_code;
HuffmanTreeNode* node = tree->root_;
const HuffmanTreeNode* const max_node = tree->root_ + tree->max_nodes_;
if (code_length <= HUFF_LUT_BITS) {
const int base_code = ReverseBitsShort(code, code_length);
int i;
base_code = ReverseBitsShort(code, code_length);
for (i = 0; i < (1 << (HUFF_LUT_BITS - code_length)); ++i) {
const int idx = base_code | (i << code_length);
tree->lut_symbol_[idx] = symbol;
tree->lut_bits_[idx] = code_length;
}
} else {
base_code = ReverseBitsShort((code >> (code_length - HUFF_LUT_BITS)),
HUFF_LUT_BITS);
}
while (code_length-- > 0) {
if (node >= max_node) {
@ -176,6 +182,9 @@ static int TreeAddSymbol(HuffmanTree* const tree,
return 0; // leaf is already occupied.
}
node += node->children_ + ((code >> code_length) & 1);
if (--step == 0) {
tree->lut_jump_[base_code] = node - tree->root_;
}
}
if (NodeIsEmpty(node)) {
node->children_ = 0; // turn newly created node into a leaf.

View File

@ -34,7 +34,8 @@ typedef struct HuffmanTree HuffmanTree;
struct HuffmanTree {
// Fast lookup for short bit lengths.
uint8_t lut_bits_[HUFF_LUT];
int lut_symbol_[HUFF_LUT];
int16_t lut_symbol_[HUFF_LUT];
int16_t lut_jump_[HUFF_LUT];
// Complete tree for lookups.
HuffmanTreeNode* root_; // all the nodes, starting at root.
int max_nodes_; // max number of nodes