mirror of
https://github.com/google/brotli.git
synced 2024-11-21 19:20:09 +00:00
Merge pull request #2 from szabadka/decoder
Fix BrotliDecompressedSize() to work for an uncompressed plus an empty meta-block.
This commit is contained in:
commit
c62fa2116f
66
dec/decode.c
66
dec/decode.c
@ -633,22 +633,62 @@ int CopyUncompressedBlockToOutput(BrotliOutput output, int len, int pos,
|
|||||||
int BrotliDecompressedSize(size_t encoded_size,
|
int BrotliDecompressedSize(size_t encoded_size,
|
||||||
const uint8_t* encoded_buffer,
|
const uint8_t* encoded_buffer,
|
||||||
size_t* decoded_size) {
|
size_t* decoded_size) {
|
||||||
BrotliMemInput memin;
|
int i;
|
||||||
BrotliInput input = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
|
uint64_t val = 0;
|
||||||
BrotliBitReader br;
|
int bit_pos = 0;
|
||||||
int meta_block_len;
|
int is_last;
|
||||||
int input_end;
|
int is_uncompressed = 0;
|
||||||
int is_uncompressed;
|
int size_nibbles;
|
||||||
if (!BrotliInitBitReader(&br, input)) {
|
int meta_block_len = 0;
|
||||||
|
if (encoded_size == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DecodeWindowBits(&br);
|
/* Look at the first 8 bytes, it is enough to decode the length of the first
|
||||||
DecodeMetaBlockLength(&br, &meta_block_len, &input_end, &is_uncompressed);
|
meta-block. */
|
||||||
if (!input_end) {
|
for (i = 0; i < encoded_size && i < 8; ++i) {
|
||||||
return 0;
|
val |= (uint64_t)encoded_buffer[i] << (8 * i);
|
||||||
}
|
}
|
||||||
*decoded_size = (size_t)meta_block_len;
|
/* Skip the window bits. */
|
||||||
return 1;
|
bit_pos += (val & 1) ? 4 : 1;
|
||||||
|
/* Decode the ISLAST bit. */
|
||||||
|
is_last = (val >> bit_pos) & 1;
|
||||||
|
++bit_pos;
|
||||||
|
if (is_last) {
|
||||||
|
/* Decode the ISEMPTY bit, if it is set to 1, we are done. */
|
||||||
|
if ((val >> bit_pos) & 1) {
|
||||||
|
*decoded_size = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
++bit_pos;
|
||||||
|
}
|
||||||
|
/* Decode the length of the first meta-block. */
|
||||||
|
size_nibbles = (int)((val >> bit_pos) & 3) + 4;
|
||||||
|
bit_pos += 2;
|
||||||
|
for (i = 0; i < size_nibbles; ++i) {
|
||||||
|
meta_block_len |= (int)((val >> bit_pos) & 0xf) << (4 * i);
|
||||||
|
bit_pos += 4;
|
||||||
|
}
|
||||||
|
++meta_block_len;
|
||||||
|
if (is_last) {
|
||||||
|
/* If this meta-block is the only one, we are done. */
|
||||||
|
*decoded_size = (size_t)meta_block_len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
is_uncompressed = (val >> bit_pos) & 1;
|
||||||
|
++bit_pos;
|
||||||
|
if (is_uncompressed) {
|
||||||
|
/* If the first meta-block is uncompressed, we skip it and look at the
|
||||||
|
first two bits (ISLAST and ISEMPTY) of the next meta-block, and if
|
||||||
|
both are set to 1, we have a stream with an uncompressed meta-block
|
||||||
|
followed by an empty one, so the decompressed size is the size of the
|
||||||
|
first meta-block. */
|
||||||
|
int offset = ((bit_pos + 7) >> 3) + meta_block_len;
|
||||||
|
if (offset < encoded_size && ((encoded_buffer[offset] & 3) == 3)) {
|
||||||
|
*decoded_size = (size_t)meta_block_len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BrotliDecompressBuffer(size_t encoded_size,
|
int BrotliDecompressBuffer(size_t encoded_size,
|
||||||
|
@ -27,7 +27,8 @@ extern "C" {
|
|||||||
|
|
||||||
/* Sets *decoded_size to the decompressed size of the given encoded stream. */
|
/* 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, */
|
/* This function only works if the encoded buffer has a single meta block, */
|
||||||
/* and this meta block must have the "is last" bit set. */
|
/* or if it has two meta-blocks, where the first is uncompressed and the */
|
||||||
|
/* second is empty. */
|
||||||
/* Returns 1 on success, 0 on failure. */
|
/* Returns 1 on success, 0 on failure. */
|
||||||
int BrotliDecompressedSize(size_t encoded_size,
|
int BrotliDecompressedSize(size_t encoded_size,
|
||||||
const uint8_t* encoded_buffer,
|
const uint8_t* encoded_buffer,
|
||||||
|
Loading…
Reference in New Issue
Block a user