Support window bits 10 - 15 in the decoder.

The previous window bit value 17 is used to
extend the range, since it has not been used
in any previous encoders.
This commit is contained in:
Zoltan Szabadka 2015-05-07 17:44:33 +02:00
parent 7bbfd5df95
commit 54f69c9ef7
5 changed files with 841 additions and 734 deletions

View File

@ -67,11 +67,19 @@ static const int kDistanceShortCodeValueOffset[NUM_DISTANCE_SHORT_CODES] = {
};
static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) {
if (BrotliReadBits(br, 1)) {
return 17 + (int)BrotliReadBits(br, 3);
} else {
int n;
if (BrotliReadBits(br, 1) == 0) {
return 16;
}
n = (int)BrotliReadBits(br, 3);
if (n > 0) {
return 17 + n;
}
n = (int)BrotliReadBits(br, 3);
if (n > 0) {
return 8 + n;
}
return 17;
}
/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
@ -845,7 +853,13 @@ BrotliResult BrotliDecompressedSize(size_t encoded_size,
val |= (uint64_t)encoded_buffer[i] << (8 * i);
}
/* Skip the window bits. */
bit_pos += (val & 1) ? 4 : 1;
++bit_pos;
if (val & 1) {
bit_pos += 3;
if (((val >> 1) & 7) == 0) {
bit_pos += 3;
}
}
/* Decode the ISLAST bit. */
is_last = (val >> bit_pos) & 1;
++bit_pos;
@ -859,6 +873,10 @@ BrotliResult BrotliDecompressedSize(size_t encoded_size,
}
/* Decode the length of the first meta-block. */
size_nibbles = (int)((val >> bit_pos) & 3) + 4;
if (size_nibbles == 7) {
/* First meta-block contains metadata, this case is not supported here. */
return BROTLI_RESULT_ERROR;
}
bit_pos += 2;
for (i = 0; i < size_nibbles; ++i) {
meta_block_len |= (int)((val >> bit_pos) & 0xf) << (4 * i);
@ -997,6 +1015,11 @@ BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
}
/* Decode window size. */
s->window_bits = DecodeWindowBits(br);
if (s->window_bits == 9) {
/* Value 9 is reserved for future use. */
result = BROTLI_RESULT_ERROR;
break;
}
s->max_backward_distance = (1 << s->window_bits) - 16;
s->block_type_trees = (HuffmanCode*)malloc(

View File

@ -1356,9 +1356,31 @@ previous sections.
The stream header has only the following one field:
.nf
1-4 bits: WBITS, a value in the range 16 - 24, value 16 is
encoded with one 0 bit, and values 17 - 24 are
encoded with bit pattern xxx1 (so 0111 is 20)
1-7 bits: WBITS, a value in the range 10 - 24, encoded with
the following variable length code (as it appears in
the compressed data, where the bits are parsed from
right to left):
Value Bit Pattern
----- -----------
10 0100001
11 0110001
12 1000001
13 1010001
14 1100001
15 1110001
16 0
17 0000001
18 0011
19 0101
20 0111
21 1001
22 1011
23 1101
24 1111
Note that bit pattern 0010001 is invalid and must not
be used.
.fi
The size of the sliding window, which is the maximum value of any

File diff suppressed because it is too large Load Diff

View File

@ -190,6 +190,9 @@ BrotliCompressor::BrotliCompressor(BrotliParams params)
if (params_.lgwin == 16) {
last_byte_ = 0;
last_byte_bits_ = 1;
} else if (params_.lgwin == 17) {
last_byte_ = 1;
last_byte_bits_ = 7;
} else {
last_byte_ = ((params_.lgwin - 17) << 1) | 1;
last_byte_bits_ = 4;

View File

@ -231,6 +231,9 @@ bool WriteMetaBlockParallel(const BrotliParams& params,
if (params.lgwin == 16) {
first_byte = 0;
first_byte_bits = 1;
} else if (params.lgwin == 17) {
first_byte = 1;
first_byte_bits = 7;
} else {
first_byte = ((params.lgwin - 17) << 1) | 1;
first_byte_bits = 4;