Index: third_party/libwebp/dec/vp8l.c |
diff --git a/third_party/libwebp/dec/vp8l.c b/third_party/libwebp/dec/vp8l.c |
index 70edbeb67aa3fee5cdf7316742b9486814f0a2be..5659cb5d3f2d5d1d54ce2f8246cbaf7154fc89c3 100644 |
--- a/third_party/libwebp/dec/vp8l.c |
+++ b/third_party/libwebp/dec/vp8l.c |
@@ -149,31 +149,22 @@ static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) { |
//------------------------------------------------------------------------------ |
// Decodes the next Huffman code from bit-stream. |
// FillBitWindow(br) needs to be called at minimum every second call |
-// to ReadSymbolUnsafe. |
-static int ReadSymbolUnsafe(const HuffmanTree* tree, VP8LBitReader* const br) { |
+// to ReadSymbol, in order to pre-fetch enough bits. |
+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); |
assert(node != NULL); |
while (!HuffmanTreeNodeIsLeaf(node)) { |
- node = HuffmanTreeNextNode(node, VP8LReadOneBitUnsafe(br)); |
+ node = HuffmanTreeNextNode(node, bits & 1); |
+ bits >>= 1; |
+ ++num_bits; |
} |
+ VP8LDiscardBits(br, num_bits); |
return node->symbol_; |
} |
-static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, |
- VP8LBitReader* const br) { |
- const int read_safe = (br->pos_ + 8 > br->len_); |
- if (!read_safe) { |
- return ReadSymbolUnsafe(tree, br); |
- } else { |
- const HuffmanTreeNode* node = tree->root_; |
- assert(node != NULL); |
- while (!HuffmanTreeNodeIsLeaf(node)) { |
- node = HuffmanTreeNextNode(node, VP8LReadOneBit(br)); |
- } |
- return node->symbol_; |
- } |
-} |
- |
static int ReadHuffmanCodeLengths( |
VP8LDecoder* const dec, const int* const code_length_code_lengths, |
int num_symbols, int* const code_lengths) { |
@@ -327,10 +318,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, |
hdr->huffman_subsample_bits_ = huffman_precision; |
for (i = 0; i < huffman_pixs; ++i) { |
// The huffman data is stored in red and green bytes. |
- const int index = (huffman_image[i] >> 8) & 0xffff; |
- huffman_image[i] = index; |
- if (index >= num_htree_groups) { |
- num_htree_groups = index + 1; |
+ const int group = (huffman_image[i] >> 8) & 0xffff; |
+ huffman_image[i] = group; |
+ if (group >= num_htree_groups) { |
+ num_htree_groups = group + 1; |
} |
} |
} |
@@ -615,20 +606,22 @@ static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr, |
typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row); |
-static void ApplyTransforms(VP8LDecoder* const dec, int num_rows, |
- const uint32_t* const rows) { |
+static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows, |
+ const uint32_t* const rows) { |
int n = dec->next_transform_; |
const int cache_pixs = dec->width_ * num_rows; |
- uint32_t* rows_data = dec->argb_cache_; |
const int start_row = dec->last_row_; |
const int end_row = start_row + num_rows; |
+ const uint32_t* rows_in = rows; |
+ uint32_t* const rows_out = dec->argb_cache_; |
// Inverse transforms. |
// TODO: most transforms only need to operate on the cropped region only. |
- memcpy(rows_data, rows, cache_pixs * sizeof(*rows_data)); |
+ memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); |
while (n-- > 0) { |
VP8LTransform* const transform = &dec->transforms_[n]; |
- VP8LInverseTransform(transform, start_row, end_row, rows, rows_data); |
+ VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out); |
+ rows_in = rows_out; |
} |
} |
@@ -639,7 +632,7 @@ static void ProcessRows(VP8LDecoder* const dec, int row) { |
const int num_rows = row - dec->last_row_; |
if (num_rows <= 0) return; // Nothing to be done. |
- ApplyTransforms(dec, num_rows, rows); |
+ ApplyInverseTransforms(dec, num_rows, rows); |
// Emit output. |
{ |
@@ -797,19 +790,6 @@ static void ClearTransform(VP8LTransform* const transform) { |
transform->data_ = NULL; |
} |
-static void ApplyInverseTransforms(VP8LDecoder* const dec, int start_idx, |
- uint32_t* const decoded_data) { |
- int n = dec->next_transform_; |
- assert(start_idx >= 0); |
- while (n-- > start_idx) { |
- VP8LTransform* const transform = &dec->transforms_[n]; |
- VP8LInverseTransform(transform, 0, transform->ysize_, |
- decoded_data, decoded_data); |
- ClearTransform(transform); |
- } |
- dec->next_transform_ = start_idx; |
-} |
- |
// For security reason, we need to remap the color map to span |
// the total possible bundled values, and not just the num_colors. |
static int ExpandColorMap(int num_colors, VP8LTransform* const transform) { |
@@ -964,7 +944,6 @@ static int DecodeImageStream(int xsize, int ysize, |
VP8LBitReader* const br = &dec->br_; |
VP8LMetadata* const hdr = &dec->hdr_; |
uint32_t* data = NULL; |
fbarchard
2013/03/22 18:56:44
shouldnt we be using uint32* etc?
jzern
2013/03/22 19:10:36
no. we use posix types in this (C) project
|
- const int transform_start_idx = dec->next_transform_; |
int color_cache_bits = 0; |
// Read the transforms (may recurse). |
@@ -1024,9 +1003,6 @@ static int DecodeImageStream(int xsize, int ysize, |
ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, NULL); |
ok = ok && !br->error_; |
- // Apply transforms on the decoded data. |
- if (ok) ApplyInverseTransforms(dec, transform_start_idx, data); |
- |
End: |
if (!ok) { |
@@ -1083,7 +1059,7 @@ static void ExtractAlphaRows(VP8LDecoder* const dec, int row) { |
const uint32_t* const in = dec->argb_ + dec->width_ * dec->last_row_; |
if (num_rows <= 0) return; // Nothing to be done. |
- ApplyTransforms(dec, num_rows, in); |
+ ApplyInverseTransforms(dec, num_rows, in); |
// Extract alpha (which is stored in the green plane). |
{ |