mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
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:
parent
c34307abda
commit
699d80ea6b
@ -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)) {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user