VP8LSetBitPos: remove the eos_ setting

This code is ultra-critical for lossless decoding, especially on ARM.
The extra call VP8LIsEndOfStream() was causing unnecessary slow-down.

Now, we check for bitstream-end separately in the main loop.

Change-Id: I739b5d74cc29578e2b712ba99b544fd995ef0e0d
This commit is contained in:
skal 2017-02-11 01:51:37 -08:00
parent 027151ca6c
commit 16be192f47
2 changed files with 8 additions and 6 deletions

View File

@ -1012,12 +1012,13 @@ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
ok = 0; ok = 0;
goto End; goto End;
} }
assert(br->eos_ == VP8LIsEndOfStream(br)); br->eos_ = VP8LIsEndOfStream(br);
} }
// Process the remaining rows corresponding to last row-block. // Process the remaining rows corresponding to last row-block.
ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row); ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
End: End:
br->eos_ = VP8LIsEndOfStream(br);
if (!ok || (br->eos_ && pos < end)) { if (!ok || (br->eos_ && pos < end)) {
ok = 0; ok = 0;
dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
@ -1094,7 +1095,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
} else { } else {
code = ReadSymbol(htree_group->htrees[GREEN], br); code = ReadSymbol(htree_group->htrees[GREEN], br);
} }
if (br->eos_) break; // early out if (VP8LIsEndOfStream(br)) break;
if (code < NUM_LITERAL_CODES) { // Literal if (code < NUM_LITERAL_CODES) { // Literal
if (htree_group->is_trivial_literal) { if (htree_group->is_trivial_literal) {
*src = htree_group->literal_arb | (code << 8); *src = htree_group->literal_arb | (code << 8);
@ -1104,7 +1105,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
VP8LFillBitWindow(br); VP8LFillBitWindow(br);
blue = ReadSymbol(htree_group->htrees[BLUE], br); blue = ReadSymbol(htree_group->htrees[BLUE], br);
alpha = ReadSymbol(htree_group->htrees[ALPHA], br); alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
if (br->eos_) break; if (VP8LIsEndOfStream(br)) break;
*src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue; *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
} }
AdvanceByOne: AdvanceByOne:
@ -1132,7 +1133,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
VP8LFillBitWindow(br); VP8LFillBitWindow(br);
dist_code = GetCopyDistance(dist_symbol, br); dist_code = GetCopyDistance(dist_symbol, br);
dist = PlaneCodeToDistance(width, dist_code); dist = PlaneCodeToDistance(width, dist_code);
if (br->eos_) break; if (VP8LIsEndOfStream(br)) break;
if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
goto Error; goto Error;
} else { } else {
@ -1169,9 +1170,9 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
} else { // Not reached } else { // Not reached
goto Error; goto Error;
} }
assert(br->eos_ == VP8LIsEndOfStream(br));
} }
br->eos_ = VP8LIsEndOfStream(br);
if (dec->incremental_ && br->eos_ && src < src_end) { if (dec->incremental_ && br->eos_ && src < src_end) {
RestoreState(dec); RestoreState(dec);
} else if (!br->eos_) { } else if (!br->eos_) {

View File

@ -155,9 +155,10 @@ static WEBP_INLINE int VP8LIsEndOfStream(const VP8LBitReader* const br) {
// For jumping over a number of bits in the bit stream when accessed with // For jumping over a number of bits in the bit stream when accessed with
// VP8LPrefetchBits and VP8LFillBitWindow. // VP8LPrefetchBits and VP8LFillBitWindow.
// This function does *not* set br->eos_, since it's speed-critical.
// Use with extreme care!
static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) { static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {
br->bit_pos_ = val; br->bit_pos_ = val;
br->eos_ = VP8LIsEndOfStream(br);
} }
// 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.