brotli 0.2.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +37 -0
- data/.github/workflows/publish.yml +24 -0
- data/.gitmodules +1 -1
- data/Gemfile +6 -3
- data/README.md +2 -2
- data/Rakefile +16 -9
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +210 -31
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +25 -17
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +107 -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 +137 -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 +14 -3
- data/vendor/brotli/c/common/platform.c +23 -0
- data/vendor/brotli/c/common/platform.h +95 -122
- data/vendor/brotli/c/common/shared_dictionary.c +521 -0
- data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
- data/vendor/brotli/c/common/transform.c +60 -4
- data/vendor/brotli/c/common/transform.h +5 -0
- data/vendor/brotli/c/common/version.h +31 -6
- data/vendor/brotli/c/dec/bit_reader.c +34 -4
- data/vendor/brotli/c/dec/bit_reader.h +221 -107
- data/vendor/brotli/c/dec/decode.c +772 -403
- data/vendor/brotli/c/dec/huffman.c +7 -4
- data/vendor/brotli/c/dec/huffman.h +8 -13
- data/vendor/brotli/c/dec/prefix.h +1 -18
- data/vendor/brotli/c/dec/state.c +40 -21
- data/vendor/brotli/c/dec/state.h +201 -59
- data/vendor/brotli/c/enc/backward_references.c +88 -25
- data/vendor/brotli/c/enc/backward_references.h +10 -8
- data/vendor/brotli/c/enc/backward_references_hq.c +194 -80
- data/vendor/brotli/c/enc/backward_references_hq.h +17 -13
- data/vendor/brotli/c/enc/backward_references_inc.h +52 -16
- data/vendor/brotli/c/enc/bit_cost.c +8 -7
- data/vendor/brotli/c/enc/bit_cost.h +5 -4
- data/vendor/brotli/c/enc/block_splitter.c +40 -17
- data/vendor/brotli/c/enc/block_splitter.h +5 -4
- data/vendor/brotli/c/enc/block_splitter_inc.h +99 -49
- data/vendor/brotli/c/enc/brotli_bit_stream.c +142 -137
- data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
- data/vendor/brotli/c/enc/cluster.c +10 -9
- data/vendor/brotli/c/enc/cluster.h +7 -6
- data/vendor/brotli/c/enc/cluster_inc.h +30 -22
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +17 -16
- data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
- data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
- data/vendor/brotli/c/enc/compress_fragment.c +93 -83
- data/vendor/brotli/c/enc/compress_fragment.h +32 -7
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +100 -88
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +1829 -1101
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +550 -416
- data/vendor/brotli/c/enc/encoder_dict.c +613 -5
- data/vendor/brotli/c/enc/encoder_dict.h +120 -4
- data/vendor/brotli/c/enc/entropy_encode.c +5 -2
- data/vendor/brotli/c/enc/entropy_encode.h +4 -3
- data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +21 -101
- data/vendor/brotli/c/enc/find_match_length.h +17 -25
- data/vendor/brotli/c/enc/hash.h +350 -120
- data/vendor/brotli/c/enc/hash_composite_inc.h +71 -67
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +92 -51
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +79 -84
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -54
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +93 -62
- data/vendor/brotli/c/enc/hash_rolling_inc.h +25 -29
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +42 -40
- data/vendor/brotli/c/enc/histogram.c +4 -4
- data/vendor/brotli/c/enc/histogram.h +7 -6
- data/vendor/brotli/c/enc/literal_cost.c +20 -15
- data/vendor/brotli/c/enc/literal_cost.h +4 -2
- data/vendor/brotli/c/enc/memory.c +29 -5
- data/vendor/brotli/c/enc/memory.h +43 -14
- data/vendor/brotli/c/enc/metablock.c +95 -85
- data/vendor/brotli/c/enc/metablock.h +9 -8
- data/vendor/brotli/c/enc/metablock_inc.h +9 -7
- data/vendor/brotli/c/enc/params.h +7 -4
- data/vendor/brotli/c/enc/prefix.h +3 -2
- data/vendor/brotli/c/enc/quality.h +40 -3
- data/vendor/brotli/c/enc/ringbuffer.h +8 -4
- data/vendor/brotli/c/enc/state.h +104 -0
- data/vendor/brotli/c/enc/static_dict.c +60 -4
- data/vendor/brotli/c/enc/static_dict.h +3 -2
- data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
- data/vendor/brotli/c/enc/utf8_util.c +2 -2
- data/vendor/brotli/c/enc/utf8_util.h +2 -1
- data/vendor/brotli/c/enc/write_bits.h +29 -26
- data/vendor/brotli/c/include/brotli/decode.h +67 -2
- data/vendor/brotli/c/include/brotli/encode.h +77 -3
- data/vendor/brotli/c/include/brotli/port.h +34 -3
- data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
- metadata +23 -97
- data/.travis.yml +0 -31
- data/docs/Brotli/Error.html +0 -124
- data/docs/Brotli.html +0 -485
- 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
@@ -13,12 +13,13 @@
|
|
13
13
|
#include "../common/context.h"
|
14
14
|
#include "../common/dictionary.h"
|
15
15
|
#include "../common/platform.h"
|
16
|
+
#include "../common/shared_dictionary_internal.h"
|
16
17
|
#include "../common/transform.h"
|
17
18
|
#include "../common/version.h"
|
18
|
-
#include "
|
19
|
-
#include "
|
20
|
-
#include "
|
21
|
-
#include "
|
19
|
+
#include "bit_reader.h"
|
20
|
+
#include "huffman.h"
|
21
|
+
#include "prefix.h"
|
22
|
+
#include "state.h"
|
22
23
|
|
23
24
|
#if defined(BROTLI_TARGET_NEON)
|
24
25
|
#include <arm_neon.h>
|
@@ -41,8 +42,9 @@ extern "C" {
|
|
41
42
|
|
42
43
|
/* We need the slack region for the following reasons:
|
43
44
|
- doing up to two 16-byte copies for fast backward copying
|
44
|
-
- inserting transformed dictionary word
|
45
|
-
|
45
|
+
- inserting transformed dictionary word:
|
46
|
+
255 prefix + 32 base + 255 suffix */
|
47
|
+
static const brotli_reg_t kRingBufferWriteAheadSlack = 542;
|
46
48
|
|
47
49
|
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
|
48
50
|
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
@@ -111,8 +113,13 @@ void BrotliDecoderDestroyInstance(BrotliDecoderState* state) {
|
|
111
113
|
|
112
114
|
/* Saves error code and converts it to BrotliDecoderResult. */
|
113
115
|
static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
114
|
-
BrotliDecoderState* s, BrotliDecoderErrorCode e) {
|
116
|
+
BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) {
|
115
117
|
s->error_code = (int)e;
|
118
|
+
s->used_input += consumed_input;
|
119
|
+
if ((s->buffer_length != 0) && (s->br.next_in == s->br.last_in)) {
|
120
|
+
/* If internal buffer is depleted at last, reset it. */
|
121
|
+
s->buffer_length = 0;
|
122
|
+
}
|
116
123
|
switch (e) {
|
117
124
|
case BROTLI_DECODER_SUCCESS:
|
118
125
|
return BROTLI_DECODER_RESULT_SUCCESS;
|
@@ -132,7 +139,7 @@ static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
|
132
139
|
Precondition: bit-reader accumulator has at least 8 bits. */
|
133
140
|
static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
134
141
|
BrotliBitReader* br) {
|
135
|
-
|
142
|
+
brotli_reg_t n;
|
136
143
|
BROTLI_BOOL large_window = s->large_window;
|
137
144
|
s->large_window = BROTLI_FALSE;
|
138
145
|
BrotliTakeBits(br, 1, &n);
|
@@ -142,7 +149,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
|
142
149
|
}
|
143
150
|
BrotliTakeBits(br, 3, &n);
|
144
151
|
if (n != 0) {
|
145
|
-
s->window_bits =
|
152
|
+
s->window_bits = (17u + n) & 63u;
|
146
153
|
return BROTLI_DECODER_SUCCESS;
|
147
154
|
}
|
148
155
|
BrotliTakeBits(br, 3, &n);
|
@@ -159,7 +166,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
|
159
166
|
}
|
160
167
|
}
|
161
168
|
if (n != 0) {
|
162
|
-
s->window_bits =
|
169
|
+
s->window_bits = (8u + n) & 63u;
|
163
170
|
return BROTLI_DECODER_SUCCESS;
|
164
171
|
}
|
165
172
|
s->window_bits = 17;
|
@@ -178,8 +185,8 @@ static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
|
|
178
185
|
|
179
186
|
/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
|
180
187
|
static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
181
|
-
BrotliDecoderState* s, BrotliBitReader* br,
|
182
|
-
|
188
|
+
BrotliDecoderState* s, BrotliBitReader* br, brotli_reg_t* value) {
|
189
|
+
brotli_reg_t bits;
|
183
190
|
switch (s->substate_decode_uint8) {
|
184
191
|
case BROTLI_STATE_DECODE_UINT8_NONE:
|
185
192
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
|
@@ -216,14 +223,14 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
|
216
223
|
|
217
224
|
default:
|
218
225
|
return
|
219
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
226
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
220
227
|
}
|
221
228
|
}
|
222
229
|
|
223
230
|
/* Decodes a metablock length and flags by reading 2 - 31 bits. */
|
224
231
|
static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
225
232
|
BrotliDecoderState* s, BrotliBitReader* br) {
|
226
|
-
|
233
|
+
brotli_reg_t bits;
|
227
234
|
int i;
|
228
235
|
for (;;) {
|
229
236
|
switch (s->substate_metablock_header) {
|
@@ -274,7 +281,8 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
274
281
|
s->loop_counter = i;
|
275
282
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
276
283
|
}
|
277
|
-
if (i + 1 == s->size_nibbles && s->size_nibbles > 4 &&
|
284
|
+
if (i + 1 == (int)s->size_nibbles && s->size_nibbles > 4 &&
|
285
|
+
bits == 0) {
|
278
286
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE);
|
279
287
|
}
|
280
288
|
s->meta_block_remaining_len |= (int)(bits << (i * 4));
|
@@ -323,7 +331,8 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
323
331
|
s->loop_counter = i;
|
324
332
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
325
333
|
}
|
326
|
-
if (i + 1 == s->size_nibbles && s->size_nibbles > 1 &&
|
334
|
+
if (i + 1 == (int)s->size_nibbles && s->size_nibbles > 1 &&
|
335
|
+
bits == 0) {
|
327
336
|
return BROTLI_FAILURE(
|
328
337
|
BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
|
329
338
|
}
|
@@ -335,7 +344,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
335
344
|
|
336
345
|
default:
|
337
346
|
return
|
338
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
347
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
339
348
|
}
|
340
349
|
}
|
341
350
|
}
|
@@ -344,13 +353,13 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
344
353
|
This method doesn't read data from the bit reader, BUT drops the amount of
|
345
354
|
bits that correspond to the decoded symbol.
|
346
355
|
bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
|
347
|
-
static BROTLI_INLINE
|
348
|
-
|
349
|
-
|
356
|
+
static BROTLI_INLINE brotli_reg_t DecodeSymbol(brotli_reg_t bits,
|
357
|
+
const HuffmanCode* table,
|
358
|
+
BrotliBitReader* br) {
|
350
359
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
351
360
|
BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK);
|
352
361
|
if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) {
|
353
|
-
|
362
|
+
brotli_reg_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
|
354
363
|
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
355
364
|
BROTLI_HC_ADJUST_TABLE_INDEX(table,
|
356
365
|
BROTLI_HC_FAST_LOAD_VALUE(table) +
|
@@ -362,17 +371,17 @@ static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
|
|
362
371
|
|
363
372
|
/* Reads and decodes the next Huffman code from bit-stream.
|
364
373
|
This method peeks 16 bits of input and drops 0 - 15 of them. */
|
365
|
-
static BROTLI_INLINE
|
366
|
-
|
374
|
+
static BROTLI_INLINE brotli_reg_t ReadSymbol(const HuffmanCode* table,
|
375
|
+
BrotliBitReader* br) {
|
367
376
|
return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br);
|
368
377
|
}
|
369
378
|
|
370
379
|
/* Same as DecodeSymbol, but it is known that there is less than 15 bits of
|
371
380
|
input are currently available. */
|
372
381
|
static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
373
|
-
const HuffmanCode* table, BrotliBitReader* br,
|
374
|
-
|
375
|
-
|
382
|
+
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
383
|
+
brotli_reg_t val;
|
384
|
+
brotli_reg_t available_bits = BrotliGetAvailableBits(br);
|
376
385
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
377
386
|
if (available_bits == 0) {
|
378
387
|
if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) {
|
@@ -381,7 +390,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
381
390
|
}
|
382
391
|
return BROTLI_FALSE; /* No valid bits at all. */
|
383
392
|
}
|
384
|
-
val =
|
393
|
+
val = BrotliGetBitsUnmasked(br);
|
385
394
|
BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK);
|
386
395
|
if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) {
|
387
396
|
if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) {
|
@@ -410,8 +419,8 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
410
419
|
}
|
411
420
|
|
412
421
|
static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
413
|
-
const HuffmanCode* table, BrotliBitReader* br,
|
414
|
-
|
422
|
+
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
423
|
+
brotli_reg_t val;
|
415
424
|
if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
|
416
425
|
*result = DecodeSymbol(val, table, br);
|
417
426
|
return BROTLI_TRUE;
|
@@ -423,8 +432,8 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
|
423
432
|
static BROTLI_INLINE void PreloadSymbol(int safe,
|
424
433
|
const HuffmanCode* table,
|
425
434
|
BrotliBitReader* br,
|
426
|
-
|
427
|
-
|
435
|
+
brotli_reg_t* bits,
|
436
|
+
brotli_reg_t* value) {
|
428
437
|
if (safe) {
|
429
438
|
return;
|
430
439
|
}
|
@@ -436,15 +445,15 @@ static BROTLI_INLINE void PreloadSymbol(int safe,
|
|
436
445
|
|
437
446
|
/* Decodes the next Huffman code using data prepared by PreloadSymbol.
|
438
447
|
Reads 0 - 15 bits. Also peeks 8 following bits. */
|
439
|
-
static BROTLI_INLINE
|
448
|
+
static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
|
440
449
|
BrotliBitReader* br,
|
441
|
-
|
442
|
-
|
443
|
-
|
450
|
+
brotli_reg_t* bits,
|
451
|
+
brotli_reg_t* value) {
|
452
|
+
brotli_reg_t result = *value;
|
444
453
|
if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
|
445
|
-
|
454
|
+
brotli_reg_t val = BrotliGet16BitsUnmasked(br);
|
446
455
|
const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
|
447
|
-
|
456
|
+
brotli_reg_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
|
448
457
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext);
|
449
458
|
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
450
459
|
BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask);
|
@@ -457,8 +466,8 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
|
|
457
466
|
return result;
|
458
467
|
}
|
459
468
|
|
460
|
-
static BROTLI_INLINE
|
461
|
-
|
469
|
+
static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) {
|
470
|
+
brotli_reg_t result = 0;
|
462
471
|
while (x) {
|
463
472
|
x >>= 1;
|
464
473
|
++result;
|
@@ -470,32 +479,34 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
|
|
470
479
|
Totally 1..4 symbols are read, 1..11 bits each.
|
471
480
|
The list of symbols MUST NOT contain duplicates. */
|
472
481
|
static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
473
|
-
|
482
|
+
brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
|
483
|
+
BrotliDecoderState* s) {
|
474
484
|
/* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */
|
475
485
|
BrotliBitReader* br = &s->br;
|
476
|
-
|
477
|
-
|
478
|
-
|
486
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
487
|
+
brotli_reg_t max_bits = Log2Floor(alphabet_size_max - 1);
|
488
|
+
brotli_reg_t i = h->sub_loop_counter;
|
489
|
+
brotli_reg_t num_symbols = h->symbol;
|
479
490
|
while (i <= num_symbols) {
|
480
|
-
|
491
|
+
brotli_reg_t v;
|
481
492
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
|
482
|
-
|
483
|
-
|
493
|
+
h->sub_loop_counter = i;
|
494
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
|
484
495
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
485
496
|
}
|
486
|
-
if (v >=
|
497
|
+
if (v >= alphabet_size_limit) {
|
487
498
|
return
|
488
499
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
|
489
500
|
}
|
490
|
-
|
491
|
-
BROTLI_LOG_UINT(
|
501
|
+
h->symbols_lists_array[i] = (uint16_t)v;
|
502
|
+
BROTLI_LOG_UINT(h->symbols_lists_array[i]);
|
492
503
|
++i;
|
493
504
|
}
|
494
505
|
|
495
506
|
for (i = 0; i < num_symbols; ++i) {
|
496
|
-
|
507
|
+
brotli_reg_t k = i + 1;
|
497
508
|
for (; k <= num_symbols; ++k) {
|
498
|
-
if (
|
509
|
+
if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) {
|
499
510
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
|
500
511
|
}
|
501
512
|
}
|
@@ -510,9 +521,9 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
|
510
521
|
C) extend corresponding index-chain
|
511
522
|
D) reduce the Huffman space
|
512
523
|
E) update the histogram */
|
513
|
-
static BROTLI_INLINE void ProcessSingleCodeLength(
|
514
|
-
|
515
|
-
|
524
|
+
static BROTLI_INLINE void ProcessSingleCodeLength(brotli_reg_t code_len,
|
525
|
+
brotli_reg_t* symbol, brotli_reg_t* repeat, brotli_reg_t* space,
|
526
|
+
brotli_reg_t* prev_code_len, uint16_t* symbol_lists,
|
516
527
|
uint16_t* code_length_histo, int* next_symbol) {
|
517
528
|
*repeat = 0;
|
518
529
|
if (code_len != 0) { /* code_len == 1..15 */
|
@@ -537,14 +548,14 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
|
537
548
|
|
538
549
|
PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or
|
539
550
|
code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
540
|
-
static BROTLI_INLINE void ProcessRepeatedCodeLength(
|
541
|
-
|
542
|
-
|
543
|
-
|
551
|
+
static BROTLI_INLINE void ProcessRepeatedCodeLength(brotli_reg_t code_len,
|
552
|
+
brotli_reg_t repeat_delta, brotli_reg_t alphabet_size, brotli_reg_t* symbol,
|
553
|
+
brotli_reg_t* repeat, brotli_reg_t* space, brotli_reg_t* prev_code_len,
|
554
|
+
brotli_reg_t* repeat_code_len, uint16_t* symbol_lists,
|
544
555
|
uint16_t* code_length_histo, int* next_symbol) {
|
545
|
-
|
546
|
-
|
547
|
-
|
556
|
+
brotli_reg_t old_repeat;
|
557
|
+
brotli_reg_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
558
|
+
brotli_reg_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
548
559
|
if (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
549
560
|
new_len = *prev_code_len;
|
550
561
|
extra_bits = 2;
|
@@ -569,7 +580,7 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
|
569
580
|
BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
|
570
581
|
(int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len));
|
571
582
|
if (*repeat_code_len != 0) {
|
572
|
-
|
583
|
+
brotli_reg_t last = *symbol + repeat_delta;
|
573
584
|
int next = next_symbol[*repeat_code_len];
|
574
585
|
do {
|
575
586
|
symbol_lists[next] = (uint16_t)*symbol;
|
@@ -586,29 +597,30 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
|
586
597
|
|
587
598
|
/* Reads and decodes symbol codelengths. */
|
588
599
|
static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
589
|
-
|
600
|
+
brotli_reg_t alphabet_size, BrotliDecoderState* s) {
|
590
601
|
BrotliBitReader* br = &s->br;
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
uint16_t*
|
598
|
-
|
602
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
603
|
+
brotli_reg_t symbol = h->symbol;
|
604
|
+
brotli_reg_t repeat = h->repeat;
|
605
|
+
brotli_reg_t space = h->space;
|
606
|
+
brotli_reg_t prev_code_len = h->prev_code_len;
|
607
|
+
brotli_reg_t repeat_code_len = h->repeat_code_len;
|
608
|
+
uint16_t* symbol_lists = h->symbol_lists;
|
609
|
+
uint16_t* code_length_histo = h->code_length_histo;
|
610
|
+
int* next_symbol = h->next_symbol;
|
599
611
|
if (!BrotliWarmupBitReader(br)) {
|
600
612
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
601
613
|
}
|
602
614
|
while (symbol < alphabet_size && space > 0) {
|
603
|
-
const HuffmanCode* p =
|
604
|
-
|
615
|
+
const HuffmanCode* p = h->table;
|
616
|
+
brotli_reg_t code_len;
|
605
617
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
606
|
-
if (!BrotliCheckInputAmount(br
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
618
|
+
if (!BrotliCheckInputAmount(br)) {
|
619
|
+
h->symbol = symbol;
|
620
|
+
h->repeat = repeat;
|
621
|
+
h->prev_code_len = prev_code_len;
|
622
|
+
h->repeat_code_len = repeat_code_len;
|
623
|
+
h->space = space;
|
612
624
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
613
625
|
}
|
614
626
|
BrotliFillBitWindow16(br);
|
@@ -620,29 +632,30 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
620
632
|
ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
|
621
633
|
&prev_code_len, symbol_lists, code_length_histo, next_symbol);
|
622
634
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
623
|
-
|
635
|
+
brotli_reg_t extra_bits =
|
624
636
|
(code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;
|
625
|
-
|
626
|
-
|
637
|
+
brotli_reg_t repeat_delta =
|
638
|
+
BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
|
627
639
|
BrotliDropBits(br, extra_bits);
|
628
640
|
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
629
641
|
&symbol, &repeat, &space, &prev_code_len, &repeat_code_len,
|
630
642
|
symbol_lists, code_length_histo, next_symbol);
|
631
643
|
}
|
632
644
|
}
|
633
|
-
|
645
|
+
h->space = space;
|
634
646
|
return BROTLI_DECODER_SUCCESS;
|
635
647
|
}
|
636
648
|
|
637
649
|
static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
638
|
-
|
650
|
+
brotli_reg_t alphabet_size, BrotliDecoderState* s) {
|
639
651
|
BrotliBitReader* br = &s->br;
|
652
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
640
653
|
BROTLI_BOOL get_byte = BROTLI_FALSE;
|
641
|
-
while (
|
642
|
-
const HuffmanCode* p =
|
643
|
-
|
644
|
-
|
645
|
-
|
654
|
+
while (h->symbol < alphabet_size && h->space > 0) {
|
655
|
+
const HuffmanCode* p = h->table;
|
656
|
+
brotli_reg_t code_len;
|
657
|
+
brotli_reg_t available_bits;
|
658
|
+
brotli_reg_t bits = 0;
|
646
659
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
647
660
|
if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
648
661
|
get_byte = BROTLI_FALSE;
|
@@ -659,12 +672,12 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
659
672
|
code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */
|
660
673
|
if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
661
674
|
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p));
|
662
|
-
ProcessSingleCodeLength(code_len, &
|
663
|
-
&
|
664
|
-
|
675
|
+
ProcessSingleCodeLength(code_len, &h->symbol, &h->repeat, &h->space,
|
676
|
+
&h->prev_code_len, h->symbol_lists, h->code_length_histo,
|
677
|
+
h->next_symbol);
|
665
678
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
666
|
-
|
667
|
-
|
679
|
+
brotli_reg_t extra_bits = code_len - 14U;
|
680
|
+
brotli_reg_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
|
668
681
|
BitMask(extra_bits);
|
669
682
|
if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) {
|
670
683
|
get_byte = BROTLI_TRUE;
|
@@ -672,9 +685,9 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
672
685
|
}
|
673
686
|
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits);
|
674
687
|
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
675
|
-
&
|
676
|
-
&
|
677
|
-
|
688
|
+
&h->symbol, &h->repeat, &h->space, &h->prev_code_len,
|
689
|
+
&h->repeat_code_len, h->symbol_lists, h->code_length_histo,
|
690
|
+
h->next_symbol);
|
678
691
|
}
|
679
692
|
}
|
680
693
|
return BROTLI_DECODER_SUCCESS;
|
@@ -684,36 +697,37 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
684
697
|
Each code is 2..4 bits long. In total 30..72 bits are used. */
|
685
698
|
static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
686
699
|
BrotliBitReader* br = &s->br;
|
687
|
-
|
688
|
-
|
689
|
-
|
700
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
701
|
+
brotli_reg_t num_codes = h->repeat;
|
702
|
+
brotli_reg_t space = h->space;
|
703
|
+
brotli_reg_t i = h->sub_loop_counter;
|
690
704
|
for (; i < BROTLI_CODE_LENGTH_CODES; ++i) {
|
691
705
|
const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
|
692
|
-
|
693
|
-
|
706
|
+
brotli_reg_t ix;
|
707
|
+
brotli_reg_t v;
|
694
708
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
|
695
|
-
|
709
|
+
brotli_reg_t available_bits = BrotliGetAvailableBits(br);
|
696
710
|
if (available_bits != 0) {
|
697
711
|
ix = BrotliGetBitsUnmasked(br) & 0xF;
|
698
712
|
} else {
|
699
713
|
ix = 0;
|
700
714
|
}
|
701
715
|
if (kCodeLengthPrefixLength[ix] > available_bits) {
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
716
|
+
h->sub_loop_counter = i;
|
717
|
+
h->repeat = num_codes;
|
718
|
+
h->space = space;
|
719
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
|
706
720
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
707
721
|
}
|
708
722
|
}
|
709
723
|
v = kCodeLengthPrefixValue[ix];
|
710
724
|
BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
|
711
|
-
|
712
|
-
BROTLI_LOG_ARRAY_INDEX(
|
725
|
+
h->code_length_code_lengths[code_len_idx] = (uint8_t)v;
|
726
|
+
BROTLI_LOG_ARRAY_INDEX(h->code_length_code_lengths, code_len_idx);
|
713
727
|
if (v != 0) {
|
714
728
|
space = space - (32U >> v);
|
715
729
|
++num_codes;
|
716
|
-
++
|
730
|
+
++h->code_length_histo[v];
|
717
731
|
if (space - 1U >= 32U) {
|
718
732
|
/* space is 0 or wrapped around. */
|
719
733
|
break;
|
@@ -737,49 +751,48 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
|
737
751
|
encoded with predefined entropy code. 32 - 74 bits are used.
|
738
752
|
B.2) Decoded table is used to decode code lengths of symbols in resulting
|
739
753
|
Huffman table. In worst case 3520 bits are read. */
|
740
|
-
static BrotliDecoderErrorCode ReadHuffmanCode(
|
741
|
-
|
754
|
+
static BrotliDecoderErrorCode ReadHuffmanCode(brotli_reg_t alphabet_size_max,
|
755
|
+
brotli_reg_t alphabet_size_limit,
|
742
756
|
HuffmanCode* table,
|
743
|
-
|
757
|
+
brotli_reg_t* opt_table_size,
|
744
758
|
BrotliDecoderState* s) {
|
745
759
|
BrotliBitReader* br = &s->br;
|
746
|
-
|
747
|
-
alphabet_size &= 0x7FF;
|
760
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
748
761
|
/* State machine. */
|
749
762
|
for (;;) {
|
750
|
-
switch (
|
763
|
+
switch (h->substate_huffman) {
|
751
764
|
case BROTLI_STATE_HUFFMAN_NONE:
|
752
|
-
if (!BrotliSafeReadBits(br, 2, &
|
765
|
+
if (!BrotliSafeReadBits(br, 2, &h->sub_loop_counter)) {
|
753
766
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
754
767
|
}
|
755
|
-
BROTLI_LOG_UINT(
|
768
|
+
BROTLI_LOG_UINT(h->sub_loop_counter);
|
756
769
|
/* The value is used as follows:
|
757
770
|
1 for simple code;
|
758
771
|
0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
|
759
|
-
if (
|
760
|
-
|
761
|
-
|
762
|
-
memset(&
|
772
|
+
if (h->sub_loop_counter != 1) {
|
773
|
+
h->space = 32;
|
774
|
+
h->repeat = 0; /* num_codes */
|
775
|
+
memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo[0]) *
|
763
776
|
(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));
|
764
|
-
memset(&
|
765
|
-
sizeof(
|
766
|
-
|
777
|
+
memset(&h->code_length_code_lengths[0], 0,
|
778
|
+
sizeof(h->code_length_code_lengths));
|
779
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
|
767
780
|
continue;
|
768
781
|
}
|
769
782
|
/* Fall through. */
|
770
783
|
|
771
784
|
case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:
|
772
785
|
/* Read symbols, codes & code lengths directly. */
|
773
|
-
if (!BrotliSafeReadBits(br, 2, &
|
774
|
-
|
786
|
+
if (!BrotliSafeReadBits(br, 2, &h->symbol)) { /* num_symbols */
|
787
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
|
775
788
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
776
789
|
}
|
777
|
-
|
790
|
+
h->sub_loop_counter = 0;
|
778
791
|
/* Fall through. */
|
779
792
|
|
780
793
|
case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
|
781
794
|
BrotliDecoderErrorCode result =
|
782
|
-
ReadSimpleHuffmanSymbols(
|
795
|
+
ReadSimpleHuffmanSymbols(alphabet_size_max, alphabet_size_limit, s);
|
783
796
|
if (result != BROTLI_DECODER_SUCCESS) {
|
784
797
|
return result;
|
785
798
|
}
|
@@ -787,96 +800,98 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
|
|
787
800
|
/* Fall through. */
|
788
801
|
|
789
802
|
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
|
790
|
-
|
791
|
-
if (
|
792
|
-
|
803
|
+
brotli_reg_t table_size;
|
804
|
+
if (h->symbol == 3) {
|
805
|
+
brotli_reg_t bits;
|
793
806
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
794
|
-
|
807
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
|
795
808
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
796
809
|
}
|
797
|
-
|
810
|
+
h->symbol += bits;
|
798
811
|
}
|
799
|
-
BROTLI_LOG_UINT(
|
800
|
-
table_size = BrotliBuildSimpleHuffmanTable(
|
801
|
-
|
812
|
+
BROTLI_LOG_UINT(h->symbol);
|
813
|
+
table_size = BrotliBuildSimpleHuffmanTable(table, HUFFMAN_TABLE_BITS,
|
814
|
+
h->symbols_lists_array,
|
815
|
+
(uint32_t)h->symbol);
|
802
816
|
if (opt_table_size) {
|
803
817
|
*opt_table_size = table_size;
|
804
818
|
}
|
805
|
-
|
819
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
806
820
|
return BROTLI_DECODER_SUCCESS;
|
807
821
|
}
|
808
822
|
|
809
823
|
/* Decode Huffman-coded code lengths. */
|
810
824
|
case BROTLI_STATE_HUFFMAN_COMPLEX: {
|
811
|
-
|
825
|
+
brotli_reg_t i;
|
812
826
|
BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);
|
813
827
|
if (result != BROTLI_DECODER_SUCCESS) {
|
814
828
|
return result;
|
815
829
|
}
|
816
|
-
BrotliBuildCodeLengthsHuffmanTable(
|
817
|
-
|
818
|
-
|
819
|
-
memset(&
|
830
|
+
BrotliBuildCodeLengthsHuffmanTable(h->table,
|
831
|
+
h->code_length_code_lengths,
|
832
|
+
h->code_length_histo);
|
833
|
+
memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo));
|
820
834
|
for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {
|
821
|
-
|
822
|
-
|
835
|
+
h->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
|
836
|
+
h->symbol_lists[h->next_symbol[i]] = 0xFFFF;
|
823
837
|
}
|
824
838
|
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
839
|
+
h->symbol = 0;
|
840
|
+
h->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;
|
841
|
+
h->repeat = 0;
|
842
|
+
h->repeat_code_len = 0;
|
843
|
+
h->space = 32768;
|
844
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
|
831
845
|
}
|
832
846
|
/* Fall through. */
|
833
847
|
|
834
848
|
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
|
835
|
-
|
836
|
-
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
|
849
|
+
brotli_reg_t table_size;
|
850
|
+
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
|
851
|
+
alphabet_size_limit, s);
|
837
852
|
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
838
|
-
result = SafeReadSymbolCodeLengths(
|
853
|
+
result = SafeReadSymbolCodeLengths(alphabet_size_limit, s);
|
839
854
|
}
|
840
855
|
if (result != BROTLI_DECODER_SUCCESS) {
|
841
856
|
return result;
|
842
857
|
}
|
843
858
|
|
844
|
-
if (
|
845
|
-
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)
|
859
|
+
if (h->space != 0) {
|
860
|
+
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)h->space));
|
846
861
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
|
847
862
|
}
|
848
863
|
table_size = BrotliBuildHuffmanTable(
|
849
|
-
table, HUFFMAN_TABLE_BITS,
|
864
|
+
table, HUFFMAN_TABLE_BITS, h->symbol_lists, h->code_length_histo);
|
850
865
|
if (opt_table_size) {
|
851
866
|
*opt_table_size = table_size;
|
852
867
|
}
|
853
|
-
|
868
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
854
869
|
return BROTLI_DECODER_SUCCESS;
|
855
870
|
}
|
856
871
|
|
857
872
|
default:
|
858
873
|
return
|
859
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
874
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
860
875
|
}
|
861
876
|
}
|
862
877
|
}
|
863
878
|
|
864
879
|
/* Decodes a block length by reading 3..39 bits. */
|
865
|
-
static BROTLI_INLINE
|
866
|
-
|
867
|
-
|
868
|
-
|
880
|
+
static BROTLI_INLINE brotli_reg_t ReadBlockLength(const HuffmanCode* table,
|
881
|
+
BrotliBitReader* br) {
|
882
|
+
brotli_reg_t code;
|
883
|
+
brotli_reg_t nbits;
|
869
884
|
code = ReadSymbol(table, br);
|
870
|
-
nbits =
|
871
|
-
return
|
885
|
+
nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */
|
886
|
+
return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits);
|
872
887
|
}
|
873
888
|
|
874
889
|
/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
|
875
890
|
reading can't be continued with ReadBlockLength. */
|
876
891
|
static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
877
|
-
BrotliDecoderState* s,
|
892
|
+
BrotliDecoderState* s, brotli_reg_t* result, const HuffmanCode* table,
|
878
893
|
BrotliBitReader* br) {
|
879
|
-
|
894
|
+
brotli_reg_t index;
|
880
895
|
if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) {
|
881
896
|
if (!SafeReadSymbol(table, br, &index)) {
|
882
897
|
return BROTLI_FALSE;
|
@@ -885,14 +900,15 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
|
885
900
|
index = s->block_length_index;
|
886
901
|
}
|
887
902
|
{
|
888
|
-
|
889
|
-
|
903
|
+
brotli_reg_t bits;
|
904
|
+
brotli_reg_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
|
905
|
+
brotli_reg_t offset = _kBrotliPrefixCodeRanges[index].offset;
|
890
906
|
if (!BrotliSafeReadBits(br, nbits, &bits)) {
|
891
907
|
s->block_length_index = index;
|
892
908
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
|
893
909
|
return BROTLI_FALSE;
|
894
910
|
}
|
895
|
-
*result =
|
911
|
+
*result = offset + bits;
|
896
912
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
|
897
913
|
return BROTLI_TRUE;
|
898
914
|
}
|
@@ -913,10 +929,10 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
|
913
929
|
Most of input values are 0 and 1. To reduce number of branches, we replace
|
914
930
|
inner for loop with do-while. */
|
915
931
|
static BROTLI_NOINLINE void InverseMoveToFrontTransform(
|
916
|
-
uint8_t* v,
|
932
|
+
uint8_t* v, brotli_reg_t v_len, BrotliDecoderState* state) {
|
917
933
|
/* Reinitialize elements that could have been changed. */
|
918
|
-
|
919
|
-
|
934
|
+
brotli_reg_t i = 1;
|
935
|
+
brotli_reg_t upper_bound = state->mtf_upper_bound;
|
920
936
|
uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */
|
921
937
|
uint8_t* mtf_u8 = (uint8_t*)mtf;
|
922
938
|
/* Load endian-aware constant. */
|
@@ -952,22 +968,22 @@ static BROTLI_NOINLINE void InverseMoveToFrontTransform(
|
|
952
968
|
/* Decodes a series of Huffman table using ReadHuffmanCode function. */
|
953
969
|
static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
954
970
|
HuffmanTreeGroup* group, BrotliDecoderState* s) {
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
971
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
972
|
+
if (h->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
|
973
|
+
h->next = group->codes;
|
974
|
+
h->htree_index = 0;
|
975
|
+
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
|
976
|
+
}
|
977
|
+
while (h->htree_index < group->num_htrees) {
|
978
|
+
brotli_reg_t table_size;
|
979
|
+
BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max,
|
980
|
+
group->alphabet_size_limit, h->next, &table_size, s);
|
965
981
|
if (result != BROTLI_DECODER_SUCCESS) return result;
|
966
|
-
group->htrees[
|
967
|
-
|
968
|
-
++
|
982
|
+
group->htrees[h->htree_index] = h->next;
|
983
|
+
h->next += table_size;
|
984
|
+
++h->htree_index;
|
969
985
|
}
|
970
|
-
|
986
|
+
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
|
971
987
|
return BROTLI_DECODER_SUCCESS;
|
972
988
|
}
|
973
989
|
|
@@ -979,21 +995,22 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
|
979
995
|
This table will be used for reading context map items.
|
980
996
|
3) Read context map items; "0" values could be run-length encoded.
|
981
997
|
4) Optionally, apply InverseMoveToFront transform to the resulting map. */
|
982
|
-
static BrotliDecoderErrorCode DecodeContextMap(
|
983
|
-
|
998
|
+
static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
|
999
|
+
brotli_reg_t* num_htrees,
|
984
1000
|
uint8_t** context_map_arg,
|
985
1001
|
BrotliDecoderState* s) {
|
986
1002
|
BrotliBitReader* br = &s->br;
|
987
1003
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
1004
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
988
1005
|
|
989
|
-
switch ((int)
|
1006
|
+
switch ((int)h->substate_context_map) {
|
990
1007
|
case BROTLI_STATE_CONTEXT_MAP_NONE:
|
991
1008
|
result = DecodeVarLenUint8(s, br, num_htrees);
|
992
1009
|
if (result != BROTLI_DECODER_SUCCESS) {
|
993
1010
|
return result;
|
994
1011
|
}
|
995
1012
|
(*num_htrees)++;
|
996
|
-
|
1013
|
+
h->context_index = 0;
|
997
1014
|
BROTLI_LOG_UINT(context_map_size);
|
998
1015
|
BROTLI_LOG_UINT(*num_htrees);
|
999
1016
|
*context_map_arg =
|
@@ -1005,49 +1022,49 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1005
1022
|
memset(*context_map_arg, 0, (size_t)context_map_size);
|
1006
1023
|
return BROTLI_DECODER_SUCCESS;
|
1007
1024
|
}
|
1008
|
-
|
1025
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
|
1009
1026
|
/* Fall through. */
|
1010
1027
|
|
1011
1028
|
case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
|
1012
|
-
|
1029
|
+
brotli_reg_t bits;
|
1013
1030
|
/* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
|
1014
1031
|
to peek 4 bits ahead. */
|
1015
1032
|
if (!BrotliSafeGetBits(br, 5, &bits)) {
|
1016
1033
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1017
1034
|
}
|
1018
1035
|
if ((bits & 1) != 0) { /* Use RLE for zeros. */
|
1019
|
-
|
1036
|
+
h->max_run_length_prefix = (bits >> 1) + 1;
|
1020
1037
|
BrotliDropBits(br, 5);
|
1021
1038
|
} else {
|
1022
|
-
|
1039
|
+
h->max_run_length_prefix = 0;
|
1023
1040
|
BrotliDropBits(br, 1);
|
1024
1041
|
}
|
1025
|
-
BROTLI_LOG_UINT(
|
1026
|
-
|
1042
|
+
BROTLI_LOG_UINT(h->max_run_length_prefix);
|
1043
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
|
1027
1044
|
}
|
1028
1045
|
/* Fall through. */
|
1029
1046
|
|
1030
1047
|
case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {
|
1031
|
-
|
1048
|
+
brotli_reg_t alphabet_size = *num_htrees + h->max_run_length_prefix;
|
1032
1049
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
1033
|
-
|
1050
|
+
h->context_map_table, NULL, s);
|
1034
1051
|
if (result != BROTLI_DECODER_SUCCESS) return result;
|
1035
|
-
|
1036
|
-
|
1052
|
+
h->code = 0xFFFF;
|
1053
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
|
1037
1054
|
}
|
1038
1055
|
/* Fall through. */
|
1039
1056
|
|
1040
1057
|
case BROTLI_STATE_CONTEXT_MAP_DECODE: {
|
1041
|
-
|
1042
|
-
|
1058
|
+
brotli_reg_t context_index = h->context_index;
|
1059
|
+
brotli_reg_t max_run_length_prefix = h->max_run_length_prefix;
|
1043
1060
|
uint8_t* context_map = *context_map_arg;
|
1044
|
-
|
1061
|
+
brotli_reg_t code = h->code;
|
1045
1062
|
BROTLI_BOOL skip_preamble = (code != 0xFFFF);
|
1046
1063
|
while (context_index < context_map_size || skip_preamble) {
|
1047
1064
|
if (!skip_preamble) {
|
1048
|
-
if (!SafeReadSymbol(
|
1049
|
-
|
1050
|
-
|
1065
|
+
if (!SafeReadSymbol(h->context_map_table, br, &code)) {
|
1066
|
+
h->code = 0xFFFF;
|
1067
|
+
h->context_index = context_index;
|
1051
1068
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1052
1069
|
}
|
1053
1070
|
BROTLI_LOG_UINT(code);
|
@@ -1066,10 +1083,10 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1066
1083
|
}
|
1067
1084
|
/* RLE sub-stage. */
|
1068
1085
|
{
|
1069
|
-
|
1086
|
+
brotli_reg_t reps;
|
1070
1087
|
if (!BrotliSafeReadBits(br, code, &reps)) {
|
1071
|
-
|
1072
|
-
|
1088
|
+
h->code = code;
|
1089
|
+
h->context_index = context_index;
|
1073
1090
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1074
1091
|
}
|
1075
1092
|
reps += 1U << code;
|
@@ -1087,21 +1104,21 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1087
1104
|
/* Fall through. */
|
1088
1105
|
|
1089
1106
|
case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
|
1090
|
-
|
1107
|
+
brotli_reg_t bits;
|
1091
1108
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
1092
|
-
|
1109
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
|
1093
1110
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1094
1111
|
}
|
1095
1112
|
if (bits != 0) {
|
1096
1113
|
InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
|
1097
1114
|
}
|
1098
|
-
|
1115
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
|
1099
1116
|
return BROTLI_DECODER_SUCCESS;
|
1100
1117
|
}
|
1101
1118
|
|
1102
1119
|
default:
|
1103
1120
|
return
|
1104
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
1121
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
1105
1122
|
}
|
1106
1123
|
}
|
1107
1124
|
|
@@ -1109,14 +1126,14 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1109
1126
|
Reads 3..54 bits. */
|
1110
1127
|
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
|
1111
1128
|
int safe, BrotliDecoderState* s, int tree_type) {
|
1112
|
-
|
1129
|
+
brotli_reg_t max_block_type = s->num_block_types[tree_type];
|
1113
1130
|
const HuffmanCode* type_tree = &s->block_type_trees[
|
1114
1131
|
tree_type * BROTLI_HUFFMAN_MAX_SIZE_258];
|
1115
1132
|
const HuffmanCode* len_tree = &s->block_len_trees[
|
1116
1133
|
tree_type * BROTLI_HUFFMAN_MAX_SIZE_26];
|
1117
1134
|
BrotliBitReader* br = &s->br;
|
1118
|
-
|
1119
|
-
|
1135
|
+
brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
|
1136
|
+
brotli_reg_t block_type;
|
1120
1137
|
if (max_block_type <= 1) {
|
1121
1138
|
return BROTLI_FALSE;
|
1122
1139
|
}
|
@@ -1161,7 +1178,8 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
|
1161
1178
|
size_t sample = s->context_map[offset];
|
1162
1179
|
size_t j;
|
1163
1180
|
for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) {
|
1164
|
-
|
1181
|
+
/* NOLINTNEXTLINE(bugprone-macro-repeated-side-effects) */
|
1182
|
+
BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; })
|
1165
1183
|
}
|
1166
1184
|
if (error == 0) {
|
1167
1185
|
s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31);
|
@@ -1172,8 +1190,8 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
|
1172
1190
|
static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
|
1173
1191
|
uint8_t context_mode;
|
1174
1192
|
size_t trivial;
|
1175
|
-
|
1176
|
-
|
1193
|
+
brotli_reg_t block_type = s->block_type_rb[1];
|
1194
|
+
brotli_reg_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS;
|
1177
1195
|
s->context_map_slice = s->context_map + context_offset;
|
1178
1196
|
trivial = s->trivial_literal_contexts[block_type >> 5];
|
1179
1197
|
s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;
|
@@ -1342,10 +1360,61 @@ static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer(
|
|
1342
1360
|
return BROTLI_TRUE;
|
1343
1361
|
}
|
1344
1362
|
|
1363
|
+
static BrotliDecoderErrorCode BROTLI_NOINLINE
|
1364
|
+
SkipMetadataBlock(BrotliDecoderState* s) {
|
1365
|
+
BrotliBitReader* br = &s->br;
|
1366
|
+
|
1367
|
+
if (s->meta_block_remaining_len == 0) {
|
1368
|
+
return BROTLI_DECODER_SUCCESS;
|
1369
|
+
}
|
1370
|
+
|
1371
|
+
BROTLI_DCHECK((BrotliGetAvailableBits(br) & 7) == 0);
|
1372
|
+
|
1373
|
+
/* Drain accumulator. */
|
1374
|
+
if (BrotliGetAvailableBits(br) >= 8) {
|
1375
|
+
uint8_t buffer[8];
|
1376
|
+
int nbytes = (int)(BrotliGetAvailableBits(br)) >> 3;
|
1377
|
+
BROTLI_DCHECK(nbytes <= 8);
|
1378
|
+
if (nbytes > s->meta_block_remaining_len) {
|
1379
|
+
nbytes = s->meta_block_remaining_len;
|
1380
|
+
}
|
1381
|
+
BrotliCopyBytes(buffer, br, (size_t)nbytes);
|
1382
|
+
if (s->metadata_chunk_func) {
|
1383
|
+
s->metadata_chunk_func(s->metadata_callback_opaque, buffer,
|
1384
|
+
(size_t)nbytes);
|
1385
|
+
}
|
1386
|
+
s->meta_block_remaining_len -= nbytes;
|
1387
|
+
if (s->meta_block_remaining_len == 0) {
|
1388
|
+
return BROTLI_DECODER_SUCCESS;
|
1389
|
+
}
|
1390
|
+
}
|
1391
|
+
|
1392
|
+
/* Direct access to metadata is possible. */
|
1393
|
+
int nbytes = (int)BrotliGetRemainingBytes(br);
|
1394
|
+
if (nbytes > s->meta_block_remaining_len) {
|
1395
|
+
nbytes = s->meta_block_remaining_len;
|
1396
|
+
}
|
1397
|
+
if (nbytes > 0) {
|
1398
|
+
if (s->metadata_chunk_func) {
|
1399
|
+
s->metadata_chunk_func(s->metadata_callback_opaque, br->next_in,
|
1400
|
+
(size_t)nbytes);
|
1401
|
+
}
|
1402
|
+
BrotliDropBytes(br, (size_t)nbytes);
|
1403
|
+
s->meta_block_remaining_len -= nbytes;
|
1404
|
+
if (s->meta_block_remaining_len == 0) {
|
1405
|
+
return BROTLI_DECODER_SUCCESS;
|
1406
|
+
}
|
1407
|
+
}
|
1408
|
+
|
1409
|
+
BROTLI_DCHECK(BrotliGetRemainingBytes(br) == 0);
|
1410
|
+
|
1411
|
+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1412
|
+
}
|
1413
|
+
|
1345
1414
|
static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
1346
1415
|
size_t* available_out, uint8_t** next_out, size_t* total_out,
|
1347
1416
|
BrotliDecoderState* s) {
|
1348
|
-
/* TODO: avoid allocation for single uncompressed block. */
|
1417
|
+
/* TODO(eustas): avoid allocation for single uncompressed block. */
|
1349
1418
|
if (!BrotliEnsureRingBuffer(s)) {
|
1350
1419
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1);
|
1351
1420
|
}
|
@@ -1393,6 +1462,115 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|
1393
1462
|
BROTLI_DCHECK(0); /* Unreachable */
|
1394
1463
|
}
|
1395
1464
|
|
1465
|
+
static BROTLI_BOOL AttachCompoundDictionary(
|
1466
|
+
BrotliDecoderState* state, const uint8_t* data, size_t size) {
|
1467
|
+
BrotliDecoderCompoundDictionary* addon = state->compound_dictionary;
|
1468
|
+
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
|
1469
|
+
if (!addon) {
|
1470
|
+
addon = (BrotliDecoderCompoundDictionary*)BROTLI_DECODER_ALLOC(
|
1471
|
+
state, sizeof(BrotliDecoderCompoundDictionary));
|
1472
|
+
if (!addon) return BROTLI_FALSE;
|
1473
|
+
addon->num_chunks = 0;
|
1474
|
+
addon->total_size = 0;
|
1475
|
+
addon->br_length = 0;
|
1476
|
+
addon->br_copied = 0;
|
1477
|
+
addon->block_bits = -1;
|
1478
|
+
addon->chunk_offsets[0] = 0;
|
1479
|
+
state->compound_dictionary = addon;
|
1480
|
+
}
|
1481
|
+
if (addon->num_chunks == 15) return BROTLI_FALSE;
|
1482
|
+
addon->chunks[addon->num_chunks] = data;
|
1483
|
+
addon->num_chunks++;
|
1484
|
+
addon->total_size += (int)size;
|
1485
|
+
addon->chunk_offsets[addon->num_chunks] = addon->total_size;
|
1486
|
+
return BROTLI_TRUE;
|
1487
|
+
}
|
1488
|
+
|
1489
|
+
static void EnsureCoumpoundDictionaryInitialized(BrotliDecoderState* state) {
|
1490
|
+
BrotliDecoderCompoundDictionary* addon = state->compound_dictionary;
|
1491
|
+
/* 256 = (1 << 8) slots in block map. */
|
1492
|
+
int block_bits = 8;
|
1493
|
+
int cursor = 0;
|
1494
|
+
int index = 0;
|
1495
|
+
if (addon->block_bits != -1) return;
|
1496
|
+
while (((addon->total_size - 1) >> block_bits) != 0) block_bits++;
|
1497
|
+
block_bits -= 8;
|
1498
|
+
addon->block_bits = block_bits;
|
1499
|
+
while (cursor < addon->total_size) {
|
1500
|
+
while (addon->chunk_offsets[index + 1] < cursor) index++;
|
1501
|
+
addon->block_map[cursor >> block_bits] = (uint8_t)index;
|
1502
|
+
cursor += 1 << block_bits;
|
1503
|
+
}
|
1504
|
+
}
|
1505
|
+
|
1506
|
+
static BROTLI_BOOL InitializeCompoundDictionaryCopy(BrotliDecoderState* s,
|
1507
|
+
int address, int length) {
|
1508
|
+
BrotliDecoderCompoundDictionary* addon = s->compound_dictionary;
|
1509
|
+
int index;
|
1510
|
+
EnsureCoumpoundDictionaryInitialized(s);
|
1511
|
+
index = addon->block_map[address >> addon->block_bits];
|
1512
|
+
while (address >= addon->chunk_offsets[index + 1]) index++;
|
1513
|
+
if (addon->total_size < address + length) return BROTLI_FALSE;
|
1514
|
+
/* Update the recent distances cache. */
|
1515
|
+
s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
|
1516
|
+
++s->dist_rb_idx;
|
1517
|
+
s->meta_block_remaining_len -= length;
|
1518
|
+
addon->br_index = index;
|
1519
|
+
addon->br_offset = address - addon->chunk_offsets[index];
|
1520
|
+
addon->br_length = length;
|
1521
|
+
addon->br_copied = 0;
|
1522
|
+
return BROTLI_TRUE;
|
1523
|
+
}
|
1524
|
+
|
1525
|
+
static int GetCompoundDictionarySize(BrotliDecoderState* s) {
|
1526
|
+
return s->compound_dictionary ? s->compound_dictionary->total_size : 0;
|
1527
|
+
}
|
1528
|
+
|
1529
|
+
static int CopyFromCompoundDictionary(BrotliDecoderState* s, int pos) {
|
1530
|
+
BrotliDecoderCompoundDictionary* addon = s->compound_dictionary;
|
1531
|
+
int orig_pos = pos;
|
1532
|
+
while (addon->br_length != addon->br_copied) {
|
1533
|
+
uint8_t* copy_dst = &s->ringbuffer[pos];
|
1534
|
+
const uint8_t* copy_src =
|
1535
|
+
addon->chunks[addon->br_index] + addon->br_offset;
|
1536
|
+
int space = s->ringbuffer_size - pos;
|
1537
|
+
int rem_chunk_length = (addon->chunk_offsets[addon->br_index + 1] -
|
1538
|
+
addon->chunk_offsets[addon->br_index]) - addon->br_offset;
|
1539
|
+
int length = addon->br_length - addon->br_copied;
|
1540
|
+
if (length > rem_chunk_length) length = rem_chunk_length;
|
1541
|
+
if (length > space) length = space;
|
1542
|
+
memcpy(copy_dst, copy_src, (size_t)length);
|
1543
|
+
pos += length;
|
1544
|
+
addon->br_offset += length;
|
1545
|
+
addon->br_copied += length;
|
1546
|
+
if (length == rem_chunk_length) {
|
1547
|
+
addon->br_index++;
|
1548
|
+
addon->br_offset = 0;
|
1549
|
+
}
|
1550
|
+
if (pos == s->ringbuffer_size) break;
|
1551
|
+
}
|
1552
|
+
return pos - orig_pos;
|
1553
|
+
}
|
1554
|
+
|
1555
|
+
BROTLI_BOOL BrotliDecoderAttachDictionary(
|
1556
|
+
BrotliDecoderState* state, BrotliSharedDictionaryType type,
|
1557
|
+
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) {
|
1558
|
+
brotli_reg_t i;
|
1559
|
+
brotli_reg_t num_prefix_before = state->dictionary->num_prefix;
|
1560
|
+
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
|
1561
|
+
if (!BrotliSharedDictionaryAttach(state->dictionary, type, data_size, data)) {
|
1562
|
+
return BROTLI_FALSE;
|
1563
|
+
}
|
1564
|
+
for (i = num_prefix_before; i < state->dictionary->num_prefix; i++) {
|
1565
|
+
if (!AttachCompoundDictionary(
|
1566
|
+
state, state->dictionary->prefix[i],
|
1567
|
+
state->dictionary->prefix_size[i])) {
|
1568
|
+
return BROTLI_FALSE;
|
1569
|
+
}
|
1570
|
+
}
|
1571
|
+
return BROTLI_TRUE;
|
1572
|
+
}
|
1573
|
+
|
1396
1574
|
/* Calculates the smallest feasible ring buffer.
|
1397
1575
|
|
1398
1576
|
If we know the data size is small, do not allocate more ring buffer
|
@@ -1444,7 +1622,7 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
|
|
1444
1622
|
int i = s->loop_counter;
|
1445
1623
|
|
1446
1624
|
while (i < (int)s->num_block_types[0]) {
|
1447
|
-
|
1625
|
+
brotli_reg_t bits;
|
1448
1626
|
if (!BrotliSafeReadBits(br, 2, &bits)) {
|
1449
1627
|
s->loop_counter = i;
|
1450
1628
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -1457,38 +1635,34 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
|
|
1457
1635
|
}
|
1458
1636
|
|
1459
1637
|
static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
|
1460
|
-
|
1461
|
-
|
1462
|
-
s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
|
1638
|
+
int offset = s->distance_code - 3;
|
1639
|
+
if (s->distance_code <= 3) {
|
1463
1640
|
/* Compensate double distance-ring-buffer roll for dictionary items. */
|
1464
|
-
s->distance_context = 1;
|
1641
|
+
s->distance_context = 1 >> s->distance_code;
|
1642
|
+
s->distance_code = s->dist_rb[(s->dist_rb_idx - offset) & 3];
|
1643
|
+
s->dist_rb_idx -= s->distance_context;
|
1465
1644
|
} 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;
|
1645
|
+
int index_delta = 3;
|
1646
|
+
int delta;
|
1647
|
+
int base = s->distance_code - 10;
|
1648
|
+
if (s->distance_code < 10) {
|
1649
|
+
base = s->distance_code - 4;
|
1479
1650
|
} else {
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1651
|
+
index_delta = 2;
|
1652
|
+
}
|
1653
|
+
/* Unpack one of six 4-bit values. */
|
1654
|
+
delta = ((0x605142 >> (4 * base)) & 0xF) - 3;
|
1655
|
+
s->distance_code = s->dist_rb[(s->dist_rb_idx + index_delta) & 0x3] + delta;
|
1656
|
+
if (s->distance_code <= 0) {
|
1657
|
+
/* A huge distance will cause a BROTLI_FAILURE() soon.
|
1658
|
+
This is a little faster than failing here. */
|
1659
|
+
s->distance_code = 0x7FFFFFFF;
|
1486
1660
|
}
|
1487
1661
|
}
|
1488
1662
|
}
|
1489
1663
|
|
1490
1664
|
static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
1491
|
-
BrotliBitReader* const br,
|
1665
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
1492
1666
|
if (n_bits != 0) {
|
1493
1667
|
return BrotliSafeReadBits(br, n_bits, val);
|
1494
1668
|
} else {
|
@@ -1497,62 +1671,153 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
|
1497
1671
|
}
|
1498
1672
|
}
|
1499
1673
|
|
1674
|
+
static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
|
1675
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
1676
|
+
if (n_bits != 0) {
|
1677
|
+
return BrotliSafeReadBits32(br, n_bits, val);
|
1678
|
+
} else {
|
1679
|
+
*val = 0;
|
1680
|
+
return BROTLI_TRUE;
|
1681
|
+
}
|
1682
|
+
}
|
1683
|
+
|
1684
|
+
/*
|
1685
|
+
RFC 7932 Section 4 with "..." shortenings and "[]" emendations.
|
1686
|
+
|
1687
|
+
Each distance ... is represented with a pair <distance code, extra bits>...
|
1688
|
+
The distance code is encoded using a prefix code... The number of extra bits
|
1689
|
+
can be 0..24... Two additional parameters: NPOSTFIX (0..3), and ...
|
1690
|
+
NDIRECT (0..120) ... are encoded in the meta-block header...
|
1691
|
+
|
1692
|
+
The first 16 distance symbols ... reference past distances... ring buffer ...
|
1693
|
+
Next NDIRECT distance symbols ... represent distances from 1 to NDIRECT...
|
1694
|
+
[For] distance symbols 16 + NDIRECT and greater ... the number of extra bits
|
1695
|
+
... is given by the following formula:
|
1696
|
+
|
1697
|
+
[ xcode = dcode - NDIRECT - 16 ]
|
1698
|
+
ndistbits = 1 + [ xcode ] >> (NPOSTFIX + 1)
|
1699
|
+
|
1700
|
+
...
|
1701
|
+
*/
|
1702
|
+
|
1703
|
+
/*
|
1704
|
+
RFC 7932 Section 9.2 with "..." shortenings and "[]" emendations.
|
1705
|
+
|
1706
|
+
... to get the actual value of the parameter NDIRECT, left-shift this
|
1707
|
+
four-bit number by NPOSTFIX bits ...
|
1708
|
+
*/
|
1709
|
+
|
1710
|
+
/* Remaining formulas from RFC 7932 Section 4 could be rewritten as following:
|
1711
|
+
|
1712
|
+
alphabet_size = 16 + NDIRECT + (max_distbits << (NPOSTFIX + 1))
|
1713
|
+
|
1714
|
+
half = ((xcode >> NPOSTFIX) & 1) << ndistbits
|
1715
|
+
postfix = xcode & ((1 << NPOSTFIX) - 1)
|
1716
|
+
range_start = 2 * (1 << ndistbits - 1 - 1)
|
1717
|
+
|
1718
|
+
distance = (range_start + half + extra) << NPOSTFIX + postfix + NDIRECT + 1
|
1719
|
+
|
1720
|
+
NB: ndistbits >= 1 -> range_start >= 0
|
1721
|
+
NB: range_start has factor 2, as the range is covered by 2 "halves"
|
1722
|
+
NB: extra -1 offset in range_start formula covers the absence of
|
1723
|
+
ndistbits = 0 case
|
1724
|
+
NB: when NPOSTFIX = 0, NDIRECT is not greater than 15
|
1725
|
+
|
1726
|
+
In other words, xcode has the following binary structure - XXXHPPP:
|
1727
|
+
- XXX represent the number of extra distance bits
|
1728
|
+
- H selects upper / lower range of distances
|
1729
|
+
- PPP represent "postfix"
|
1730
|
+
|
1731
|
+
"Regular" distance encoding has NPOSTFIX = 0; omitting the postfix part
|
1732
|
+
simplifies distance calculation.
|
1733
|
+
|
1734
|
+
Using NPOSTFIX > 0 allows cheaper encoding of regular structures, e.g. where
|
1735
|
+
most of distances have the same reminder of division by 2/4/8. For example,
|
1736
|
+
the table of int32_t values that come from different sources; if it is likely
|
1737
|
+
that 3 highest bytes of values from the same source are the same, then
|
1738
|
+
copy distance often looks like 4x + y.
|
1739
|
+
|
1740
|
+
Distance calculation could be rewritten to:
|
1741
|
+
|
1742
|
+
ndistbits = NDISTBITS(NDIRECT, NPOSTFIX)[dcode]
|
1743
|
+
distance = OFFSET(NDIRECT, NPOSTFIX)[dcode] + extra << NPOSTFIX
|
1744
|
+
|
1745
|
+
NDISTBITS and OFFSET could be pre-calculated, as NDIRECT and NPOSTFIX could
|
1746
|
+
change only once per meta-block.
|
1747
|
+
*/
|
1748
|
+
|
1749
|
+
/* Calculates distance lookup table.
|
1750
|
+
NB: it is possible to have all 64 tables precalculated. */
|
1751
|
+
static void CalculateDistanceLut(BrotliDecoderState* s) {
|
1752
|
+
BrotliMetablockBodyArena* b = &s->arena.body;
|
1753
|
+
brotli_reg_t npostfix = s->distance_postfix_bits;
|
1754
|
+
brotli_reg_t ndirect = s->num_direct_distance_codes;
|
1755
|
+
brotli_reg_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
|
1756
|
+
brotli_reg_t postfix = 1u << npostfix;
|
1757
|
+
brotli_reg_t j;
|
1758
|
+
brotli_reg_t bits = 1;
|
1759
|
+
brotli_reg_t half = 0;
|
1760
|
+
|
1761
|
+
/* Skip short codes. */
|
1762
|
+
brotli_reg_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
|
1763
|
+
|
1764
|
+
/* Fill direct codes. */
|
1765
|
+
for (j = 0; j < ndirect; ++j) {
|
1766
|
+
b->dist_extra_bits[i] = 0;
|
1767
|
+
b->dist_offset[i] = j + 1;
|
1768
|
+
++i;
|
1769
|
+
}
|
1770
|
+
|
1771
|
+
/* Fill regular distance codes. */
|
1772
|
+
while (i < alphabet_size_limit) {
|
1773
|
+
brotli_reg_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
|
1774
|
+
/* Always fill the complete group. */
|
1775
|
+
for (j = 0; j < postfix; ++j) {
|
1776
|
+
b->dist_extra_bits[i] = (uint8_t)bits;
|
1777
|
+
b->dist_offset[i] = base + j;
|
1778
|
+
++i;
|
1779
|
+
}
|
1780
|
+
bits = bits + half;
|
1781
|
+
half = half ^ 1;
|
1782
|
+
}
|
1783
|
+
}
|
1784
|
+
|
1500
1785
|
/* Precondition: s->distance_code < 0. */
|
1501
1786
|
static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
|
1502
1787
|
int safe, BrotliDecoderState* s, BrotliBitReader* br) {
|
1503
|
-
|
1788
|
+
BrotliMetablockBodyArena* b = &s->arena.body;
|
1789
|
+
brotli_reg_t code;
|
1790
|
+
brotli_reg_t bits;
|
1504
1791
|
BrotliBitReaderState memento;
|
1505
1792
|
HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
|
1506
1793
|
if (!safe) {
|
1507
|
-
|
1794
|
+
code = ReadSymbol(distance_tree, br);
|
1508
1795
|
} else {
|
1509
|
-
uint32_t code;
|
1510
1796
|
BrotliBitReaderSaveState(br, &memento);
|
1511
1797
|
if (!SafeReadSymbol(distance_tree, br, &code)) {
|
1512
1798
|
return BROTLI_FALSE;
|
1513
1799
|
}
|
1514
|
-
s->distance_code = (int)code;
|
1515
1800
|
}
|
1801
|
+
--s->block_length[2];
|
1516
1802
|
/* Convert the distance code to the actual distance by possibly
|
1517
|
-
looking up past distances from the s->
|
1803
|
+
looking up past distances from the s->dist_rb. */
|
1518
1804
|
s->distance_context = 0;
|
1519
|
-
if ((
|
1805
|
+
if ((code & ~0xFu) == 0) {
|
1806
|
+
s->distance_code = (int)code;
|
1520
1807
|
TakeDistanceFromRingBuffer(s);
|
1521
|
-
--s->block_length[2];
|
1522
1808
|
return BROTLI_TRUE;
|
1523
1809
|
}
|
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;
|
1810
|
+
if (!safe) {
|
1811
|
+
bits = BrotliReadBits32(br, b->dist_extra_bits[code]);
|
1812
|
+
} else {
|
1813
|
+
if (!SafeReadBits32(br, b->dist_extra_bits[code], &bits)) {
|
1814
|
+
++s->block_length[2];
|
1815
|
+
BrotliBitReaderRestoreState(br, &memento);
|
1816
|
+
return BROTLI_FALSE;
|
1552
1817
|
}
|
1553
1818
|
}
|
1554
|
-
s->distance_code =
|
1555
|
-
|
1819
|
+
s->distance_code =
|
1820
|
+
(int)(b->dist_offset[code] + (bits << s->distance_postfix_bits));
|
1556
1821
|
return BROTLI_TRUE;
|
1557
1822
|
}
|
1558
1823
|
|
@@ -1568,9 +1833,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadDistance(
|
|
1568
1833
|
|
1569
1834
|
static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
|
1570
1835
|
int safe, BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) {
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1836
|
+
brotli_reg_t cmd_code;
|
1837
|
+
brotli_reg_t insert_len_extra = 0;
|
1838
|
+
brotli_reg_t copy_length;
|
1574
1839
|
CmdLutElement v;
|
1575
1840
|
BrotliBitReaderState memento;
|
1576
1841
|
if (!safe) {
|
@@ -1588,9 +1853,9 @@ static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
|
|
1588
1853
|
*insert_length = v.insert_len_offset;
|
1589
1854
|
if (!safe) {
|
1590
1855
|
if (BROTLI_PREDICT_FALSE(v.insert_len_extra_bits != 0)) {
|
1591
|
-
insert_len_extra =
|
1856
|
+
insert_len_extra = BrotliReadBits24(br, v.insert_len_extra_bits);
|
1592
1857
|
}
|
1593
|
-
copy_length =
|
1858
|
+
copy_length = BrotliReadBits24(br, v.copy_len_extra_bits);
|
1594
1859
|
} else {
|
1595
1860
|
if (!SafeReadBits(br, v.insert_len_extra_bits, &insert_len_extra) ||
|
1596
1861
|
!SafeReadBits(br, v.copy_len_extra_bits, ©_length)) {
|
@@ -1615,11 +1880,11 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadCommand(
|
|
1615
1880
|
}
|
1616
1881
|
|
1617
1882
|
static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
|
1618
|
-
int safe, BrotliBitReader* const br
|
1883
|
+
int safe, BrotliBitReader* const br) {
|
1619
1884
|
if (safe) {
|
1620
1885
|
return BROTLI_TRUE;
|
1621
1886
|
}
|
1622
|
-
return BrotliCheckInputAmount(br
|
1887
|
+
return BrotliCheckInputAmount(br);
|
1623
1888
|
}
|
1624
1889
|
|
1625
1890
|
#define BROTLI_SAFE(METHOD) \
|
@@ -1640,8 +1905,9 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
|
|
1640
1905
|
int i = s->loop_counter;
|
1641
1906
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
1642
1907
|
BrotliBitReader* br = &s->br;
|
1908
|
+
int compound_dictionary_size = GetCompoundDictionarySize(s);
|
1643
1909
|
|
1644
|
-
if (!CheckInputAmount(safe, br
|
1910
|
+
if (!CheckInputAmount(safe, br)) {
|
1645
1911
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1646
1912
|
goto saveStateAndReturn;
|
1647
1913
|
}
|
@@ -1659,14 +1925,14 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
|
|
1659
1925
|
} else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
|
1660
1926
|
goto CommandPostWrapCopy;
|
1661
1927
|
} else {
|
1662
|
-
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
1928
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
1663
1929
|
}
|
1664
1930
|
|
1665
1931
|
CommandBegin:
|
1666
1932
|
if (safe) {
|
1667
1933
|
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
1668
1934
|
}
|
1669
|
-
if (!CheckInputAmount(safe, br
|
1935
|
+
if (!CheckInputAmount(safe, br)) {
|
1670
1936
|
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
1671
1937
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1672
1938
|
goto saveStateAndReturn;
|
@@ -1690,25 +1956,23 @@ CommandInner:
|
|
1690
1956
|
}
|
1691
1957
|
/* Read the literals in the command. */
|
1692
1958
|
if (s->trivial_literal_context) {
|
1693
|
-
|
1694
|
-
|
1959
|
+
brotli_reg_t bits;
|
1960
|
+
brotli_reg_t value;
|
1695
1961
|
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
1696
1962
|
do {
|
1697
|
-
if (!CheckInputAmount(safe, br
|
1963
|
+
if (!CheckInputAmount(safe, br)) {
|
1698
1964
|
s->state = BROTLI_STATE_COMMAND_INNER;
|
1699
1965
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1700
1966
|
goto saveStateAndReturn;
|
1701
1967
|
}
|
1702
1968
|
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
|
1703
|
-
|
1704
|
-
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
1705
|
-
if (!s->trivial_literal_context) goto CommandInner;
|
1969
|
+
goto NextLiteralBlock;
|
1706
1970
|
}
|
1707
1971
|
if (!safe) {
|
1708
1972
|
s->ringbuffer[pos] =
|
1709
1973
|
(uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
|
1710
1974
|
} else {
|
1711
|
-
|
1975
|
+
brotli_reg_t literal;
|
1712
1976
|
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
|
1713
1977
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1714
1978
|
goto saveStateAndReturn;
|
@@ -1730,14 +1994,13 @@ CommandInner:
|
|
1730
1994
|
do {
|
1731
1995
|
const HuffmanCode* hc;
|
1732
1996
|
uint8_t context;
|
1733
|
-
if (!CheckInputAmount(safe, br
|
1997
|
+
if (!CheckInputAmount(safe, br)) {
|
1734
1998
|
s->state = BROTLI_STATE_COMMAND_INNER;
|
1735
1999
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1736
2000
|
goto saveStateAndReturn;
|
1737
2001
|
}
|
1738
2002
|
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
|
1739
|
-
|
1740
|
-
if (s->trivial_literal_context) goto CommandInner;
|
2003
|
+
goto NextLiteralBlock;
|
1741
2004
|
}
|
1742
2005
|
context = BROTLI_CONTEXT(p1, p2, s->context_lookup);
|
1743
2006
|
BROTLI_LOG_UINT(context);
|
@@ -1746,7 +2009,7 @@ CommandInner:
|
|
1746
2009
|
if (!safe) {
|
1747
2010
|
p1 = (uint8_t)ReadSymbol(hc, br);
|
1748
2011
|
} else {
|
1749
|
-
|
2012
|
+
brotli_reg_t literal;
|
1750
2013
|
if (!SafeReadSymbol(hc, br, &literal)) {
|
1751
2014
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1752
2015
|
goto saveStateAndReturn;
|
@@ -1806,20 +2069,75 @@ CommandPostDecodeLiterals:
|
|
1806
2069
|
pos, s->distance_code, i, s->meta_block_remaining_len));
|
1807
2070
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DISTANCE);
|
1808
2071
|
}
|
1809
|
-
if (
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
2072
|
+
if (s->distance_code - s->max_distance - 1 < compound_dictionary_size) {
|
2073
|
+
int address = compound_dictionary_size -
|
2074
|
+
(s->distance_code - s->max_distance);
|
2075
|
+
if (!InitializeCompoundDictionaryCopy(s, address, i)) {
|
2076
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY);
|
2077
|
+
}
|
2078
|
+
pos += CopyFromCompoundDictionary(s, pos);
|
2079
|
+
if (pos >= s->ringbuffer_size) {
|
2080
|
+
s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;
|
2081
|
+
goto saveStateAndReturn;
|
2082
|
+
}
|
2083
|
+
} else if (i >= SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH &&
|
2084
|
+
i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH) {
|
2085
|
+
uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask];
|
2086
|
+
uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask];
|
2087
|
+
uint8_t dict_id = s->dictionary->context_based ?
|
2088
|
+
s->dictionary->context_map[BROTLI_CONTEXT(p1, p2, s->context_lookup)]
|
2089
|
+
: 0;
|
2090
|
+
const BrotliDictionary* words = s->dictionary->words[dict_id];
|
2091
|
+
const BrotliTransforms* transforms = s->dictionary->transforms[dict_id];
|
2092
|
+
int offset = (int)words->offsets_by_length[i];
|
2093
|
+
brotli_reg_t shift = words->size_bits_by_length[i];
|
2094
|
+
int address =
|
2095
|
+
s->distance_code - s->max_distance - 1 - compound_dictionary_size;
|
1817
2096
|
int mask = (int)BitMask(shift);
|
1818
2097
|
int word_idx = address & mask;
|
1819
2098
|
int transform_idx = address >> shift;
|
1820
2099
|
/* Compensate double distance-ring-buffer roll. */
|
1821
2100
|
s->dist_rb_idx += s->distance_context;
|
1822
2101
|
offset += word_idx * i;
|
2102
|
+
/* If the distance is out of bound, select a next static dictionary if
|
2103
|
+
there exist multiple. */
|
2104
|
+
if ((transform_idx >= (int)transforms->num_transforms ||
|
2105
|
+
words->size_bits_by_length[i] == 0) &&
|
2106
|
+
s->dictionary->num_dictionaries > 1) {
|
2107
|
+
uint8_t dict_id2;
|
2108
|
+
int dist_remaining = address -
|
2109
|
+
(int)(((1u << shift) & ~1u)) * (int)transforms->num_transforms;
|
2110
|
+
for (dict_id2 = 0; dict_id2 < s->dictionary->num_dictionaries;
|
2111
|
+
dict_id2++) {
|
2112
|
+
const BrotliDictionary* words2 = s->dictionary->words[dict_id2];
|
2113
|
+
if (dict_id2 != dict_id && words2->size_bits_by_length[i] != 0) {
|
2114
|
+
const BrotliTransforms* transforms2 =
|
2115
|
+
s->dictionary->transforms[dict_id2];
|
2116
|
+
brotli_reg_t shift2 = words2->size_bits_by_length[i];
|
2117
|
+
int num = (int)((1u << shift2) & ~1u) *
|
2118
|
+
(int)transforms2->num_transforms;
|
2119
|
+
if (dist_remaining < num) {
|
2120
|
+
dict_id = dict_id2;
|
2121
|
+
words = words2;
|
2122
|
+
transforms = transforms2;
|
2123
|
+
address = dist_remaining;
|
2124
|
+
shift = shift2;
|
2125
|
+
mask = (int)BitMask(shift);
|
2126
|
+
word_idx = address & mask;
|
2127
|
+
transform_idx = address >> shift;
|
2128
|
+
offset = (int)words->offsets_by_length[i] + word_idx * i;
|
2129
|
+
break;
|
2130
|
+
}
|
2131
|
+
dist_remaining -= num;
|
2132
|
+
}
|
2133
|
+
}
|
2134
|
+
}
|
2135
|
+
if (BROTLI_PREDICT_FALSE(words->size_bits_by_length[i] == 0)) {
|
2136
|
+
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
2137
|
+
"len: %d bytes left: %d\n",
|
2138
|
+
pos, s->distance_code, i, s->meta_block_remaining_len));
|
2139
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DICTIONARY);
|
2140
|
+
}
|
1823
2141
|
if (BROTLI_PREDICT_FALSE(!words->data)) {
|
1824
2142
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET);
|
1825
2143
|
}
|
@@ -1836,6 +2154,10 @@ CommandPostDecodeLiterals:
|
|
1836
2154
|
BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s],"
|
1837
2155
|
" transform_idx = %d, transformed: [%.*s]\n",
|
1838
2156
|
i, word, transform_idx, len, &s->ringbuffer[pos]));
|
2157
|
+
if (len == 0 && s->distance_code <= 120) {
|
2158
|
+
BROTLI_LOG(("Invalid length-0 dictionary word after transform\n"));
|
2159
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_TRANSFORM);
|
2160
|
+
}
|
1839
2161
|
}
|
1840
2162
|
pos += len;
|
1841
2163
|
s->meta_block_remaining_len -= len;
|
@@ -1917,6 +2239,10 @@ CommandPostWrapCopy:
|
|
1917
2239
|
goto CommandBegin;
|
1918
2240
|
}
|
1919
2241
|
|
2242
|
+
NextLiteralBlock:
|
2243
|
+
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
|
2244
|
+
goto CommandInner;
|
2245
|
+
|
1920
2246
|
saveStateAndReturn:
|
1921
2247
|
s->pos = pos;
|
1922
2248
|
s->loop_counter = i;
|
@@ -1935,24 +2261,11 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands(
|
|
1935
2261
|
return ProcessCommandsInternal(1, s);
|
1936
2262
|
}
|
1937
2263
|
|
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
2264
|
BrotliDecoderResult BrotliDecoderDecompress(
|
1954
|
-
size_t encoded_size,
|
1955
|
-
uint8_t
|
2265
|
+
size_t encoded_size,
|
2266
|
+
const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)],
|
2267
|
+
size_t* decoded_size,
|
2268
|
+
uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]) {
|
1956
2269
|
BrotliDecoderState s;
|
1957
2270
|
BrotliDecoderResult result;
|
1958
2271
|
size_t total_out = 0;
|
@@ -1989,6 +2302,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
1989
2302
|
size_t* available_out, uint8_t** next_out, size_t* total_out) {
|
1990
2303
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
1991
2304
|
BrotliBitReader* br = &s->br;
|
2305
|
+
size_t input_size = *available_in;
|
2306
|
+
#define BROTLI_SAVE_ERROR_CODE(code) \
|
2307
|
+
SaveErrorCode(s, (code), input_size - *available_in)
|
1992
2308
|
/* Ensure that |total_out| is set, even if no data will ever be pushed out. */
|
1993
2309
|
if (total_out) {
|
1994
2310
|
*total_out = s->partial_pos_out;
|
@@ -1998,19 +2314,18 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
1998
2314
|
return BROTLI_DECODER_RESULT_ERROR;
|
1999
2315
|
}
|
2000
2316
|
if (*available_out && (!next_out || !*next_out)) {
|
2001
|
-
return
|
2002
|
-
|
2317
|
+
return BROTLI_SAVE_ERROR_CODE(
|
2318
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
|
2003
2319
|
}
|
2004
2320
|
if (!*available_out) next_out = 0;
|
2005
2321
|
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
|
2006
|
-
br
|
2007
|
-
br->next_in = *next_in;
|
2322
|
+
BrotliBitReaderSetInput(br, *next_in, *available_in);
|
2008
2323
|
} else {
|
2009
2324
|
/* At least one byte of input is required. More than one byte of input may
|
2010
2325
|
be required to complete the transaction -> reading more data must be
|
2011
2326
|
done in a loop -> do it in a main loop. */
|
2012
2327
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2013
|
-
br
|
2328
|
+
BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length);
|
2014
2329
|
}
|
2015
2330
|
/* State machine */
|
2016
2331
|
for (;;) {
|
@@ -2027,23 +2342,23 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2027
2342
|
}
|
2028
2343
|
}
|
2029
2344
|
if (s->buffer_length != 0) { /* Used with internal buffer. */
|
2030
|
-
if (br->
|
2345
|
+
if (br->next_in == br->last_in) {
|
2031
2346
|
/* Successfully finished read transaction.
|
2032
2347
|
Accumulator contains less than 8 bits, because internal buffer
|
2033
2348
|
is expanded byte-by-byte until it is enough to complete read. */
|
2034
2349
|
s->buffer_length = 0;
|
2035
2350
|
/* Switch to input stream and restart. */
|
2036
2351
|
result = BROTLI_DECODER_SUCCESS;
|
2037
|
-
br
|
2038
|
-
br->next_in = *next_in;
|
2352
|
+
BrotliBitReaderSetInput(br, *next_in, *available_in);
|
2039
2353
|
continue;
|
2040
2354
|
} else if (*available_in != 0) {
|
2041
2355
|
/* Not enough data in buffer, but can take one more byte from
|
2042
2356
|
input stream. */
|
2043
2357
|
result = BROTLI_DECODER_SUCCESS;
|
2358
|
+
BROTLI_DCHECK(s->buffer_length < 8);
|
2044
2359
|
s->buffer.u8[s->buffer_length] = **next_in;
|
2045
2360
|
s->buffer_length++;
|
2046
|
-
br->
|
2361
|
+
BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length);
|
2047
2362
|
(*next_in)++;
|
2048
2363
|
(*available_in)--;
|
2049
2364
|
/* Retry with more data in buffer. */
|
@@ -2054,7 +2369,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2054
2369
|
} else { /* Input stream doesn't contain enough input. */
|
2055
2370
|
/* Copy tail to internal buffer and return. */
|
2056
2371
|
*next_in = br->next_in;
|
2057
|
-
*available_in = br
|
2372
|
+
*available_in = BrotliBitReaderGetAvailIn(br);
|
2058
2373
|
while (*available_in) {
|
2059
2374
|
s->buffer.u8[s->buffer_length] = **next_in;
|
2060
2375
|
s->buffer_length++;
|
@@ -2077,7 +2392,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2077
2392
|
stream it has less than 8 bits in accumulator, so it is safe to
|
2078
2393
|
return unused accumulator bits there. */
|
2079
2394
|
BrotliBitReaderUnload(br);
|
2080
|
-
*available_in = br
|
2395
|
+
*available_in = BrotliBitReaderGetAvailIn(br);
|
2081
2396
|
*next_in = br->next_in;
|
2082
2397
|
}
|
2083
2398
|
break;
|
@@ -2101,17 +2416,20 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2101
2416
|
s->state = BROTLI_STATE_INITIALIZE;
|
2102
2417
|
break;
|
2103
2418
|
|
2104
|
-
case BROTLI_STATE_LARGE_WINDOW_BITS:
|
2105
|
-
|
2419
|
+
case BROTLI_STATE_LARGE_WINDOW_BITS: {
|
2420
|
+
brotli_reg_t bits;
|
2421
|
+
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
2106
2422
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2107
2423
|
break;
|
2108
2424
|
}
|
2425
|
+
s->window_bits = bits & 63u;
|
2109
2426
|
if (s->window_bits < BROTLI_LARGE_MIN_WBITS ||
|
2110
2427
|
s->window_bits > BROTLI_LARGE_MAX_WBITS) {
|
2111
2428
|
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
|
2112
2429
|
break;
|
2113
2430
|
}
|
2114
2431
|
s->state = BROTLI_STATE_INITIALIZE;
|
2432
|
+
}
|
2115
2433
|
/* Fall through. */
|
2116
2434
|
|
2117
2435
|
case BROTLI_STATE_INITIALIZE:
|
@@ -2156,6 +2474,10 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2156
2474
|
}
|
2157
2475
|
if (s->is_metadata) {
|
2158
2476
|
s->state = BROTLI_STATE_METADATA;
|
2477
|
+
if (s->metadata_start_func) {
|
2478
|
+
s->metadata_start_func(s->metadata_callback_opaque,
|
2479
|
+
(size_t)s->meta_block_remaining_len);
|
2480
|
+
}
|
2159
2481
|
break;
|
2160
2482
|
}
|
2161
2483
|
if (s->meta_block_remaining_len == 0) {
|
@@ -2167,33 +2489,23 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2167
2489
|
s->state = BROTLI_STATE_UNCOMPRESSED;
|
2168
2490
|
break;
|
2169
2491
|
}
|
2492
|
+
s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER;
|
2493
|
+
/* Fall through. */
|
2494
|
+
|
2495
|
+
case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER: {
|
2496
|
+
BrotliMetablockHeaderArena* h = &s->arena.header;
|
2170
2497
|
s->loop_counter = 0;
|
2498
|
+
/* Initialize compressed metablock header arena. */
|
2499
|
+
h->sub_loop_counter = 0;
|
2500
|
+
/* Make small negative indexes addressable. */
|
2501
|
+
h->symbol_lists =
|
2502
|
+
&h->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
|
2503
|
+
h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
2504
|
+
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
|
2505
|
+
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
|
2171
2506
|
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
2507
|
}
|
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;
|
2508
|
+
/* Fall through. */
|
2197
2509
|
|
2198
2510
|
case BROTLI_STATE_HUFFMAN_CODE_0:
|
2199
2511
|
if (s->loop_counter >= 3) {
|
@@ -2215,7 +2527,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2215
2527
|
/* Fall through. */
|
2216
2528
|
|
2217
2529
|
case BROTLI_STATE_HUFFMAN_CODE_1: {
|
2218
|
-
|
2530
|
+
brotli_reg_t alphabet_size = s->num_block_types[s->loop_counter] + 2;
|
2219
2531
|
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
|
2220
2532
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
2221
2533
|
&s->block_type_trees[tree_offset], NULL, s);
|
@@ -2225,7 +2537,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2225
2537
|
/* Fall through. */
|
2226
2538
|
|
2227
2539
|
case BROTLI_STATE_HUFFMAN_CODE_2: {
|
2228
|
-
|
2540
|
+
brotli_reg_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;
|
2229
2541
|
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
|
2230
2542
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
2231
2543
|
&s->block_len_trees[tree_offset], NULL, s);
|
@@ -2247,19 +2559,35 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2247
2559
|
break;
|
2248
2560
|
}
|
2249
2561
|
|
2562
|
+
case BROTLI_STATE_UNCOMPRESSED: {
|
2563
|
+
result = CopyUncompressedBlockToOutput(
|
2564
|
+
available_out, next_out, total_out, s);
|
2565
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
2566
|
+
break;
|
2567
|
+
}
|
2568
|
+
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2569
|
+
break;
|
2570
|
+
}
|
2571
|
+
|
2572
|
+
case BROTLI_STATE_METADATA:
|
2573
|
+
result = SkipMetadataBlock(s);
|
2574
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
2575
|
+
break;
|
2576
|
+
}
|
2577
|
+
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2578
|
+
break;
|
2579
|
+
|
2250
2580
|
case BROTLI_STATE_METABLOCK_HEADER_2: {
|
2251
|
-
|
2581
|
+
brotli_reg_t bits;
|
2252
2582
|
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
2253
2583
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2254
2584
|
break;
|
2255
2585
|
}
|
2256
2586
|
s->distance_postfix_bits = bits & BitMask(2);
|
2257
2587
|
bits >>= 2;
|
2258
|
-
s->num_direct_distance_codes =
|
2259
|
-
(bits << s->distance_postfix_bits);
|
2588
|
+
s->num_direct_distance_codes = bits << s->distance_postfix_bits;
|
2260
2589
|
BROTLI_LOG_UINT(s->num_direct_distance_codes);
|
2261
2590
|
BROTLI_LOG_UINT(s->distance_postfix_bits);
|
2262
|
-
s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
|
2263
2591
|
s->context_modes =
|
2264
2592
|
(uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)s->num_block_types[0]);
|
2265
2593
|
if (s->context_modes == 0) {
|
@@ -2291,17 +2619,20 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2291
2619
|
/* Fall through. */
|
2292
2620
|
|
2293
2621
|
case BROTLI_STATE_CONTEXT_MAP_2: {
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
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);
|
2622
|
+
brotli_reg_t npostfix = s->distance_postfix_bits;
|
2623
|
+
brotli_reg_t ndirect = s->num_direct_distance_codes;
|
2624
|
+
brotli_reg_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
2625
|
+
npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
|
2626
|
+
brotli_reg_t distance_alphabet_size_limit = distance_alphabet_size_max;
|
2304
2627
|
BROTLI_BOOL allocation_success = BROTLI_TRUE;
|
2628
|
+
if (s->large_window) {
|
2629
|
+
BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
|
2630
|
+
BROTLI_MAX_ALLOWED_DISTANCE, (uint32_t)npostfix,
|
2631
|
+
(uint32_t)ndirect);
|
2632
|
+
distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
2633
|
+
npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
|
2634
|
+
distance_alphabet_size_limit = limit.max_alphabet_size;
|
2635
|
+
}
|
2305
2636
|
result = DecodeContextMap(
|
2306
2637
|
s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS,
|
2307
2638
|
&s->num_dist_htrees, &s->dist_context_map, s);
|
@@ -2315,10 +2646,10 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2315
2646
|
s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS,
|
2316
2647
|
BROTLI_NUM_COMMAND_SYMBOLS, s->num_block_types[1]);
|
2317
2648
|
allocation_success &= BrotliDecoderHuffmanTreeGroupInit(
|
2318
|
-
s, &s->distance_hgroup,
|
2319
|
-
|
2649
|
+
s, &s->distance_hgroup, distance_alphabet_size_max,
|
2650
|
+
distance_alphabet_size_limit, s->num_dist_htrees);
|
2320
2651
|
if (!allocation_success) {
|
2321
|
-
return
|
2652
|
+
return BROTLI_SAVE_ERROR_CODE(
|
2322
2653
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
|
2323
2654
|
}
|
2324
2655
|
s->loop_counter = 0;
|
@@ -2332,24 +2663,30 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2332
2663
|
case 0: hgroup = &s->literal_hgroup; break;
|
2333
2664
|
case 1: hgroup = &s->insert_copy_hgroup; break;
|
2334
2665
|
case 2: hgroup = &s->distance_hgroup; break;
|
2335
|
-
default: return
|
2336
|
-
BROTLI_DECODER_ERROR_UNREACHABLE));
|
2666
|
+
default: return BROTLI_SAVE_ERROR_CODE(BROTLI_FAILURE(
|
2667
|
+
BROTLI_DECODER_ERROR_UNREACHABLE)); /* COV_NF_LINE */
|
2337
2668
|
}
|
2338
2669
|
result = HuffmanTreeGroupDecode(hgroup, s);
|
2339
2670
|
if (result != BROTLI_DECODER_SUCCESS) break;
|
2340
2671
|
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;
|
2672
|
+
if (s->loop_counter < 3) {
|
2673
|
+
break;
|
2350
2674
|
}
|
2351
|
-
|
2675
|
+
s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY;
|
2352
2676
|
}
|
2677
|
+
/* Fall through. */
|
2678
|
+
|
2679
|
+
case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY:
|
2680
|
+
PrepareLiteralDecoding(s);
|
2681
|
+
s->dist_context_map_slice = s->dist_context_map;
|
2682
|
+
s->htree_command = s->insert_copy_hgroup.htrees[0];
|
2683
|
+
if (!BrotliEnsureRingBuffer(s)) {
|
2684
|
+
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
|
2685
|
+
break;
|
2686
|
+
}
|
2687
|
+
CalculateDistanceLut(s);
|
2688
|
+
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
2689
|
+
/* Fall through. */
|
2353
2690
|
|
2354
2691
|
case BROTLI_STATE_COMMAND_BEGIN:
|
2355
2692
|
/* Fall through. */
|
@@ -2379,6 +2716,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2379
2716
|
s->max_distance = s->max_backward_distance;
|
2380
2717
|
}
|
2381
2718
|
if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
|
2719
|
+
BrotliDecoderCompoundDictionary* addon = s->compound_dictionary;
|
2720
|
+
if (addon && (addon->br_length != addon->br_copied)) {
|
2721
|
+
s->pos += CopyFromCompoundDictionary(s, s->pos);
|
2722
|
+
if (s->pos >= s->ringbuffer_size) continue;
|
2723
|
+
}
|
2382
2724
|
if (s->meta_block_remaining_len == 0) {
|
2383
2725
|
/* Next metablock, if any. */
|
2384
2726
|
s->state = BROTLI_STATE_METABLOCK_DONE;
|
@@ -2417,7 +2759,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2417
2759
|
}
|
2418
2760
|
if (s->buffer_length == 0) {
|
2419
2761
|
BrotliBitReaderUnload(br);
|
2420
|
-
*available_in = br
|
2762
|
+
*available_in = BrotliBitReaderGetAvailIn(br);
|
2421
2763
|
*next_in = br->next_in;
|
2422
2764
|
}
|
2423
2765
|
s->state = BROTLI_STATE_DONE;
|
@@ -2431,10 +2773,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2431
2773
|
break;
|
2432
2774
|
}
|
2433
2775
|
}
|
2434
|
-
return
|
2776
|
+
return BROTLI_SAVE_ERROR_CODE(result);
|
2435
2777
|
}
|
2436
2778
|
}
|
2437
|
-
return
|
2779
|
+
return BROTLI_SAVE_ERROR_CODE(result);
|
2780
|
+
#undef BROTLI_SAVE_ERROR_CODE
|
2438
2781
|
}
|
2439
2782
|
|
2440
2783
|
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {
|
@@ -2464,7 +2807,7 @@ const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) {
|
|
2464
2807
|
} else {
|
2465
2808
|
/* ... or stream is broken. Normally this should be caught by
|
2466
2809
|
BrotliDecoderDecompressStream, this is just a safeguard. */
|
2467
|
-
if ((int)status < 0) SaveErrorCode(s, status);
|
2810
|
+
if ((int)status < 0) SaveErrorCode(s, status, 0);
|
2468
2811
|
*size = 0;
|
2469
2812
|
result = 0;
|
2470
2813
|
}
|
@@ -2488,7 +2831,7 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
|
|
2488
2831
|
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
2489
2832
|
switch (c) {
|
2490
2833
|
#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \
|
2491
|
-
case BROTLI_DECODER ## PREFIX ## NAME: return #NAME;
|
2834
|
+
case BROTLI_DECODER ## PREFIX ## NAME: return #PREFIX #NAME;
|
2492
2835
|
#define BROTLI_NOTHING_
|
2493
2836
|
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_)
|
2494
2837
|
#undef BROTLI_ERROR_CODE_CASE_
|
@@ -2497,10 +2840,36 @@ const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
|
2497
2840
|
}
|
2498
2841
|
}
|
2499
2842
|
|
2500
|
-
uint32_t BrotliDecoderVersion() {
|
2843
|
+
uint32_t BrotliDecoderVersion(void) {
|
2501
2844
|
return BROTLI_VERSION;
|
2502
2845
|
}
|
2503
2846
|
|
2847
|
+
void BrotliDecoderSetMetadataCallbacks(
|
2848
|
+
BrotliDecoderState* state,
|
2849
|
+
brotli_decoder_metadata_start_func start_func,
|
2850
|
+
brotli_decoder_metadata_chunk_func chunk_func, void* opaque) {
|
2851
|
+
state->metadata_start_func = start_func;
|
2852
|
+
state->metadata_chunk_func = chunk_func;
|
2853
|
+
state->metadata_callback_opaque = opaque;
|
2854
|
+
}
|
2855
|
+
|
2856
|
+
/* Escalate internal functions visibility; for testing purposes only. */
|
2857
|
+
#if defined(BROTLI_TEST)
|
2858
|
+
BROTLI_BOOL SafeReadSymbolForTest(
|
2859
|
+
const HuffmanCode*, BrotliBitReader*, brotli_reg_t*);
|
2860
|
+
BROTLI_BOOL SafeReadSymbolForTest(
|
2861
|
+
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
2862
|
+
return SafeReadSymbol(table, br, result);
|
2863
|
+
}
|
2864
|
+
|
2865
|
+
void InverseMoveToFrontTransformForTest(
|
2866
|
+
uint8_t*, brotli_reg_t, BrotliDecoderState*);
|
2867
|
+
void InverseMoveToFrontTransformForTest(
|
2868
|
+
uint8_t* v, brotli_reg_t l, BrotliDecoderState* s) {
|
2869
|
+
InverseMoveToFrontTransform(v, l, s);
|
2870
|
+
}
|
2871
|
+
#endif
|
2872
|
+
|
2504
2873
|
#if defined(__cplusplus) || defined(c_plusplus)
|
2505
2874
|
} /* extern "C" */
|
2506
2875
|
#endif
|