mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +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,
|
static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree,
|
||||||
VP8LBitReader* const br) {
|
VP8LBitReader* const br) {
|
||||||
const HuffmanTreeNode* node = tree->root_;
|
const HuffmanTreeNode* node = tree->root_;
|
||||||
int num_bits = 0;
|
|
||||||
uint32_t bits = VP8LPrefetchBits(br);
|
uint32_t bits = VP8LPrefetchBits(br);
|
||||||
|
int bitpos = br->bit_pos_;
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
while (!HuffmanTreeNodeIsLeaf(node)) {
|
while (HuffmanTreeNodeIsNotLeaf(node)) {
|
||||||
node = HuffmanTreeNextNode(node, bits & 1);
|
node = HuffmanTreeNextNode(node, bits & 1);
|
||||||
bits >>= 1;
|
bits >>= 1;
|
||||||
++num_bits;
|
++bitpos;
|
||||||
}
|
}
|
||||||
VP8LDiscardBits(br, num_bits);
|
VP8LSetBitPos(br, bitpos);
|
||||||
return node->symbol_;
|
return node->symbol_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,9 +316,10 @@ static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
|
|||||||
return (uint32_t)(br->val_ >> br->bit_pos_);
|
return (uint32_t)(br->val_ >> br->bit_pos_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard 'num_bits' bits from the cache.
|
// For jumping over a number of bits in the bit stream when accessed with
|
||||||
static WEBP_INLINE void VP8LDiscardBits(VP8LBitReader* const br, int num_bits) {
|
// VP8LPrefetchBits and VP8LFillBitWindow.
|
||||||
br->bit_pos_ += num_bits;
|
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.
|
// 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 (NodeIsEmpty(node)) {
|
||||||
if (IsFull(tree)) return 0; // error: too many symbols.
|
if (IsFull(tree)) return 0; // error: too many symbols.
|
||||||
AssignChildren(tree, node);
|
AssignChildren(tree, node);
|
||||||
} else if (HuffmanTreeNodeIsLeaf(node)) {
|
} else if (!HuffmanTreeNodeIsNotLeaf(node)) {
|
||||||
return 0; // leaf is already occupied.
|
return 0; // leaf is already occupied.
|
||||||
}
|
}
|
||||||
node += node->children_ + ((code >> code_length) & 1);
|
node += node->children_ + ((code >> code_length) & 1);
|
||||||
}
|
}
|
||||||
if (NodeIsEmpty(node)) {
|
if (NodeIsEmpty(node)) {
|
||||||
node->children_ = 0; // turn newly created node into a leaf.
|
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.
|
return 0; // trying to assign a symbol to already used code.
|
||||||
}
|
}
|
||||||
node->symbol_ = symbol; // Add symbol in this node.
|
node->symbol_ = symbol; // Add symbol in this node.
|
||||||
|
@ -35,10 +35,10 @@ struct HuffmanTree {
|
|||||||
int num_nodes_; // number of currently occupied nodes
|
int num_nodes_; // number of currently occupied nodes
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns true if the given node is a leaf of the Huffman tree.
|
// Returns true if the given node is not a leaf of the Huffman tree.
|
||||||
static WEBP_INLINE int HuffmanTreeNodeIsLeaf(
|
static WEBP_INLINE int HuffmanTreeNodeIsNotLeaf(
|
||||||
const HuffmanTreeNode* const node) {
|
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.
|
// Go down one level. Most critical function. 'right_child' must be 0 or 1.
|
||||||
|
Loading…
Reference in New Issue
Block a user