brotli 0.2.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +34 -0
- data/.github/workflows/publish.yml +34 -0
- data/Gemfile +6 -3
- data/Rakefile +16 -9
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +209 -31
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +20 -18
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +104 -0
- data/test/brotli_writer_test.rb +36 -0
- data/test/test_helper.rb +8 -0
- data/vendor/brotli/c/common/constants.c +15 -0
- data/vendor/brotli/c/common/constants.h +136 -0
- data/vendor/brotli/c/common/context.c +156 -0
- data/vendor/brotli/c/common/context.h +4 -152
- data/vendor/brotli/c/common/dictionary.bin.br +0 -0
- data/vendor/brotli/c/common/dictionary.c +10 -1
- data/vendor/brotli/c/common/platform.c +22 -0
- data/vendor/brotli/c/common/platform.h +43 -17
- data/vendor/brotli/c/common/transform.c +59 -3
- data/vendor/brotli/c/common/transform.h +5 -0
- data/vendor/brotli/c/common/version.h +2 -2
- data/vendor/brotli/c/dec/bit_reader.c +28 -0
- data/vendor/brotli/c/dec/bit_reader.h +58 -16
- data/vendor/brotli/c/dec/decode.c +353 -251
- data/vendor/brotli/c/dec/huffman.h +6 -12
- data/vendor/brotli/c/dec/prefix.h +0 -18
- data/vendor/brotli/c/dec/state.c +9 -14
- data/vendor/brotli/c/dec/state.h +144 -37
- data/vendor/brotli/c/enc/backward_references.c +8 -7
- data/vendor/brotli/c/enc/backward_references.h +5 -4
- data/vendor/brotli/c/enc/backward_references_hq.c +51 -33
- data/vendor/brotli/c/enc/backward_references_hq.h +11 -8
- data/vendor/brotli/c/enc/backward_references_inc.h +24 -14
- data/vendor/brotli/c/enc/block_splitter.c +3 -3
- data/vendor/brotli/c/enc/block_splitter_inc.h +15 -6
- data/vendor/brotli/c/enc/brotli_bit_stream.c +13 -30
- data/vendor/brotli/c/enc/cluster_inc.h +6 -3
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +12 -12
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +1 -1
- data/vendor/brotli/c/enc/dictionary_hash.c +1826 -1100
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +104 -39
- data/vendor/brotli/c/enc/encoder_dict.c +3 -2
- data/vendor/brotli/c/enc/encoder_dict.h +3 -1
- data/vendor/brotli/c/enc/entropy_encode.c +2 -0
- data/vendor/brotli/c/enc/entropy_encode.h +2 -2
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +19 -100
- data/vendor/brotli/c/enc/find_match_length.h +2 -3
- data/vendor/brotli/c/enc/hash.h +80 -90
- data/vendor/brotli/c/enc/hash_composite_inc.h +52 -63
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +88 -49
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +50 -50
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -50
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +91 -60
- data/vendor/brotli/c/enc/hash_rolling_inc.h +23 -27
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +39 -38
- data/vendor/brotli/c/enc/memory.h +24 -12
- data/vendor/brotli/c/enc/metablock.c +23 -27
- data/vendor/brotli/c/enc/metablock_inc.h +1 -1
- data/vendor/brotli/c/enc/params.h +3 -1
- data/vendor/brotli/c/enc/ringbuffer.h +4 -1
- data/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/vendor/brotli/c/enc/write_bits.h +27 -25
- data/vendor/brotli/c/include/brotli/encode.h +22 -1
- data/vendor/brotli/c/include/brotli/port.h +14 -0
- metadata +17 -97
- data/.travis.yml +0 -31
- data/docs/Brotli.html +0 -485
- data/docs/Brotli/Error.html +0 -124
- data/docs/_index.html +0 -122
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -496
- data/docs/file.README.html +0 -127
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -127
- data/docs/js/app.js +0 -292
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -67
- data/docs/top-level-namespace.html +0 -110
- data/spec/brotli_spec.rb +0 -88
- data/spec/inflate_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -4
@@ -37,6 +37,8 @@ enum BrotliWordTransformType {
|
|
37
37
|
BROTLI_TRANSFORM_OMIT_FIRST_7 = 18,
|
38
38
|
BROTLI_TRANSFORM_OMIT_FIRST_8 = 19,
|
39
39
|
BROTLI_TRANSFORM_OMIT_FIRST_9 = 20,
|
40
|
+
BROTLI_TRANSFORM_SHIFT_FIRST = 21,
|
41
|
+
BROTLI_TRANSFORM_SHIFT_ALL = 22,
|
40
42
|
BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */
|
41
43
|
};
|
42
44
|
|
@@ -50,6 +52,9 @@ typedef struct BrotliTransforms {
|
|
50
52
|
uint32_t num_transforms;
|
51
53
|
/* Each entry is a [prefix_id, transform, suffix_id] triplet. */
|
52
54
|
const uint8_t* transforms;
|
55
|
+
/* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL,
|
56
|
+
must be NULL if and only if no such transforms are present. */
|
57
|
+
const uint8_t* params;
|
53
58
|
/* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""].
|
54
59
|
0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""].
|
55
60
|
-1, if cut-off transform does not exist. */
|
@@ -14,13 +14,13 @@
|
|
14
14
|
BrotliEncoderVersion methods. */
|
15
15
|
|
16
16
|
/* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
|
17
|
-
#define BROTLI_VERSION
|
17
|
+
#define BROTLI_VERSION 0x1000009
|
18
18
|
|
19
19
|
/* This macro is used by build system to produce Libtool-friendly soname. See
|
20
20
|
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
21
21
|
*/
|
22
22
|
|
23
23
|
/* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */
|
24
|
-
#define BROTLI_ABI_VERSION
|
24
|
+
#define BROTLI_ABI_VERSION 0x1009000
|
25
25
|
|
26
26
|
#endif /* BROTLI_COMMON_VERSION_H_ */
|
@@ -15,6 +15,17 @@
|
|
15
15
|
extern "C" {
|
16
16
|
#endif
|
17
17
|
|
18
|
+
const uint32_t kBrotliBitMask[33] = { 0x00000000,
|
19
|
+
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
20
|
+
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
|
21
|
+
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
|
22
|
+
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
|
23
|
+
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
|
24
|
+
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
|
25
|
+
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
|
26
|
+
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
|
27
|
+
};
|
28
|
+
|
18
29
|
void BrotliInitBitReader(BrotliBitReader* const br) {
|
19
30
|
br->val_ = 0;
|
20
31
|
br->bit_pos_ = sizeof(br->val_) << 3;
|
@@ -43,6 +54,23 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|
43
54
|
return BROTLI_TRUE;
|
44
55
|
}
|
45
56
|
|
57
|
+
BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
|
58
|
+
uint32_t n_bits, uint32_t* val) {
|
59
|
+
uint32_t low_val;
|
60
|
+
uint32_t high_val;
|
61
|
+
BrotliBitReaderState memento;
|
62
|
+
BROTLI_DCHECK(n_bits <= 32);
|
63
|
+
BROTLI_DCHECK(n_bits > 24);
|
64
|
+
BrotliBitReaderSaveState(br, &memento);
|
65
|
+
if (!BrotliSafeReadBits(br, 16, &low_val) ||
|
66
|
+
!BrotliSafeReadBits(br, n_bits - 16, &high_val)) {
|
67
|
+
BrotliBitReaderRestoreState(br, &memento);
|
68
|
+
return BROTLI_FALSE;
|
69
|
+
}
|
70
|
+
*val = low_val | (high_val << 16);
|
71
|
+
return BROTLI_TRUE;
|
72
|
+
}
|
73
|
+
|
46
74
|
#if defined(__cplusplus) || defined(c_plusplus)
|
47
75
|
} /* extern "C" */
|
48
76
|
#endif
|
@@ -11,6 +11,7 @@
|
|
11
11
|
|
12
12
|
#include <string.h> /* memcpy */
|
13
13
|
|
14
|
+
#include "../common/constants.h"
|
14
15
|
#include "../common/platform.h"
|
15
16
|
#include <brotli/types.h>
|
16
17
|
|
@@ -20,16 +21,7 @@ extern "C" {
|
|
20
21
|
|
21
22
|
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
|
22
23
|
|
23
|
-
|
24
|
-
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
25
|
-
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
|
26
|
-
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
|
27
|
-
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
|
28
|
-
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
|
29
|
-
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
|
30
|
-
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
|
31
|
-
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
|
32
|
-
};
|
24
|
+
BROTLI_INTERNAL extern const uint32_t kBrotliBitMask[33];
|
33
25
|
|
34
26
|
static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
35
27
|
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
|
@@ -37,7 +29,7 @@ static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
|
37
29
|
"Unsigned Bit Field Extract" UBFX instruction on ARM. */
|
38
30
|
return ~((0xFFFFFFFFu) << n);
|
39
31
|
} else {
|
40
|
-
return
|
32
|
+
return kBrotliBitMask[n];
|
41
33
|
}
|
42
34
|
}
|
43
35
|
|
@@ -65,6 +57,12 @@ BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
|
|
65
57
|
reading. */
|
66
58
|
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
|
67
59
|
|
60
|
+
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
|
61
|
+
the main code-path. Never called for RFC brotli streams, required only for
|
62
|
+
"large-window" mode and other extensions. */
|
63
|
+
BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
|
64
|
+
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val);
|
65
|
+
|
68
66
|
static BROTLI_INLINE void BrotliBitReaderSaveState(
|
69
67
|
BrotliBitReader* const from, BrotliBitReaderState* to) {
|
70
68
|
to->val_ = from->val_;
|
@@ -87,8 +85,11 @@ static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
|
|
87
85
|
}
|
88
86
|
|
89
87
|
/* Returns amount of unread bytes the bit reader still has buffered from the
|
90
|
-
BrotliInput, including whole bytes in br->val_.
|
88
|
+
BrotliInput, including whole bytes in br->val_. Result is capped with
|
89
|
+
maximal ring-buffer size (larger number won't be utilized anyway). */
|
91
90
|
static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
|
91
|
+
static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS;
|
92
|
+
if (br->avail_in > kCap) return kCap;
|
92
93
|
return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
|
93
94
|
}
|
94
95
|
|
@@ -237,15 +238,17 @@ static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
|
237
238
|
static BROTLI_INLINE void BrotliTakeBits(
|
238
239
|
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
239
240
|
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
240
|
-
BROTLI_LOG(("[
|
241
|
+
BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
|
241
242
|
(int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
|
242
243
|
BrotliDropBits(br, n_bits);
|
243
244
|
}
|
244
245
|
|
245
246
|
/* Reads the specified number of bits from |br| and advances the bit pos.
|
246
|
-
Assumes that there is enough input to perform BrotliFillBitWindow.
|
247
|
-
|
247
|
+
Assumes that there is enough input to perform BrotliFillBitWindow.
|
248
|
+
Up to 24 bits are allowed to be requested from this method. */
|
249
|
+
static BROTLI_INLINE uint32_t BrotliReadBits24(
|
248
250
|
BrotliBitReader* const br, uint32_t n_bits) {
|
251
|
+
BROTLI_DCHECK(n_bits <= 24);
|
249
252
|
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
250
253
|
uint32_t val;
|
251
254
|
BrotliFillBitWindow(br, n_bits);
|
@@ -262,10 +265,32 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
|
|
262
265
|
}
|
263
266
|
}
|
264
267
|
|
268
|
+
/* Same as BrotliReadBits24, but allows reading up to 32 bits. */
|
269
|
+
static BROTLI_INLINE uint32_t BrotliReadBits32(
|
270
|
+
BrotliBitReader* const br, uint32_t n_bits) {
|
271
|
+
BROTLI_DCHECK(n_bits <= 32);
|
272
|
+
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
273
|
+
uint32_t val;
|
274
|
+
BrotliFillBitWindow(br, n_bits);
|
275
|
+
BrotliTakeBits(br, n_bits, &val);
|
276
|
+
return val;
|
277
|
+
} else {
|
278
|
+
uint32_t low_val;
|
279
|
+
uint32_t high_val;
|
280
|
+
BrotliFillBitWindow(br, 16);
|
281
|
+
BrotliTakeBits(br, 16, &low_val);
|
282
|
+
BrotliFillBitWindow(br, 16);
|
283
|
+
BrotliTakeBits(br, n_bits - 16, &high_val);
|
284
|
+
return low_val | (high_val << 16);
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
265
288
|
/* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there
|
266
|
-
is not enough input. |n_bits| MUST be positive.
|
289
|
+
is not enough input. |n_bits| MUST be positive.
|
290
|
+
Up to 24 bits are allowed to be requested from this method. */
|
267
291
|
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
268
292
|
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
293
|
+
BROTLI_DCHECK(n_bits <= 24);
|
269
294
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
270
295
|
if (!BrotliPullByte(br)) {
|
271
296
|
return BROTLI_FALSE;
|
@@ -275,6 +300,23 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
|
275
300
|
return BROTLI_TRUE;
|
276
301
|
}
|
277
302
|
|
303
|
+
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
|
304
|
+
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
|
305
|
+
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
306
|
+
BROTLI_DCHECK(n_bits <= 32);
|
307
|
+
if (BROTLI_64_BITS || (n_bits <= 24)) {
|
308
|
+
while (BrotliGetAvailableBits(br) < n_bits) {
|
309
|
+
if (!BrotliPullByte(br)) {
|
310
|
+
return BROTLI_FALSE;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
BrotliTakeBits(br, n_bits, val);
|
314
|
+
return BROTLI_TRUE;
|
315
|
+
} else {
|
316
|
+
return BrotliSafeReadBits32Slow(br, n_bits, val);
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
278
320
|
/* Advances the bit reader position to the next byte boundary and verifies
|
279
321
|
that any skipped bits are set to zero. */
|
280
322
|
static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
@@ -41,7 +41,8 @@ extern "C" {
|
|
41
41
|
|
42
42
|
/* We need the slack region for the following reasons:
|
43
43
|
- doing up to two 16-byte copies for fast backward copying
|
44
|
-
- inserting transformed dictionary word
|
44
|
+
- inserting transformed dictionary word:
|
45
|
+
5 prefix + 24 base + 8 suffix */
|
45
46
|
static const uint32_t kRingBufferWriteAheadSlack = 42;
|
46
47
|
|
47
48
|
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
|
@@ -274,7 +275,8 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
274
275
|
s->loop_counter = i;
|
275
276
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
276
277
|
}
|
277
|
-
if (i + 1 == s->size_nibbles && s->size_nibbles > 4 &&
|
278
|
+
if (i + 1 == (int)s->size_nibbles && s->size_nibbles > 4 &&
|
279
|
+
bits == 0) {
|
278
280
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE);
|
279
281
|
}
|
280
282
|
s->meta_block_remaining_len |= (int)(bits << (i * 4));
|
@@ -323,7 +325,8 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
323
325
|
s->loop_counter = i;
|
324
326
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
325
327
|
}
|
326
|
-
if (i + 1 == s->size_nibbles && s->size_nibbles > 1 &&
|
328
|
+
if (i + 1 == (int)s->size_nibbles && s->size_nibbles > 1 &&
|
329
|
+
bits == 0) {
|
327
330
|
return BROTLI_FAILURE(
|
328
331
|
BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
|
329
332
|
}
|
@@ -470,32 +473,34 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
|
|
470
473
|
Totally 1..4 symbols are read, 1..11 bits each.
|
471
474
|
The list of symbols MUST NOT contain duplicates. */
|
472
475
|
static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
473
|
-
uint32_t
|
476
|
+
uint32_t alphabet_size_max, uint32_t alphabet_size_limit,
|
477
|
+
BrotliDecoderState* s) {
|
474
478
|
/* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */
|
475
479
|
BrotliBitReader* br = &s->br;
|
476
|
-
|
477
|
-
uint32_t
|
478
|
-
uint32_t
|
480
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
481
|
+
uint32_t max_bits = Log2Floor(alphabet_size_max - 1);
|
482
|
+
uint32_t i = h->sub_loop_counter;
|
483
|
+
uint32_t num_symbols = h->symbol;
|
479
484
|
while (i <= num_symbols) {
|
480
485
|
uint32_t v;
|
481
486
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
|
482
|
-
|
483
|
-
|
487
|
+
h->sub_loop_counter = i;
|
488
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
|
484
489
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
485
490
|
}
|
486
|
-
if (v >=
|
491
|
+
if (v >= alphabet_size_limit) {
|
487
492
|
return
|
488
493
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
|
489
494
|
}
|
490
|
-
|
491
|
-
BROTLI_LOG_UINT(
|
495
|
+
h->symbols_lists_array[i] = (uint16_t)v;
|
496
|
+
BROTLI_LOG_UINT(h->symbols_lists_array[i]);
|
492
497
|
++i;
|
493
498
|
}
|
494
499
|
|
495
500
|
for (i = 0; i < num_symbols; ++i) {
|
496
501
|
uint32_t k = i + 1;
|
497
502
|
for (; k <= num_symbols; ++k) {
|
498
|
-
if (
|
503
|
+
if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) {
|
499
504
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
|
500
505
|
}
|
501
506
|
}
|
@@ -588,27 +593,28 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
|
588
593
|
static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
589
594
|
uint32_t alphabet_size, BrotliDecoderState* s) {
|
590
595
|
BrotliBitReader* br = &s->br;
|
591
|
-
|
592
|
-
uint32_t
|
593
|
-
uint32_t
|
594
|
-
uint32_t
|
595
|
-
uint32_t
|
596
|
-
|
597
|
-
uint16_t*
|
598
|
-
|
596
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
597
|
+
uint32_t symbol = h->symbol;
|
598
|
+
uint32_t repeat = h->repeat;
|
599
|
+
uint32_t space = h->space;
|
600
|
+
uint32_t prev_code_len = h->prev_code_len;
|
601
|
+
uint32_t repeat_code_len = h->repeat_code_len;
|
602
|
+
uint16_t* symbol_lists = h->symbol_lists;
|
603
|
+
uint16_t* code_length_histo = h->code_length_histo;
|
604
|
+
int* next_symbol = h->next_symbol;
|
599
605
|
if (!BrotliWarmupBitReader(br)) {
|
600
606
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
601
607
|
}
|
602
608
|
while (symbol < alphabet_size && space > 0) {
|
603
|
-
const HuffmanCode* p =
|
609
|
+
const HuffmanCode* p = h->table;
|
604
610
|
uint32_t code_len;
|
605
611
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
606
612
|
if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
613
|
+
h->symbol = symbol;
|
614
|
+
h->repeat = repeat;
|
615
|
+
h->prev_code_len = prev_code_len;
|
616
|
+
h->repeat_code_len = repeat_code_len;
|
617
|
+
h->space = space;
|
612
618
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
613
619
|
}
|
614
620
|
BrotliFillBitWindow16(br);
|
@@ -630,16 +636,17 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
630
636
|
symbol_lists, code_length_histo, next_symbol);
|
631
637
|
}
|
632
638
|
}
|
633
|
-
|
639
|
+
h->space = space;
|
634
640
|
return BROTLI_DECODER_SUCCESS;
|
635
641
|
}
|
636
642
|
|
637
643
|
static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
638
644
|
uint32_t alphabet_size, BrotliDecoderState* s) {
|
639
645
|
BrotliBitReader* br = &s->br;
|
646
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
640
647
|
BROTLI_BOOL get_byte = BROTLI_FALSE;
|
641
|
-
while (
|
642
|
-
const HuffmanCode* p =
|
648
|
+
while (h->symbol < alphabet_size && h->space > 0) {
|
649
|
+
const HuffmanCode* p = h->table;
|
643
650
|
uint32_t code_len;
|
644
651
|
uint32_t available_bits;
|
645
652
|
uint32_t bits = 0;
|
@@ -659,9 +666,9 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
659
666
|
code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */
|
660
667
|
if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
661
668
|
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p));
|
662
|
-
ProcessSingleCodeLength(code_len, &
|
663
|
-
&
|
664
|
-
|
669
|
+
ProcessSingleCodeLength(code_len, &h->symbol, &h->repeat, &h->space,
|
670
|
+
&h->prev_code_len, h->symbol_lists, h->code_length_histo,
|
671
|
+
h->next_symbol);
|
665
672
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
666
673
|
uint32_t extra_bits = code_len - 14U;
|
667
674
|
uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
|
@@ -672,9 +679,9 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
672
679
|
}
|
673
680
|
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits);
|
674
681
|
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
675
|
-
&
|
676
|
-
&
|
677
|
-
|
682
|
+
&h->symbol, &h->repeat, &h->space, &h->prev_code_len,
|
683
|
+
&h->repeat_code_len, h->symbol_lists, h->code_length_histo,
|
684
|
+
h->next_symbol);
|
678
685
|
}
|
679
686
|
}
|
680
687
|
return BROTLI_DECODER_SUCCESS;
|
@@ -684,9 +691,10 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
684
691
|
Each code is 2..4 bits long. In total 30..72 bits are used. */
|
685
692
|
static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
686
693
|
BrotliBitReader* br = &s->br;
|
687
|
-
|
688
|
-
|
689
|
-
|
694
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
695
|
+
uint32_t num_codes = h->repeat;
|
696
|
+
unsigned space = h->space;
|
697
|
+
uint32_t i = h->sub_loop_counter;
|
690
698
|
for (; i < BROTLI_CODE_LENGTH_CODES; ++i) {
|
691
699
|
const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
|
692
700
|
uint32_t ix;
|
@@ -699,21 +707,21 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
|
699
707
|
ix = 0;
|
700
708
|
}
|
701
709
|
if (kCodeLengthPrefixLength[ix] > available_bits) {
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
710
|
+
h->sub_loop_counter = i;
|
711
|
+
h->repeat = num_codes;
|
712
|
+
h->space = space;
|
713
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
|
706
714
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
707
715
|
}
|
708
716
|
}
|
709
717
|
v = kCodeLengthPrefixValue[ix];
|
710
718
|
BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
|
711
|
-
|
712
|
-
BROTLI_LOG_ARRAY_INDEX(
|
719
|
+
h->code_length_code_lengths[code_len_idx] = (uint8_t)v;
|
720
|
+
BROTLI_LOG_ARRAY_INDEX(h->code_length_code_lengths, code_len_idx);
|
713
721
|
if (v != 0) {
|
714
722
|
space = space - (32U >> v);
|
715
723
|
++num_codes;
|
716
|
-
++
|
724
|
+
++h->code_length_histo[v];
|
717
725
|
if (space - 1U >= 32U) {
|
718
726
|
/* space is 0 or wrapped around. */
|
719
727
|
break;
|
@@ -737,49 +745,48 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
|
737
745
|
encoded with predefined entropy code. 32 - 74 bits are used.
|
738
746
|
B.2) Decoded table is used to decode code lengths of symbols in resulting
|
739
747
|
Huffman table. In worst case 3520 bits are read. */
|
740
|
-
static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t
|
741
|
-
uint32_t
|
748
|
+
static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
749
|
+
uint32_t alphabet_size_limit,
|
742
750
|
HuffmanCode* table,
|
743
751
|
uint32_t* opt_table_size,
|
744
752
|
BrotliDecoderState* s) {
|
745
753
|
BrotliBitReader* br = &s->br;
|
746
|
-
|
747
|
-
alphabet_size &= 0x7FF;
|
754
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
748
755
|
/* State machine. */
|
749
756
|
for (;;) {
|
750
|
-
switch (
|
757
|
+
switch (h->substate_huffman) {
|
751
758
|
case BROTLI_STATE_HUFFMAN_NONE:
|
752
|
-
if (!BrotliSafeReadBits(br, 2, &
|
759
|
+
if (!BrotliSafeReadBits(br, 2, &h->sub_loop_counter)) {
|
753
760
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
754
761
|
}
|
755
|
-
BROTLI_LOG_UINT(
|
762
|
+
BROTLI_LOG_UINT(h->sub_loop_counter);
|
756
763
|
/* The value is used as follows:
|
757
764
|
1 for simple code;
|
758
765
|
0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
|
759
|
-
if (
|
760
|
-
|
761
|
-
|
762
|
-
memset(&
|
766
|
+
if (h->sub_loop_counter != 1) {
|
767
|
+
h->space = 32;
|
768
|
+
h->repeat = 0; /* num_codes */
|
769
|
+
memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo[0]) *
|
763
770
|
(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));
|
764
|
-
memset(&
|
765
|
-
sizeof(
|
766
|
-
|
771
|
+
memset(&h->code_length_code_lengths[0], 0,
|
772
|
+
sizeof(h->code_length_code_lengths));
|
773
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
|
767
774
|
continue;
|
768
775
|
}
|
769
776
|
/* Fall through. */
|
770
777
|
|
771
778
|
case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:
|
772
779
|
/* Read symbols, codes & code lengths directly. */
|
773
|
-
if (!BrotliSafeReadBits(br, 2, &
|
774
|
-
|
780
|
+
if (!BrotliSafeReadBits(br, 2, &h->symbol)) { /* num_symbols */
|
781
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
|
775
782
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
776
783
|
}
|
777
|
-
|
784
|
+
h->sub_loop_counter = 0;
|
778
785
|
/* Fall through. */
|
779
786
|
|
780
787
|
case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
|
781
788
|
BrotliDecoderErrorCode result =
|
782
|
-
ReadSimpleHuffmanSymbols(
|
789
|
+
ReadSimpleHuffmanSymbols(alphabet_size_max, alphabet_size_limit, s);
|
783
790
|
if (result != BROTLI_DECODER_SUCCESS) {
|
784
791
|
return result;
|
785
792
|
}
|
@@ -788,21 +795,21 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
|
|
788
795
|
|
789
796
|
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
|
790
797
|
uint32_t table_size;
|
791
|
-
if (
|
798
|
+
if (h->symbol == 3) {
|
792
799
|
uint32_t bits;
|
793
800
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
794
|
-
|
801
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
|
795
802
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
796
803
|
}
|
797
|
-
|
804
|
+
h->symbol += bits;
|
798
805
|
}
|
799
|
-
BROTLI_LOG_UINT(
|
806
|
+
BROTLI_LOG_UINT(h->symbol);
|
800
807
|
table_size = BrotliBuildSimpleHuffmanTable(
|
801
|
-
table, HUFFMAN_TABLE_BITS,
|
808
|
+
table, HUFFMAN_TABLE_BITS, h->symbols_lists_array, h->symbol);
|
802
809
|
if (opt_table_size) {
|
803
810
|
*opt_table_size = table_size;
|
804
811
|
}
|
805
|
-
|
812
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
806
813
|
return BROTLI_DECODER_SUCCESS;
|
807
814
|
}
|
808
815
|
|
@@ -813,44 +820,45 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
|
|
813
820
|
if (result != BROTLI_DECODER_SUCCESS) {
|
814
821
|
return result;
|
815
822
|
}
|
816
|
-
BrotliBuildCodeLengthsHuffmanTable(
|
817
|
-
|
818
|
-
|
819
|
-
memset(&
|
823
|
+
BrotliBuildCodeLengthsHuffmanTable(h->table,
|
824
|
+
h->code_length_code_lengths,
|
825
|
+
h->code_length_histo);
|
826
|
+
memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo));
|
820
827
|
for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {
|
821
|
-
|
822
|
-
|
828
|
+
h->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
|
829
|
+
h->symbol_lists[h->next_symbol[i]] = 0xFFFF;
|
823
830
|
}
|
824
831
|
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
832
|
+
h->symbol = 0;
|
833
|
+
h->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;
|
834
|
+
h->repeat = 0;
|
835
|
+
h->repeat_code_len = 0;
|
836
|
+
h->space = 32768;
|
837
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
|
831
838
|
}
|
832
839
|
/* Fall through. */
|
833
840
|
|
834
841
|
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
|
835
842
|
uint32_t table_size;
|
836
|
-
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
|
843
|
+
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
|
844
|
+
alphabet_size_limit, s);
|
837
845
|
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
838
|
-
result = SafeReadSymbolCodeLengths(
|
846
|
+
result = SafeReadSymbolCodeLengths(alphabet_size_limit, s);
|
839
847
|
}
|
840
848
|
if (result != BROTLI_DECODER_SUCCESS) {
|
841
849
|
return result;
|
842
850
|
}
|
843
851
|
|
844
|
-
if (
|
845
|
-
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)
|
852
|
+
if (h->space != 0) {
|
853
|
+
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)h->space));
|
846
854
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
|
847
855
|
}
|
848
856
|
table_size = BrotliBuildHuffmanTable(
|
849
|
-
table, HUFFMAN_TABLE_BITS,
|
857
|
+
table, HUFFMAN_TABLE_BITS, h->symbol_lists, h->code_length_histo);
|
850
858
|
if (opt_table_size) {
|
851
859
|
*opt_table_size = table_size;
|
852
860
|
}
|
853
|
-
|
861
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
854
862
|
return BROTLI_DECODER_SUCCESS;
|
855
863
|
}
|
856
864
|
|
@@ -867,8 +875,8 @@ static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
|
|
867
875
|
uint32_t code;
|
868
876
|
uint32_t nbits;
|
869
877
|
code = ReadSymbol(table, br);
|
870
|
-
nbits =
|
871
|
-
return
|
878
|
+
nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */
|
879
|
+
return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits);
|
872
880
|
}
|
873
881
|
|
874
882
|
/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
|
@@ -886,13 +894,14 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
|
886
894
|
}
|
887
895
|
{
|
888
896
|
uint32_t bits;
|
889
|
-
uint32_t nbits =
|
897
|
+
uint32_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
|
898
|
+
uint32_t offset = _kBrotliPrefixCodeRanges[index].offset;
|
890
899
|
if (!BrotliSafeReadBits(br, nbits, &bits)) {
|
891
900
|
s->block_length_index = index;
|
892
901
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
|
893
902
|
return BROTLI_FALSE;
|
894
903
|
}
|
895
|
-
*result =
|
904
|
+
*result = offset + bits;
|
896
905
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
|
897
906
|
return BROTLI_TRUE;
|
898
907
|
}
|
@@ -952,22 +961,22 @@ static BROTLI_NOINLINE void InverseMoveToFrontTransform(
|
|
952
961
|
/* Decodes a series of Huffman table using ReadHuffmanCode function. */
|
953
962
|
static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
954
963
|
HuffmanTreeGroup* group, BrotliDecoderState* s) {
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
964
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
965
|
+
if (h->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
|
966
|
+
h->next = group->codes;
|
967
|
+
h->htree_index = 0;
|
968
|
+
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
|
959
969
|
}
|
960
|
-
while (
|
970
|
+
while (h->htree_index < group->num_htrees) {
|
961
971
|
uint32_t table_size;
|
962
|
-
BrotliDecoderErrorCode result =
|
963
|
-
|
964
|
-
s->next, &table_size, s);
|
972
|
+
BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max,
|
973
|
+
group->alphabet_size_limit, h->next, &table_size, s);
|
965
974
|
if (result != BROTLI_DECODER_SUCCESS) return result;
|
966
|
-
group->htrees[
|
967
|
-
|
968
|
-
++
|
975
|
+
group->htrees[h->htree_index] = h->next;
|
976
|
+
h->next += table_size;
|
977
|
+
++h->htree_index;
|
969
978
|
}
|
970
|
-
|
979
|
+
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
|
971
980
|
return BROTLI_DECODER_SUCCESS;
|
972
981
|
}
|
973
982
|
|
@@ -985,15 +994,16 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
985
994
|
BrotliDecoderState* s) {
|
986
995
|
BrotliBitReader* br = &s->br;
|
987
996
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
997
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
988
998
|
|
989
|
-
switch ((int)
|
999
|
+
switch ((int)h->substate_context_map) {
|
990
1000
|
case BROTLI_STATE_CONTEXT_MAP_NONE:
|
991
1001
|
result = DecodeVarLenUint8(s, br, num_htrees);
|
992
1002
|
if (result != BROTLI_DECODER_SUCCESS) {
|
993
1003
|
return result;
|
994
1004
|
}
|
995
1005
|
(*num_htrees)++;
|
996
|
-
|
1006
|
+
h->context_index = 0;
|
997
1007
|
BROTLI_LOG_UINT(context_map_size);
|
998
1008
|
BROTLI_LOG_UINT(*num_htrees);
|
999
1009
|
*context_map_arg =
|
@@ -1005,7 +1015,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1005
1015
|
memset(*context_map_arg, 0, (size_t)context_map_size);
|
1006
1016
|
return BROTLI_DECODER_SUCCESS;
|
1007
1017
|
}
|
1008
|
-
|
1018
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
|
1009
1019
|
/* Fall through. */
|
1010
1020
|
|
1011
1021
|
case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
|
@@ -1016,38 +1026,38 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1016
1026
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1017
1027
|
}
|
1018
1028
|
if ((bits & 1) != 0) { /* Use RLE for zeros. */
|
1019
|
-
|
1029
|
+
h->max_run_length_prefix = (bits >> 1) + 1;
|
1020
1030
|
BrotliDropBits(br, 5);
|
1021
1031
|
} else {
|
1022
|
-
|
1032
|
+
h->max_run_length_prefix = 0;
|
1023
1033
|
BrotliDropBits(br, 1);
|
1024
1034
|
}
|
1025
|
-
BROTLI_LOG_UINT(
|
1026
|
-
|
1035
|
+
BROTLI_LOG_UINT(h->max_run_length_prefix);
|
1036
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
|
1027
1037
|
}
|
1028
1038
|
/* Fall through. */
|
1029
1039
|
|
1030
1040
|
case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {
|
1031
|
-
uint32_t alphabet_size = *num_htrees +
|
1041
|
+
uint32_t alphabet_size = *num_htrees + h->max_run_length_prefix;
|
1032
1042
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
1033
|
-
|
1043
|
+
h->context_map_table, NULL, s);
|
1034
1044
|
if (result != BROTLI_DECODER_SUCCESS) return result;
|
1035
|
-
|
1036
|
-
|
1045
|
+
h->code = 0xFFFF;
|
1046
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
|
1037
1047
|
}
|
1038
1048
|
/* Fall through. */
|
1039
1049
|
|
1040
1050
|
case BROTLI_STATE_CONTEXT_MAP_DECODE: {
|
1041
|
-
uint32_t context_index =
|
1042
|
-
uint32_t max_run_length_prefix =
|
1051
|
+
uint32_t context_index = h->context_index;
|
1052
|
+
uint32_t max_run_length_prefix = h->max_run_length_prefix;
|
1043
1053
|
uint8_t* context_map = *context_map_arg;
|
1044
|
-
uint32_t code =
|
1054
|
+
uint32_t code = h->code;
|
1045
1055
|
BROTLI_BOOL skip_preamble = (code != 0xFFFF);
|
1046
1056
|
while (context_index < context_map_size || skip_preamble) {
|
1047
1057
|
if (!skip_preamble) {
|
1048
|
-
if (!SafeReadSymbol(
|
1049
|
-
|
1050
|
-
|
1058
|
+
if (!SafeReadSymbol(h->context_map_table, br, &code)) {
|
1059
|
+
h->code = 0xFFFF;
|
1060
|
+
h->context_index = context_index;
|
1051
1061
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1052
1062
|
}
|
1053
1063
|
BROTLI_LOG_UINT(code);
|
@@ -1068,8 +1078,8 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1068
1078
|
{
|
1069
1079
|
uint32_t reps;
|
1070
1080
|
if (!BrotliSafeReadBits(br, code, &reps)) {
|
1071
|
-
|
1072
|
-
|
1081
|
+
h->code = code;
|
1082
|
+
h->context_index = context_index;
|
1073
1083
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1074
1084
|
}
|
1075
1085
|
reps += 1U << code;
|
@@ -1089,13 +1099,13 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1089
1099
|
case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
|
1090
1100
|
uint32_t bits;
|
1091
1101
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
1092
|
-
|
1102
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
|
1093
1103
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1094
1104
|
}
|
1095
1105
|
if (bits != 0) {
|
1096
1106
|
InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
|
1097
1107
|
}
|
1098
|
-
|
1108
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
|
1099
1109
|
return BROTLI_DECODER_SUCCESS;
|
1100
1110
|
}
|
1101
1111
|
|
@@ -1457,32 +1467,28 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
|
|
1457
1467
|
}
|
1458
1468
|
|
1459
1469
|
static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
|
1460
|
-
|
1461
|
-
|
1462
|
-
s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
|
1470
|
+
int offset = s->distance_code - 3;
|
1471
|
+
if (s->distance_code <= 3) {
|
1463
1472
|
/* Compensate double distance-ring-buffer roll for dictionary items. */
|
1464
|
-
s->distance_context = 1;
|
1473
|
+
s->distance_context = 1 >> s->distance_code;
|
1474
|
+
s->distance_code = s->dist_rb[(s->dist_rb_idx - offset) & 3];
|
1475
|
+
s->dist_rb_idx -= s->distance_context;
|
1465
1476
|
} else {
|
1466
|
-
int
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
-0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */
|
1472
|
-
const uint32_t kDistanceShortCodeValueOffset = 0xFA5FA500;
|
1473
|
-
int v = (s->dist_rb_idx +
|
1474
|
-
(int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;
|
1475
|
-
s->distance_code = s->dist_rb[v];
|
1476
|
-
v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3;
|
1477
|
-
if ((distance_code & 0x3) != 0) {
|
1478
|
-
s->distance_code += v;
|
1477
|
+
int index_delta = 3;
|
1478
|
+
int delta;
|
1479
|
+
int base = s->distance_code - 10;
|
1480
|
+
if (s->distance_code < 10) {
|
1481
|
+
base = s->distance_code - 4;
|
1479
1482
|
} else {
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1483
|
+
index_delta = 2;
|
1484
|
+
}
|
1485
|
+
/* Unpack one of six 4-bit values. */
|
1486
|
+
delta = ((0x605142 >> (4 * base)) & 0xF) - 3;
|
1487
|
+
s->distance_code = s->dist_rb[(s->dist_rb_idx + index_delta) & 0x3] + delta;
|
1488
|
+
if (s->distance_code <= 0) {
|
1489
|
+
/* A huge distance will cause a BROTLI_FAILURE() soon.
|
1490
|
+
This is a little faster than failing here. */
|
1491
|
+
s->distance_code = 0x7FFFFFFF;
|
1486
1492
|
}
|
1487
1493
|
}
|
1488
1494
|
}
|
@@ -1497,62 +1503,153 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
|
1497
1503
|
}
|
1498
1504
|
}
|
1499
1505
|
|
1506
|
+
static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
|
1507
|
+
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
1508
|
+
if (n_bits != 0) {
|
1509
|
+
return BrotliSafeReadBits32(br, n_bits, val);
|
1510
|
+
} else {
|
1511
|
+
*val = 0;
|
1512
|
+
return BROTLI_TRUE;
|
1513
|
+
}
|
1514
|
+
}
|
1515
|
+
|
1516
|
+
/*
|
1517
|
+
RFC 7932 Section 4 with "..." shortenings and "[]" emendations.
|
1518
|
+
|
1519
|
+
Each distance ... is represented with a pair <distance code, extra bits>...
|
1520
|
+
The distance code is encoded using a prefix code... The number of extra bits
|
1521
|
+
can be 0..24... Two additional parameters: NPOSTFIX (0..3), and ...
|
1522
|
+
NDIRECT (0..120) ... are encoded in the meta-block header...
|
1523
|
+
|
1524
|
+
The first 16 distance symbols ... reference past distances... ring buffer ...
|
1525
|
+
Next NDIRECT distance symbols ... represent distances from 1 to NDIRECT...
|
1526
|
+
[For] distance symbols 16 + NDIRECT and greater ... the number of extra bits
|
1527
|
+
... is given by the following formula:
|
1528
|
+
|
1529
|
+
[ xcode = dcode - NDIRECT - 16 ]
|
1530
|
+
ndistbits = 1 + [ xcode ] >> (NPOSTFIX + 1)
|
1531
|
+
|
1532
|
+
...
|
1533
|
+
*/
|
1534
|
+
|
1535
|
+
/*
|
1536
|
+
RFC 7932 Section 9.2 with "..." shortenings and "[]" emendations.
|
1537
|
+
|
1538
|
+
... to get the actual value of the parameter NDIRECT, left-shift this
|
1539
|
+
four-bit number by NPOSTFIX bits ...
|
1540
|
+
*/
|
1541
|
+
|
1542
|
+
/* Remaining formulas from RFC 7932 Section 4 could be rewritten as following:
|
1543
|
+
|
1544
|
+
alphabet_size = 16 + NDIRECT + (max_distbits << (NPOSTFIX + 1))
|
1545
|
+
|
1546
|
+
half = ((xcode >> NPOSTFIX) & 1) << ndistbits
|
1547
|
+
postfix = xcode & ((1 << NPOSTFIX) - 1)
|
1548
|
+
range_start = 2 * (1 << ndistbits - 1 - 1)
|
1549
|
+
|
1550
|
+
distance = (range_start + half + extra) << NPOSTFIX + postfix + NDIRECT + 1
|
1551
|
+
|
1552
|
+
NB: ndistbits >= 1 -> range_start >= 0
|
1553
|
+
NB: range_start has factor 2, as the range is covered by 2 "halves"
|
1554
|
+
NB: extra -1 offset in range_start formula covers the absence of
|
1555
|
+
ndistbits = 0 case
|
1556
|
+
NB: when NPOSTFIX = 0, NDIRECT is not greater than 15
|
1557
|
+
|
1558
|
+
In other words, xcode has the following binary structure - XXXHPPP:
|
1559
|
+
- XXX represent the number of extra distance bits
|
1560
|
+
- H selects upper / lower range of distances
|
1561
|
+
- PPP represent "postfix"
|
1562
|
+
|
1563
|
+
"Regular" distance encoding has NPOSTFIX = 0; omitting the postfix part
|
1564
|
+
simplifies distance calculation.
|
1565
|
+
|
1566
|
+
Using NPOSTFIX > 0 allows cheaper encoding of regular structures, e.g. where
|
1567
|
+
most of distances have the same reminder of division by 2/4/8. For example,
|
1568
|
+
the table of int32_t values that come from different sources; if it is likely
|
1569
|
+
that 3 highest bytes of values from the same source are the same, then
|
1570
|
+
copy distance often looks like 4x + y.
|
1571
|
+
|
1572
|
+
Distance calculation could be rewritten to:
|
1573
|
+
|
1574
|
+
ndistbits = NDISTBITS(NDIRECT, NPOSTFIX)[dcode]
|
1575
|
+
distance = OFFSET(NDIRECT, NPOSTFIX)[dcode] + extra << NPOSTFIX
|
1576
|
+
|
1577
|
+
NDISTBITS and OFFSET could be pre-calculated, as NDIRECT and NPOSTFIX could
|
1578
|
+
change only once per meta-block.
|
1579
|
+
*/
|
1580
|
+
|
1581
|
+
/* Calculates distance lookup table.
|
1582
|
+
NB: it is possible to have all 64 tables precalculated. */
|
1583
|
+
static void CalculateDistanceLut(BrotliDecoderState* s) {
|
1584
|
+
BrotliMetablockBodyArena* b = &s->arena.body;
|
1585
|
+
uint32_t npostfix = s->distance_postfix_bits;
|
1586
|
+
uint32_t ndirect = s->num_direct_distance_codes;
|
1587
|
+
uint32_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
|
1588
|
+
uint32_t postfix = 1u << npostfix;
|
1589
|
+
uint32_t j;
|
1590
|
+
uint32_t bits = 1;
|
1591
|
+
uint32_t half = 0;
|
1592
|
+
|
1593
|
+
/* Skip short codes. */
|
1594
|
+
uint32_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
|
1595
|
+
|
1596
|
+
/* Fill direct codes. */
|
1597
|
+
for (j = 0; j < ndirect; ++j) {
|
1598
|
+
b->dist_extra_bits[i] = 0;
|
1599
|
+
b->dist_offset[i] = j + 1;
|
1600
|
+
++i;
|
1601
|
+
}
|
1602
|
+
|
1603
|
+
/* Fill regular distance codes. */
|
1604
|
+
while (i < alphabet_size_limit) {
|
1605
|
+
uint32_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
|
1606
|
+
/* Always fill the complete group. */
|
1607
|
+
for (j = 0; j < postfix; ++j) {
|
1608
|
+
b->dist_extra_bits[i] = (uint8_t)bits;
|
1609
|
+
b->dist_offset[i] = base + j;
|
1610
|
+
++i;
|
1611
|
+
}
|
1612
|
+
bits = bits + half;
|
1613
|
+
half = half ^ 1;
|
1614
|
+
}
|
1615
|
+
}
|
1616
|
+
|
1500
1617
|
/* Precondition: s->distance_code < 0. */
|
1501
1618
|
static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
|
1502
1619
|
int safe, BrotliDecoderState* s, BrotliBitReader* br) {
|
1503
|
-
|
1620
|
+
BrotliMetablockBodyArena* b = &s->arena.body;
|
1621
|
+
uint32_t code;
|
1622
|
+
uint32_t bits;
|
1504
1623
|
BrotliBitReaderState memento;
|
1505
1624
|
HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
|
1506
1625
|
if (!safe) {
|
1507
|
-
|
1626
|
+
code = ReadSymbol(distance_tree, br);
|
1508
1627
|
} else {
|
1509
|
-
uint32_t code;
|
1510
1628
|
BrotliBitReaderSaveState(br, &memento);
|
1511
1629
|
if (!SafeReadSymbol(distance_tree, br, &code)) {
|
1512
1630
|
return BROTLI_FALSE;
|
1513
1631
|
}
|
1514
|
-
s->distance_code = (int)code;
|
1515
1632
|
}
|
1633
|
+
--s->block_length[2];
|
1516
1634
|
/* Convert the distance code to the actual distance by possibly
|
1517
|
-
looking up past distances from the s->
|
1635
|
+
looking up past distances from the s->dist_rb. */
|
1518
1636
|
s->distance_context = 0;
|
1519
|
-
if ((
|
1637
|
+
if ((code & ~0xFu) == 0) {
|
1638
|
+
s->distance_code = (int)code;
|
1520
1639
|
TakeDistanceFromRingBuffer(s);
|
1521
|
-
--s->block_length[2];
|
1522
1640
|
return BROTLI_TRUE;
|
1523
1641
|
}
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
offset = ((2 + (distval & 1)) << nbits) - 4;
|
1532
|
-
s->distance_code = (int)s->num_direct_distance_codes + offset +
|
1533
|
-
(int)BrotliReadBits(br, nbits);
|
1534
|
-
} else {
|
1535
|
-
/* This branch also works well when s->distance_postfix_bits == 0. */
|
1536
|
-
uint32_t bits;
|
1537
|
-
postfix = distval & s->distance_postfix_mask;
|
1538
|
-
distval >>= s->distance_postfix_bits;
|
1539
|
-
nbits = ((uint32_t)distval >> 1) + 1;
|
1540
|
-
if (safe) {
|
1541
|
-
if (!SafeReadBits(br, nbits, &bits)) {
|
1542
|
-
s->distance_code = -1; /* Restore precondition. */
|
1543
|
-
BrotliBitReaderRestoreState(br, &memento);
|
1544
|
-
return BROTLI_FALSE;
|
1545
|
-
}
|
1546
|
-
} else {
|
1547
|
-
bits = BrotliReadBits(br, nbits);
|
1548
|
-
}
|
1549
|
-
offset = ((2 + (distval & 1)) << nbits) - 4;
|
1550
|
-
s->distance_code = (int)s->num_direct_distance_codes +
|
1551
|
-
((offset + (int)bits) << s->distance_postfix_bits) + postfix;
|
1642
|
+
if (!safe) {
|
1643
|
+
bits = BrotliReadBits32(br, b->dist_extra_bits[code]);
|
1644
|
+
} else {
|
1645
|
+
if (!SafeReadBits32(br, b->dist_extra_bits[code], &bits)) {
|
1646
|
+
++s->block_length[2];
|
1647
|
+
BrotliBitReaderRestoreState(br, &memento);
|
1648
|
+
return BROTLI_FALSE;
|
1552
1649
|
}
|
1553
1650
|
}
|
1554
|
-
s->distance_code =
|
1555
|
-
|
1651
|
+
s->distance_code =
|
1652
|
+
(int)(b->dist_offset[code] + (bits << s->distance_postfix_bits));
|
1556
1653
|
return BROTLI_TRUE;
|
1557
1654
|
}
|
1558
1655
|
|
@@ -1588,9 +1685,9 @@ static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
|
|
1588
1685
|
*insert_length = v.insert_len_offset;
|
1589
1686
|
if (!safe) {
|
1590
1687
|
if (BROTLI_PREDICT_FALSE(v.insert_len_extra_bits != 0)) {
|
1591
|
-
insert_len_extra =
|
1688
|
+
insert_len_extra = BrotliReadBits24(br, v.insert_len_extra_bits);
|
1592
1689
|
}
|
1593
|
-
copy_length =
|
1690
|
+
copy_length = BrotliReadBits24(br, v.copy_len_extra_bits);
|
1594
1691
|
} else {
|
1595
1692
|
if (!SafeReadBits(br, v.insert_len_extra_bits, &insert_len_extra) ||
|
1596
1693
|
!SafeReadBits(br, v.copy_len_extra_bits, ©_length)) {
|
@@ -1935,21 +2032,6 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands(
|
|
1935
2032
|
return ProcessCommandsInternal(1, s);
|
1936
2033
|
}
|
1937
2034
|
|
1938
|
-
/* Returns the maximum number of distance symbols which can only represent
|
1939
|
-
distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */
|
1940
|
-
static uint32_t BrotliMaxDistanceSymbol(uint32_t ndirect, uint32_t npostfix) {
|
1941
|
-
static const uint32_t bound[BROTLI_MAX_NPOSTFIX + 1] = {0, 4, 12, 28};
|
1942
|
-
static const uint32_t diff[BROTLI_MAX_NPOSTFIX + 1] = {73, 126, 228, 424};
|
1943
|
-
uint32_t postfix = 1U << npostfix;
|
1944
|
-
if (ndirect < bound[npostfix]) {
|
1945
|
-
return ndirect + diff[npostfix] + postfix;
|
1946
|
-
} else if (ndirect > bound[npostfix] + postfix) {
|
1947
|
-
return ndirect + diff[npostfix];
|
1948
|
-
} else {
|
1949
|
-
return bound[npostfix] + diff[npostfix] + postfix;
|
1950
|
-
}
|
1951
|
-
}
|
1952
|
-
|
1953
2035
|
BrotliDecoderResult BrotliDecoderDecompress(
|
1954
2036
|
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
|
1955
2037
|
uint8_t* decoded_buffer) {
|
@@ -2167,33 +2249,23 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2167
2249
|
s->state = BROTLI_STATE_UNCOMPRESSED;
|
2168
2250
|
break;
|
2169
2251
|
}
|
2252
|
+
s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER;
|
2253
|
+
/* Fall through. */
|
2254
|
+
|
2255
|
+
case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER: {
|
2256
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
2170
2257
|
s->loop_counter = 0;
|
2258
|
+
/* Initialize compressed metablock header arena. */
|
2259
|
+
h->sub_loop_counter = 0;
|
2260
|
+
/* Make small negative indexes addressable. */
|
2261
|
+
h->symbol_lists =
|
2262
|
+
&h->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
|
2263
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
2264
|
+
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
|
2265
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
|
2171
2266
|
s->state = BROTLI_STATE_HUFFMAN_CODE_0;
|
2172
|
-
break;
|
2173
|
-
|
2174
|
-
case BROTLI_STATE_UNCOMPRESSED: {
|
2175
|
-
result = CopyUncompressedBlockToOutput(
|
2176
|
-
available_out, next_out, total_out, s);
|
2177
|
-
if (result != BROTLI_DECODER_SUCCESS) {
|
2178
|
-
break;
|
2179
|
-
}
|
2180
|
-
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2181
|
-
break;
|
2182
2267
|
}
|
2183
|
-
|
2184
|
-
case BROTLI_STATE_METADATA:
|
2185
|
-
for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
|
2186
|
-
uint32_t bits;
|
2187
|
-
/* Read one byte and ignore it. */
|
2188
|
-
if (!BrotliSafeReadBits(br, 8, &bits)) {
|
2189
|
-
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2190
|
-
break;
|
2191
|
-
}
|
2192
|
-
}
|
2193
|
-
if (result == BROTLI_DECODER_SUCCESS) {
|
2194
|
-
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2195
|
-
}
|
2196
|
-
break;
|
2268
|
+
/* Fall through. */
|
2197
2269
|
|
2198
2270
|
case BROTLI_STATE_HUFFMAN_CODE_0:
|
2199
2271
|
if (s->loop_counter >= 3) {
|
@@ -2247,6 +2319,30 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2247
2319
|
break;
|
2248
2320
|
}
|
2249
2321
|
|
2322
|
+
case BROTLI_STATE_UNCOMPRESSED: {
|
2323
|
+
result = CopyUncompressedBlockToOutput(
|
2324
|
+
available_out, next_out, total_out, s);
|
2325
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
2326
|
+
break;
|
2327
|
+
}
|
2328
|
+
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2329
|
+
break;
|
2330
|
+
}
|
2331
|
+
|
2332
|
+
case BROTLI_STATE_METADATA:
|
2333
|
+
for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
|
2334
|
+
uint32_t bits;
|
2335
|
+
/* Read one byte and ignore it. */
|
2336
|
+
if (!BrotliSafeReadBits(br, 8, &bits)) {
|
2337
|
+
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2338
|
+
break;
|
2339
|
+
}
|
2340
|
+
}
|
2341
|
+
if (result == BROTLI_DECODER_SUCCESS) {
|
2342
|
+
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2343
|
+
}
|
2344
|
+
break;
|
2345
|
+
|
2250
2346
|
case BROTLI_STATE_METABLOCK_HEADER_2: {
|
2251
2347
|
uint32_t bits;
|
2252
2348
|
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
@@ -2255,11 +2351,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2255
2351
|
}
|
2256
2352
|
s->distance_postfix_bits = bits & BitMask(2);
|
2257
2353
|
bits >>= 2;
|
2258
|
-
s->num_direct_distance_codes =
|
2259
|
-
(bits << s->distance_postfix_bits);
|
2354
|
+
s->num_direct_distance_codes = bits << s->distance_postfix_bits;
|
2260
2355
|
BROTLI_LOG_UINT(s->num_direct_distance_codes);
|
2261
2356
|
BROTLI_LOG_UINT(s->distance_postfix_bits);
|
2262
|
-
s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
|
2263
2357
|
s->context_modes =
|
2264
2358
|
(uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)s->num_block_types[0]);
|
2265
2359
|
if (s->context_modes == 0) {
|
@@ -2291,17 +2385,19 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2291
2385
|
/* Fall through. */
|
2292
2386
|
|
2293
2387
|
case BROTLI_STATE_CONTEXT_MAP_2: {
|
2294
|
-
uint32_t
|
2295
|
-
|
2296
|
-
uint32_t
|
2297
|
-
|
2298
|
-
|
2299
|
-
BROTLI_MAX_DISTANCE_BITS));
|
2300
|
-
uint32_t max_distance_symbol = (s->large_window ?
|
2301
|
-
BrotliMaxDistanceSymbol(
|
2302
|
-
num_direct_codes, s->distance_postfix_bits) :
|
2303
|
-
num_distance_codes);
|
2388
|
+
uint32_t npostfix = s->distance_postfix_bits;
|
2389
|
+
uint32_t ndirect = s->num_direct_distance_codes;
|
2390
|
+
uint32_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
2391
|
+
npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
|
2392
|
+
uint32_t distance_alphabet_size_limit = distance_alphabet_size_max;
|
2304
2393
|
BROTLI_BOOL allocation_success = BROTLI_TRUE;
|
2394
|
+
if (s->large_window) {
|
2395
|
+
BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
|
2396
|
+
BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect);
|
2397
|
+
distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
2398
|
+
npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
|
2399
|
+
distance_alphabet_size_limit = limit.max_alphabet_size;
|
2400
|
+
}
|
2305
2401
|
result = DecodeContextMap(
|
2306
2402
|
s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS,
|
2307
2403
|
&s->num_dist_htrees, &s->dist_context_map, s);
|
@@ -2315,8 +2411,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2315
2411
|
s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS,
|
2316
2412
|
BROTLI_NUM_COMMAND_SYMBOLS, s->num_block_types[1]);
|
2317
2413
|
allocation_success &= BrotliDecoderHuffmanTreeGroupInit(
|
2318
|
-
s, &s->distance_hgroup,
|
2319
|
-
|
2414
|
+
s, &s->distance_hgroup, distance_alphabet_size_max,
|
2415
|
+
distance_alphabet_size_limit, s->num_dist_htrees);
|
2320
2416
|
if (!allocation_success) {
|
2321
2417
|
return SaveErrorCode(s,
|
2322
2418
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
|
@@ -2338,18 +2434,24 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2338
2434
|
result = HuffmanTreeGroupDecode(hgroup, s);
|
2339
2435
|
if (result != BROTLI_DECODER_SUCCESS) break;
|
2340
2436
|
s->loop_counter++;
|
2341
|
-
if (s->loop_counter
|
2342
|
-
|
2343
|
-
s->dist_context_map_slice = s->dist_context_map;
|
2344
|
-
s->htree_command = s->insert_copy_hgroup.htrees[0];
|
2345
|
-
if (!BrotliEnsureRingBuffer(s)) {
|
2346
|
-
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
|
2347
|
-
break;
|
2348
|
-
}
|
2349
|
-
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
2437
|
+
if (s->loop_counter < 3) {
|
2438
|
+
break;
|
2350
2439
|
}
|
2351
|
-
|
2440
|
+
s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY;
|
2352
2441
|
}
|
2442
|
+
/* Fall through. */
|
2443
|
+
|
2444
|
+
case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY:
|
2445
|
+
PrepareLiteralDecoding(s);
|
2446
|
+
s->dist_context_map_slice = s->dist_context_map;
|
2447
|
+
s->htree_command = s->insert_copy_hgroup.htrees[0];
|
2448
|
+
if (!BrotliEnsureRingBuffer(s)) {
|
2449
|
+
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
|
2450
|
+
break;
|
2451
|
+
}
|
2452
|
+
CalculateDistanceLut(s);
|
2453
|
+
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
2454
|
+
/* Fall through. */
|
2353
2455
|
|
2354
2456
|
case BROTLI_STATE_COMMAND_BEGIN:
|
2355
2457
|
/* Fall through. */
|