diff options
author | Evgenii Kliuchnikov <eustas@eustas-wfh.fra.corp.google.com> | 2016-06-24 15:32:51 +0200 |
---|---|---|
committer | Evgenii Kliuchnikov <eustas@eustas-wfh.fra.corp.google.com> | 2016-06-24 15:32:51 +0200 |
commit | 52ff81717bb98f13f3ef0b0b415c917cfb75237f (patch) | |
tree | 413a90cee546c7512d99bbb1c4c789f64e5327fd /dec | |
parent | 49df97c472d21d0944780fada120b7e76e4de86c (diff) | |
download | brotli-52ff81717bb98f13f3ef0b0b415c917cfb75237f.zip brotli-52ff81717bb98f13f3ef0b0b415c917cfb75237f.tar.gz brotli-52ff81717bb98f13f3ef0b0b415c917cfb75237f.tar.bz2 |
Update build systems
Diffstat (limited to 'dec')
-rw-r--r-- | dec/decode.c | 45 | ||||
-rw-r--r-- | dec/decode.h | 5 |
2 files changed, 29 insertions, 21 deletions
diff --git a/dec/decode.c b/dec/decode.c index b278b78..5ae6db0 100644 --- a/dec/decode.c +++ b/dec/decode.c @@ -1268,27 +1268,36 @@ static BrotliErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput( int BrotliDecompressedSize(size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size) { + size_t total_size = 0; BrotliState s; - int next_block_header; + BrotliBitReader* br; BrotliStateInit(&s); - s.br.next_in = encoded_buffer; - s.br.avail_in = encoded_size; - if (!BrotliWarmupBitReader(&s.br)) { - return 0; - } - DecodeWindowBits(&s.br); - if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_SUCCESS) { - return 0; - } - *decoded_size = (size_t)s.meta_block_remaining_len; - if (s.is_last_metablock) { - return 1; - } - if (!s.is_uncompressed || !BrotliJumpToByteBoundary(&s.br)) { - return 0; + br = &s.br; + *decoded_size = 0; + br->next_in = encoded_buffer; + br->avail_in = encoded_size; + if (!BrotliWarmupBitReader(br)) return 0; + DecodeWindowBits(br); + while (1) { + size_t block_size; + if (DecodeMetaBlockLength(&s, br) != BROTLI_SUCCESS) return 0; + block_size = (size_t)s.meta_block_remaining_len; + if (!s.is_metadata) { + if ((block_size + total_size) < total_size) return 0; + total_size += block_size; + } + if (s.is_last_metablock) { + *decoded_size = total_size; + return 1; + } + if (!s.is_uncompressed && !s.is_metadata) return 0; + if (!BrotliJumpToByteBoundary(br)) return 0; + BrotliBitReaderUnload(br); + if (br->avail_in < block_size) return 0; + br->avail_in -= block_size; + br->next_in += block_size; + if (!BrotliWarmupBitReader(br)) return 0; } - next_block_header = BrotliPeekByte(&s.br, (size_t)s.meta_block_remaining_len); - return (next_block_header != -1) && ((next_block_header & 3) == 3); } /* Calculates the smallest feasible ring buffer. diff --git a/dec/decode.h b/dec/decode.h index dc77613..fc53dca 100644 --- a/dec/decode.h +++ b/dec/decode.h @@ -90,9 +90,8 @@ BrotliState* BrotliCreateState( void BrotliDestroyState(BrotliState* state); /* Sets |*decoded_size| to the decompressed size of the given encoded stream. - This function only works if the encoded buffer has a single meta block, - or if it has two meta-blocks, where the first is uncompressed and the - second is empty. + This function only works if the only compressed block, is last block. + There is no limit on number of uncompressed and metadata blocks. Returns 1 on success, 0 on failure. */ int BrotliDecompressedSize(size_t encoded_size, const uint8_t* encoded_buffer, |