mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
Speedup for decoding lossless WebP photographs:
use bit_pos instead num_bit to update the bit-reader 37.69 MB/s -> 39.79 MB/s, 5.6 % Change-Id: Ica476cc3e2fc2db084d6961bea8586b050bb221d
This commit is contained in:
parent
24ee098a00
commit
313d853fa9
@ -156,15 +156,15 @@ static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
|
||||
static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree,
|
||||
VP8LBitReader* const br) {
|
||||
const HuffmanTreeNode* node = tree->root_;
|
||||
int num_bits = 0;
|
||||
uint32_t bits = VP8LPrefetchBits(br);
|
||||
int bitpos = br->bit_pos_;
|
||||
assert(node != NULL);
|
||||
while (!HuffmanTreeNodeIsLeaf(node)) {
|
||||
while (HuffmanTreeNodeIsNotLeaf(node)) {
|
||||
node = HuffmanTreeNextNode(node, bits & 1);
|
||||
bits >>= 1;
|
||||
++num_bits;
|
||||
++bitpos;
|
||||
}
|
||||
VP8LDiscardBits(br, num_bits);
|
||||
VP8LSetBitPos(br, bitpos);
|
||||
return node->symbol_;
|
||||
}
|
||||
|
||||
|
@ -316,9 +316,10 @@ static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
|
||||
return (uint32_t)(br->val_ >> br->bit_pos_);
|
||||
}
|
||||
|
||||
// Discard 'num_bits' bits from the cache.
|
||||
static WEBP_INLINE void VP8LDiscardBits(VP8LBitReader* const br, int num_bits) {
|
||||
br->bit_pos_ += num_bits;
|
||||
// For jumping over a number of bits in the bit stream when accessed with
|
||||
// VP8LPrefetchBits and VP8LFillBitWindow.
|
||||
static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {
|
||||
br->bit_pos_ = val;
|
||||
}
|
||||
|
||||
// Advances the Read buffer by 4 bytes to make room for reading next 32 bits.
|
||||
|
@ -128,14 +128,14 @@ static int TreeAddSymbol(HuffmanTree* const tree,
|
||||
if (NodeIsEmpty(node)) {
|
||||
if (IsFull(tree)) return 0; // error: too many symbols.
|
||||
AssignChildren(tree, node);
|
||||
} else if (HuffmanTreeNodeIsLeaf(node)) {
|
||||
} else if (!HuffmanTreeNodeIsNotLeaf(node)) {
|
||||
return 0; // leaf is already occupied.
|
||||
}
|
||||
node += node->children_ + ((code >> code_length) & 1);
|
||||
}
|
||||
if (NodeIsEmpty(node)) {
|
||||
node->children_ = 0; // turn newly created node into a leaf.
|
||||
} else if (!HuffmanTreeNodeIsLeaf(node)) {
|
||||
} else if (HuffmanTreeNodeIsNotLeaf(node)) {
|
||||
return 0; // trying to assign a symbol to already used code.
|
||||
}
|
||||
node->symbol_ = symbol; // Add symbol in this node.
|
||||
|
@ -35,10 +35,10 @@ struct HuffmanTree {
|
||||
int num_nodes_; // number of currently occupied nodes
|
||||
};
|
||||
|
||||
// Returns true if the given node is a leaf of the Huffman tree.
|
||||
static WEBP_INLINE int HuffmanTreeNodeIsLeaf(
|
||||
// Returns true if the given node is not a leaf of the Huffman tree.
|
||||
static WEBP_INLINE int HuffmanTreeNodeIsNotLeaf(
|
||||
const HuffmanTreeNode* const node) {
|
||||
return (node->children_ == 0);
|
||||
return node->children_;
|
||||
}
|
||||
|
||||
// Go down one level. Most critical function. 'right_child' must be 0 or 1.
|
||||
|
Loading…
Reference in New Issue
Block a user