brotli 0.4.0 → 0.6.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 +6 -3
- data/.github/workflows/publish.yml +7 -17
- data/.gitmodules +1 -1
- data/README.md +2 -2
- data/ext/brotli/brotli.c +8 -0
- data/ext/brotli/extconf.rb +6 -0
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +14 -1
- data/test/test_helper.rb +1 -0
- data/vendor/brotli/c/common/constants.c +1 -1
- data/vendor/brotli/c/common/constants.h +2 -1
- data/vendor/brotli/c/common/context.c +1 -1
- data/vendor/brotli/c/common/dictionary.c +5 -3
- data/vendor/brotli/c/common/platform.c +2 -1
- data/vendor/brotli/c/common/platform.h +60 -113
- 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 +1 -1
- data/vendor/brotli/c/common/version.h +31 -6
- data/vendor/brotli/c/dec/bit_reader.c +10 -8
- data/vendor/brotli/c/dec/bit_reader.h +172 -100
- data/vendor/brotli/c/dec/decode.c +467 -200
- data/vendor/brotli/c/dec/huffman.c +7 -4
- data/vendor/brotli/c/dec/huffman.h +2 -1
- data/vendor/brotli/c/dec/prefix.h +2 -1
- data/vendor/brotli/c/dec/state.c +33 -9
- data/vendor/brotli/c/dec/state.h +70 -35
- data/vendor/brotli/c/enc/backward_references.c +81 -19
- data/vendor/brotli/c/enc/backward_references.h +5 -4
- data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
- data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
- data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
- 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 +37 -14
- data/vendor/brotli/c/enc/block_splitter.h +5 -4
- data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
- data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
- 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 +25 -20
- data/vendor/brotli/c/enc/command.c +1 -1
- data/vendor/brotli/c/enc/command.h +5 -4
- 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 +99 -87
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
- data/vendor/brotli/c/enc/encode.c +473 -404
- data/vendor/brotli/c/enc/encoder_dict.c +611 -4
- data/vendor/brotli/c/enc/encoder_dict.h +117 -3
- data/vendor/brotli/c/enc/entropy_encode.c +3 -2
- data/vendor/brotli/c/enc/entropy_encode.h +2 -1
- data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
- data/vendor/brotli/c/enc/fast_log.c +1 -1
- data/vendor/brotli/c/enc/fast_log.h +2 -1
- data/vendor/brotli/c/enc/find_match_length.h +15 -22
- data/vendor/brotli/c/enc/hash.h +285 -45
- data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
- data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
- 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 +19 -2
- data/vendor/brotli/c/enc/metablock.c +72 -58
- data/vendor/brotli/c/enc/metablock.h +9 -8
- data/vendor/brotli/c/enc/metablock_inc.h +8 -6
- data/vendor/brotli/c/enc/params.h +4 -3
- 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 +4 -3
- 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 +1 -1
- data/vendor/brotli/c/enc/utf8_util.h +2 -1
- data/vendor/brotli/c/enc/write_bits.h +2 -1
- data/vendor/brotli/c/include/brotli/decode.h +67 -2
- data/vendor/brotli/c/include/brotli/encode.h +55 -2
- data/vendor/brotli/c/include/brotli/port.h +28 -11
- data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
- metadata +9 -3
@@ -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>
|
@@ -42,8 +43,8 @@ extern "C" {
|
|
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
45
|
- inserting transformed dictionary word:
|
45
|
-
|
46
|
-
static const
|
46
|
+
255 prefix + 32 base + 255 suffix */
|
47
|
+
static const brotli_reg_t kRingBufferWriteAheadSlack = 542;
|
47
48
|
|
48
49
|
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
|
49
50
|
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
@@ -112,8 +113,13 @@ void BrotliDecoderDestroyInstance(BrotliDecoderState* state) {
|
|
112
113
|
|
113
114
|
/* Saves error code and converts it to BrotliDecoderResult. */
|
114
115
|
static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
115
|
-
BrotliDecoderState* s, BrotliDecoderErrorCode e) {
|
116
|
+
BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) {
|
116
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
|
+
}
|
117
123
|
switch (e) {
|
118
124
|
case BROTLI_DECODER_SUCCESS:
|
119
125
|
return BROTLI_DECODER_RESULT_SUCCESS;
|
@@ -133,7 +139,7 @@ static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
|
133
139
|
Precondition: bit-reader accumulator has at least 8 bits. */
|
134
140
|
static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
135
141
|
BrotliBitReader* br) {
|
136
|
-
|
142
|
+
brotli_reg_t n;
|
137
143
|
BROTLI_BOOL large_window = s->large_window;
|
138
144
|
s->large_window = BROTLI_FALSE;
|
139
145
|
BrotliTakeBits(br, 1, &n);
|
@@ -143,7 +149,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
|
143
149
|
}
|
144
150
|
BrotliTakeBits(br, 3, &n);
|
145
151
|
if (n != 0) {
|
146
|
-
s->window_bits =
|
152
|
+
s->window_bits = (17u + n) & 63u;
|
147
153
|
return BROTLI_DECODER_SUCCESS;
|
148
154
|
}
|
149
155
|
BrotliTakeBits(br, 3, &n);
|
@@ -160,7 +166,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
|
160
166
|
}
|
161
167
|
}
|
162
168
|
if (n != 0) {
|
163
|
-
s->window_bits =
|
169
|
+
s->window_bits = (8u + n) & 63u;
|
164
170
|
return BROTLI_DECODER_SUCCESS;
|
165
171
|
}
|
166
172
|
s->window_bits = 17;
|
@@ -179,8 +185,8 @@ static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
|
|
179
185
|
|
180
186
|
/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
|
181
187
|
static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
182
|
-
BrotliDecoderState* s, BrotliBitReader* br,
|
183
|
-
|
188
|
+
BrotliDecoderState* s, BrotliBitReader* br, brotli_reg_t* value) {
|
189
|
+
brotli_reg_t bits;
|
184
190
|
switch (s->substate_decode_uint8) {
|
185
191
|
case BROTLI_STATE_DECODE_UINT8_NONE:
|
186
192
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
|
@@ -217,14 +223,14 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
|
217
223
|
|
218
224
|
default:
|
219
225
|
return
|
220
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
226
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
221
227
|
}
|
222
228
|
}
|
223
229
|
|
224
230
|
/* Decodes a metablock length and flags by reading 2 - 31 bits. */
|
225
231
|
static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
226
232
|
BrotliDecoderState* s, BrotliBitReader* br) {
|
227
|
-
|
233
|
+
brotli_reg_t bits;
|
228
234
|
int i;
|
229
235
|
for (;;) {
|
230
236
|
switch (s->substate_metablock_header) {
|
@@ -338,7 +344,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
338
344
|
|
339
345
|
default:
|
340
346
|
return
|
341
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
347
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
342
348
|
}
|
343
349
|
}
|
344
350
|
}
|
@@ -347,13 +353,13 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
347
353
|
This method doesn't read data from the bit reader, BUT drops the amount of
|
348
354
|
bits that correspond to the decoded symbol.
|
349
355
|
bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
|
350
|
-
static BROTLI_INLINE
|
351
|
-
|
352
|
-
|
356
|
+
static BROTLI_INLINE brotli_reg_t DecodeSymbol(brotli_reg_t bits,
|
357
|
+
const HuffmanCode* table,
|
358
|
+
BrotliBitReader* br) {
|
353
359
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
354
360
|
BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK);
|
355
361
|
if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) {
|
356
|
-
|
362
|
+
brotli_reg_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
|
357
363
|
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
358
364
|
BROTLI_HC_ADJUST_TABLE_INDEX(table,
|
359
365
|
BROTLI_HC_FAST_LOAD_VALUE(table) +
|
@@ -365,17 +371,17 @@ static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
|
|
365
371
|
|
366
372
|
/* Reads and decodes the next Huffman code from bit-stream.
|
367
373
|
This method peeks 16 bits of input and drops 0 - 15 of them. */
|
368
|
-
static BROTLI_INLINE
|
369
|
-
|
374
|
+
static BROTLI_INLINE brotli_reg_t ReadSymbol(const HuffmanCode* table,
|
375
|
+
BrotliBitReader* br) {
|
370
376
|
return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br);
|
371
377
|
}
|
372
378
|
|
373
379
|
/* Same as DecodeSymbol, but it is known that there is less than 15 bits of
|
374
380
|
input are currently available. */
|
375
381
|
static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
376
|
-
const HuffmanCode* table, BrotliBitReader* br,
|
377
|
-
|
378
|
-
|
382
|
+
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
383
|
+
brotli_reg_t val;
|
384
|
+
brotli_reg_t available_bits = BrotliGetAvailableBits(br);
|
379
385
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
380
386
|
if (available_bits == 0) {
|
381
387
|
if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) {
|
@@ -384,7 +390,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
384
390
|
}
|
385
391
|
return BROTLI_FALSE; /* No valid bits at all. */
|
386
392
|
}
|
387
|
-
val =
|
393
|
+
val = BrotliGetBitsUnmasked(br);
|
388
394
|
BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK);
|
389
395
|
if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) {
|
390
396
|
if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) {
|
@@ -413,8 +419,8 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
413
419
|
}
|
414
420
|
|
415
421
|
static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
416
|
-
const HuffmanCode* table, BrotliBitReader* br,
|
417
|
-
|
422
|
+
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
423
|
+
brotli_reg_t val;
|
418
424
|
if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
|
419
425
|
*result = DecodeSymbol(val, table, br);
|
420
426
|
return BROTLI_TRUE;
|
@@ -426,8 +432,8 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
|
426
432
|
static BROTLI_INLINE void PreloadSymbol(int safe,
|
427
433
|
const HuffmanCode* table,
|
428
434
|
BrotliBitReader* br,
|
429
|
-
|
430
|
-
|
435
|
+
brotli_reg_t* bits,
|
436
|
+
brotli_reg_t* value) {
|
431
437
|
if (safe) {
|
432
438
|
return;
|
433
439
|
}
|
@@ -439,15 +445,15 @@ static BROTLI_INLINE void PreloadSymbol(int safe,
|
|
439
445
|
|
440
446
|
/* Decodes the next Huffman code using data prepared by PreloadSymbol.
|
441
447
|
Reads 0 - 15 bits. Also peeks 8 following bits. */
|
442
|
-
static BROTLI_INLINE
|
448
|
+
static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
|
443
449
|
BrotliBitReader* br,
|
444
|
-
|
445
|
-
|
446
|
-
|
450
|
+
brotli_reg_t* bits,
|
451
|
+
brotli_reg_t* value) {
|
452
|
+
brotli_reg_t result = *value;
|
447
453
|
if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
|
448
|
-
|
454
|
+
brotli_reg_t val = BrotliGet16BitsUnmasked(br);
|
449
455
|
const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
|
450
|
-
|
456
|
+
brotli_reg_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
|
451
457
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext);
|
452
458
|
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
453
459
|
BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask);
|
@@ -460,8 +466,8 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
|
|
460
466
|
return result;
|
461
467
|
}
|
462
468
|
|
463
|
-
static BROTLI_INLINE
|
464
|
-
|
469
|
+
static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) {
|
470
|
+
brotli_reg_t result = 0;
|
465
471
|
while (x) {
|
466
472
|
x >>= 1;
|
467
473
|
++result;
|
@@ -473,16 +479,16 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
|
|
473
479
|
Totally 1..4 symbols are read, 1..11 bits each.
|
474
480
|
The list of symbols MUST NOT contain duplicates. */
|
475
481
|
static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
476
|
-
|
482
|
+
brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
|
477
483
|
BrotliDecoderState* s) {
|
478
484
|
/* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */
|
479
485
|
BrotliBitReader* br = &s->br;
|
480
486
|
BrotliMetablockHeaderArena* h = &s->arena.header;
|
481
|
-
|
482
|
-
|
483
|
-
|
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;
|
484
490
|
while (i <= num_symbols) {
|
485
|
-
|
491
|
+
brotli_reg_t v;
|
486
492
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
|
487
493
|
h->sub_loop_counter = i;
|
488
494
|
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
|
@@ -498,7 +504,7 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
|
498
504
|
}
|
499
505
|
|
500
506
|
for (i = 0; i < num_symbols; ++i) {
|
501
|
-
|
507
|
+
brotli_reg_t k = i + 1;
|
502
508
|
for (; k <= num_symbols; ++k) {
|
503
509
|
if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) {
|
504
510
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
|
@@ -515,9 +521,9 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
|
515
521
|
C) extend corresponding index-chain
|
516
522
|
D) reduce the Huffman space
|
517
523
|
E) update the histogram */
|
518
|
-
static BROTLI_INLINE void ProcessSingleCodeLength(
|
519
|
-
|
520
|
-
|
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,
|
521
527
|
uint16_t* code_length_histo, int* next_symbol) {
|
522
528
|
*repeat = 0;
|
523
529
|
if (code_len != 0) { /* code_len == 1..15 */
|
@@ -542,14 +548,14 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
|
542
548
|
|
543
549
|
PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or
|
544
550
|
code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
545
|
-
static BROTLI_INLINE void ProcessRepeatedCodeLength(
|
546
|
-
|
547
|
-
|
548
|
-
|
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,
|
549
555
|
uint16_t* code_length_histo, int* next_symbol) {
|
550
|
-
|
551
|
-
|
552
|
-
|
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 */
|
553
559
|
if (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
554
560
|
new_len = *prev_code_len;
|
555
561
|
extra_bits = 2;
|
@@ -574,7 +580,7 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
|
574
580
|
BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
|
575
581
|
(int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len));
|
576
582
|
if (*repeat_code_len != 0) {
|
577
|
-
|
583
|
+
brotli_reg_t last = *symbol + repeat_delta;
|
578
584
|
int next = next_symbol[*repeat_code_len];
|
579
585
|
do {
|
580
586
|
symbol_lists[next] = (uint16_t)*symbol;
|
@@ -591,14 +597,14 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
|
591
597
|
|
592
598
|
/* Reads and decodes symbol codelengths. */
|
593
599
|
static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
594
|
-
|
600
|
+
brotli_reg_t alphabet_size, BrotliDecoderState* s) {
|
595
601
|
BrotliBitReader* br = &s->br;
|
596
602
|
BrotliMetablockHeaderArena* h = &s->arena.header;
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
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;
|
602
608
|
uint16_t* symbol_lists = h->symbol_lists;
|
603
609
|
uint16_t* code_length_histo = h->code_length_histo;
|
604
610
|
int* next_symbol = h->next_symbol;
|
@@ -607,9 +613,9 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
607
613
|
}
|
608
614
|
while (symbol < alphabet_size && space > 0) {
|
609
615
|
const HuffmanCode* p = h->table;
|
610
|
-
|
616
|
+
brotli_reg_t code_len;
|
611
617
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
612
|
-
if (!BrotliCheckInputAmount(br
|
618
|
+
if (!BrotliCheckInputAmount(br)) {
|
613
619
|
h->symbol = symbol;
|
614
620
|
h->repeat = repeat;
|
615
621
|
h->prev_code_len = prev_code_len;
|
@@ -626,10 +632,10 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
626
632
|
ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
|
627
633
|
&prev_code_len, symbol_lists, code_length_histo, next_symbol);
|
628
634
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
629
|
-
|
635
|
+
brotli_reg_t extra_bits =
|
630
636
|
(code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;
|
631
|
-
|
632
|
-
|
637
|
+
brotli_reg_t repeat_delta =
|
638
|
+
BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
|
633
639
|
BrotliDropBits(br, extra_bits);
|
634
640
|
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
635
641
|
&symbol, &repeat, &space, &prev_code_len, &repeat_code_len,
|
@@ -641,15 +647,15 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
641
647
|
}
|
642
648
|
|
643
649
|
static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
644
|
-
|
650
|
+
brotli_reg_t alphabet_size, BrotliDecoderState* s) {
|
645
651
|
BrotliBitReader* br = &s->br;
|
646
652
|
BrotliMetablockHeaderArena* h = &s->arena.header;
|
647
653
|
BROTLI_BOOL get_byte = BROTLI_FALSE;
|
648
654
|
while (h->symbol < alphabet_size && h->space > 0) {
|
649
655
|
const HuffmanCode* p = h->table;
|
650
|
-
|
651
|
-
|
652
|
-
|
656
|
+
brotli_reg_t code_len;
|
657
|
+
brotli_reg_t available_bits;
|
658
|
+
brotli_reg_t bits = 0;
|
653
659
|
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
654
660
|
if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
655
661
|
get_byte = BROTLI_FALSE;
|
@@ -670,8 +676,8 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
670
676
|
&h->prev_code_len, h->symbol_lists, h->code_length_histo,
|
671
677
|
h->next_symbol);
|
672
678
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
673
|
-
|
674
|
-
|
679
|
+
brotli_reg_t extra_bits = code_len - 14U;
|
680
|
+
brotli_reg_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
|
675
681
|
BitMask(extra_bits);
|
676
682
|
if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) {
|
677
683
|
get_byte = BROTLI_TRUE;
|
@@ -692,15 +698,15 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
692
698
|
static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
693
699
|
BrotliBitReader* br = &s->br;
|
694
700
|
BrotliMetablockHeaderArena* h = &s->arena.header;
|
695
|
-
|
696
|
-
|
697
|
-
|
701
|
+
brotli_reg_t num_codes = h->repeat;
|
702
|
+
brotli_reg_t space = h->space;
|
703
|
+
brotli_reg_t i = h->sub_loop_counter;
|
698
704
|
for (; i < BROTLI_CODE_LENGTH_CODES; ++i) {
|
699
705
|
const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
|
700
|
-
|
701
|
-
|
706
|
+
brotli_reg_t ix;
|
707
|
+
brotli_reg_t v;
|
702
708
|
if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
|
703
|
-
|
709
|
+
brotli_reg_t available_bits = BrotliGetAvailableBits(br);
|
704
710
|
if (available_bits != 0) {
|
705
711
|
ix = BrotliGetBitsUnmasked(br) & 0xF;
|
706
712
|
} else {
|
@@ -745,10 +751,10 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
|
745
751
|
encoded with predefined entropy code. 32 - 74 bits are used.
|
746
752
|
B.2) Decoded table is used to decode code lengths of symbols in resulting
|
747
753
|
Huffman table. In worst case 3520 bits are read. */
|
748
|
-
static BrotliDecoderErrorCode ReadHuffmanCode(
|
749
|
-
|
754
|
+
static BrotliDecoderErrorCode ReadHuffmanCode(brotli_reg_t alphabet_size_max,
|
755
|
+
brotli_reg_t alphabet_size_limit,
|
750
756
|
HuffmanCode* table,
|
751
|
-
|
757
|
+
brotli_reg_t* opt_table_size,
|
752
758
|
BrotliDecoderState* s) {
|
753
759
|
BrotliBitReader* br = &s->br;
|
754
760
|
BrotliMetablockHeaderArena* h = &s->arena.header;
|
@@ -794,9 +800,9 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
|
794
800
|
/* Fall through. */
|
795
801
|
|
796
802
|
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
|
797
|
-
|
803
|
+
brotli_reg_t table_size;
|
798
804
|
if (h->symbol == 3) {
|
799
|
-
|
805
|
+
brotli_reg_t bits;
|
800
806
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
801
807
|
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
|
802
808
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -804,8 +810,9 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
|
804
810
|
h->symbol += bits;
|
805
811
|
}
|
806
812
|
BROTLI_LOG_UINT(h->symbol);
|
807
|
-
table_size = BrotliBuildSimpleHuffmanTable(
|
808
|
-
|
813
|
+
table_size = BrotliBuildSimpleHuffmanTable(table, HUFFMAN_TABLE_BITS,
|
814
|
+
h->symbols_lists_array,
|
815
|
+
(uint32_t)h->symbol);
|
809
816
|
if (opt_table_size) {
|
810
817
|
*opt_table_size = table_size;
|
811
818
|
}
|
@@ -815,7 +822,7 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
|
815
822
|
|
816
823
|
/* Decode Huffman-coded code lengths. */
|
817
824
|
case BROTLI_STATE_HUFFMAN_COMPLEX: {
|
818
|
-
|
825
|
+
brotli_reg_t i;
|
819
826
|
BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);
|
820
827
|
if (result != BROTLI_DECODER_SUCCESS) {
|
821
828
|
return result;
|
@@ -839,7 +846,7 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
|
839
846
|
/* Fall through. */
|
840
847
|
|
841
848
|
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
|
842
|
-
|
849
|
+
brotli_reg_t table_size;
|
843
850
|
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
|
844
851
|
alphabet_size_limit, s);
|
845
852
|
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
@@ -864,16 +871,16 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
|
864
871
|
|
865
872
|
default:
|
866
873
|
return
|
867
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
874
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
868
875
|
}
|
869
876
|
}
|
870
877
|
}
|
871
878
|
|
872
879
|
/* Decodes a block length by reading 3..39 bits. */
|
873
|
-
static BROTLI_INLINE
|
874
|
-
|
875
|
-
|
876
|
-
|
880
|
+
static BROTLI_INLINE brotli_reg_t ReadBlockLength(const HuffmanCode* table,
|
881
|
+
BrotliBitReader* br) {
|
882
|
+
brotli_reg_t code;
|
883
|
+
brotli_reg_t nbits;
|
877
884
|
code = ReadSymbol(table, br);
|
878
885
|
nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */
|
879
886
|
return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits);
|
@@ -882,9 +889,9 @@ static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
|
|
882
889
|
/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
|
883
890
|
reading can't be continued with ReadBlockLength. */
|
884
891
|
static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
885
|
-
BrotliDecoderState* s,
|
892
|
+
BrotliDecoderState* s, brotli_reg_t* result, const HuffmanCode* table,
|
886
893
|
BrotliBitReader* br) {
|
887
|
-
|
894
|
+
brotli_reg_t index;
|
888
895
|
if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) {
|
889
896
|
if (!SafeReadSymbol(table, br, &index)) {
|
890
897
|
return BROTLI_FALSE;
|
@@ -893,9 +900,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
|
893
900
|
index = s->block_length_index;
|
894
901
|
}
|
895
902
|
{
|
896
|
-
|
897
|
-
|
898
|
-
|
903
|
+
brotli_reg_t bits;
|
904
|
+
brotli_reg_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
|
905
|
+
brotli_reg_t offset = _kBrotliPrefixCodeRanges[index].offset;
|
899
906
|
if (!BrotliSafeReadBits(br, nbits, &bits)) {
|
900
907
|
s->block_length_index = index;
|
901
908
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
|
@@ -922,10 +929,10 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
|
922
929
|
Most of input values are 0 and 1. To reduce number of branches, we replace
|
923
930
|
inner for loop with do-while. */
|
924
931
|
static BROTLI_NOINLINE void InverseMoveToFrontTransform(
|
925
|
-
uint8_t* v,
|
932
|
+
uint8_t* v, brotli_reg_t v_len, BrotliDecoderState* state) {
|
926
933
|
/* Reinitialize elements that could have been changed. */
|
927
|
-
|
928
|
-
|
934
|
+
brotli_reg_t i = 1;
|
935
|
+
brotli_reg_t upper_bound = state->mtf_upper_bound;
|
929
936
|
uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */
|
930
937
|
uint8_t* mtf_u8 = (uint8_t*)mtf;
|
931
938
|
/* Load endian-aware constant. */
|
@@ -968,7 +975,7 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
|
968
975
|
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
|
969
976
|
}
|
970
977
|
while (h->htree_index < group->num_htrees) {
|
971
|
-
|
978
|
+
brotli_reg_t table_size;
|
972
979
|
BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max,
|
973
980
|
group->alphabet_size_limit, h->next, &table_size, s);
|
974
981
|
if (result != BROTLI_DECODER_SUCCESS) return result;
|
@@ -988,8 +995,8 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
|
988
995
|
This table will be used for reading context map items.
|
989
996
|
3) Read context map items; "0" values could be run-length encoded.
|
990
997
|
4) Optionally, apply InverseMoveToFront transform to the resulting map. */
|
991
|
-
static BrotliDecoderErrorCode DecodeContextMap(
|
992
|
-
|
998
|
+
static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
|
999
|
+
brotli_reg_t* num_htrees,
|
993
1000
|
uint8_t** context_map_arg,
|
994
1001
|
BrotliDecoderState* s) {
|
995
1002
|
BrotliBitReader* br = &s->br;
|
@@ -1019,7 +1026,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1019
1026
|
/* Fall through. */
|
1020
1027
|
|
1021
1028
|
case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
|
1022
|
-
|
1029
|
+
brotli_reg_t bits;
|
1023
1030
|
/* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
|
1024
1031
|
to peek 4 bits ahead. */
|
1025
1032
|
if (!BrotliSafeGetBits(br, 5, &bits)) {
|
@@ -1038,7 +1045,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1038
1045
|
/* Fall through. */
|
1039
1046
|
|
1040
1047
|
case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {
|
1041
|
-
|
1048
|
+
brotli_reg_t alphabet_size = *num_htrees + h->max_run_length_prefix;
|
1042
1049
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
1043
1050
|
h->context_map_table, NULL, s);
|
1044
1051
|
if (result != BROTLI_DECODER_SUCCESS) return result;
|
@@ -1048,10 +1055,10 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1048
1055
|
/* Fall through. */
|
1049
1056
|
|
1050
1057
|
case BROTLI_STATE_CONTEXT_MAP_DECODE: {
|
1051
|
-
|
1052
|
-
|
1058
|
+
brotli_reg_t context_index = h->context_index;
|
1059
|
+
brotli_reg_t max_run_length_prefix = h->max_run_length_prefix;
|
1053
1060
|
uint8_t* context_map = *context_map_arg;
|
1054
|
-
|
1061
|
+
brotli_reg_t code = h->code;
|
1055
1062
|
BROTLI_BOOL skip_preamble = (code != 0xFFFF);
|
1056
1063
|
while (context_index < context_map_size || skip_preamble) {
|
1057
1064
|
if (!skip_preamble) {
|
@@ -1076,7 +1083,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1076
1083
|
}
|
1077
1084
|
/* RLE sub-stage. */
|
1078
1085
|
{
|
1079
|
-
|
1086
|
+
brotli_reg_t reps;
|
1080
1087
|
if (!BrotliSafeReadBits(br, code, &reps)) {
|
1081
1088
|
h->code = code;
|
1082
1089
|
h->context_index = context_index;
|
@@ -1097,7 +1104,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1097
1104
|
/* Fall through. */
|
1098
1105
|
|
1099
1106
|
case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
|
1100
|
-
|
1107
|
+
brotli_reg_t bits;
|
1101
1108
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
1102
1109
|
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
|
1103
1110
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -1111,7 +1118,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1111
1118
|
|
1112
1119
|
default:
|
1113
1120
|
return
|
1114
|
-
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
1121
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
1115
1122
|
}
|
1116
1123
|
}
|
1117
1124
|
|
@@ -1119,14 +1126,14 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
1119
1126
|
Reads 3..54 bits. */
|
1120
1127
|
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
|
1121
1128
|
int safe, BrotliDecoderState* s, int tree_type) {
|
1122
|
-
|
1129
|
+
brotli_reg_t max_block_type = s->num_block_types[tree_type];
|
1123
1130
|
const HuffmanCode* type_tree = &s->block_type_trees[
|
1124
1131
|
tree_type * BROTLI_HUFFMAN_MAX_SIZE_258];
|
1125
1132
|
const HuffmanCode* len_tree = &s->block_len_trees[
|
1126
1133
|
tree_type * BROTLI_HUFFMAN_MAX_SIZE_26];
|
1127
1134
|
BrotliBitReader* br = &s->br;
|
1128
|
-
|
1129
|
-
|
1135
|
+
brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
|
1136
|
+
brotli_reg_t block_type;
|
1130
1137
|
if (max_block_type <= 1) {
|
1131
1138
|
return BROTLI_FALSE;
|
1132
1139
|
}
|
@@ -1171,7 +1178,8 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
|
1171
1178
|
size_t sample = s->context_map[offset];
|
1172
1179
|
size_t j;
|
1173
1180
|
for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) {
|
1174
|
-
|
1181
|
+
/* NOLINTNEXTLINE(bugprone-macro-repeated-side-effects) */
|
1182
|
+
BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; })
|
1175
1183
|
}
|
1176
1184
|
if (error == 0) {
|
1177
1185
|
s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31);
|
@@ -1182,8 +1190,8 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
|
1182
1190
|
static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
|
1183
1191
|
uint8_t context_mode;
|
1184
1192
|
size_t trivial;
|
1185
|
-
|
1186
|
-
|
1193
|
+
brotli_reg_t block_type = s->block_type_rb[1];
|
1194
|
+
brotli_reg_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS;
|
1187
1195
|
s->context_map_slice = s->context_map + context_offset;
|
1188
1196
|
trivial = s->trivial_literal_contexts[block_type >> 5];
|
1189
1197
|
s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;
|
@@ -1352,10 +1360,61 @@ static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer(
|
|
1352
1360
|
return BROTLI_TRUE;
|
1353
1361
|
}
|
1354
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
|
+
|
1355
1414
|
static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
1356
1415
|
size_t* available_out, uint8_t** next_out, size_t* total_out,
|
1357
1416
|
BrotliDecoderState* s) {
|
1358
|
-
/* TODO: avoid allocation for single uncompressed block. */
|
1417
|
+
/* TODO(eustas): avoid allocation for single uncompressed block. */
|
1359
1418
|
if (!BrotliEnsureRingBuffer(s)) {
|
1360
1419
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1);
|
1361
1420
|
}
|
@@ -1403,6 +1462,115 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|
1403
1462
|
BROTLI_DCHECK(0); /* Unreachable */
|
1404
1463
|
}
|
1405
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
|
+
|
1406
1574
|
/* Calculates the smallest feasible ring buffer.
|
1407
1575
|
|
1408
1576
|
If we know the data size is small, do not allocate more ring buffer
|
@@ -1454,7 +1622,7 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
|
|
1454
1622
|
int i = s->loop_counter;
|
1455
1623
|
|
1456
1624
|
while (i < (int)s->num_block_types[0]) {
|
1457
|
-
|
1625
|
+
brotli_reg_t bits;
|
1458
1626
|
if (!BrotliSafeReadBits(br, 2, &bits)) {
|
1459
1627
|
s->loop_counter = i;
|
1460
1628
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -1494,7 +1662,7 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
|
|
1494
1662
|
}
|
1495
1663
|
|
1496
1664
|
static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
1497
|
-
BrotliBitReader* const br,
|
1665
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
1498
1666
|
if (n_bits != 0) {
|
1499
1667
|
return BrotliSafeReadBits(br, n_bits, val);
|
1500
1668
|
} else {
|
@@ -1504,7 +1672,7 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
|
1504
1672
|
}
|
1505
1673
|
|
1506
1674
|
static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
|
1507
|
-
BrotliBitReader* const br,
|
1675
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
1508
1676
|
if (n_bits != 0) {
|
1509
1677
|
return BrotliSafeReadBits32(br, n_bits, val);
|
1510
1678
|
} else {
|
@@ -1582,16 +1750,16 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
|
|
1582
1750
|
NB: it is possible to have all 64 tables precalculated. */
|
1583
1751
|
static void CalculateDistanceLut(BrotliDecoderState* s) {
|
1584
1752
|
BrotliMetablockBodyArena* b = &s->arena.body;
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
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;
|
1592
1760
|
|
1593
1761
|
/* Skip short codes. */
|
1594
|
-
|
1762
|
+
brotli_reg_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
|
1595
1763
|
|
1596
1764
|
/* Fill direct codes. */
|
1597
1765
|
for (j = 0; j < ndirect; ++j) {
|
@@ -1602,7 +1770,7 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
|
|
1602
1770
|
|
1603
1771
|
/* Fill regular distance codes. */
|
1604
1772
|
while (i < alphabet_size_limit) {
|
1605
|
-
|
1773
|
+
brotli_reg_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
|
1606
1774
|
/* Always fill the complete group. */
|
1607
1775
|
for (j = 0; j < postfix; ++j) {
|
1608
1776
|
b->dist_extra_bits[i] = (uint8_t)bits;
|
@@ -1618,8 +1786,8 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
|
|
1618
1786
|
static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
|
1619
1787
|
int safe, BrotliDecoderState* s, BrotliBitReader* br) {
|
1620
1788
|
BrotliMetablockBodyArena* b = &s->arena.body;
|
1621
|
-
|
1622
|
-
|
1789
|
+
brotli_reg_t code;
|
1790
|
+
brotli_reg_t bits;
|
1623
1791
|
BrotliBitReaderState memento;
|
1624
1792
|
HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
|
1625
1793
|
if (!safe) {
|
@@ -1665,9 +1833,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadDistance(
|
|
1665
1833
|
|
1666
1834
|
static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
|
1667
1835
|
int safe, BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) {
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1836
|
+
brotli_reg_t cmd_code;
|
1837
|
+
brotli_reg_t insert_len_extra = 0;
|
1838
|
+
brotli_reg_t copy_length;
|
1671
1839
|
CmdLutElement v;
|
1672
1840
|
BrotliBitReaderState memento;
|
1673
1841
|
if (!safe) {
|
@@ -1712,11 +1880,11 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadCommand(
|
|
1712
1880
|
}
|
1713
1881
|
|
1714
1882
|
static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
|
1715
|
-
int safe, BrotliBitReader* const br
|
1883
|
+
int safe, BrotliBitReader* const br) {
|
1716
1884
|
if (safe) {
|
1717
1885
|
return BROTLI_TRUE;
|
1718
1886
|
}
|
1719
|
-
return BrotliCheckInputAmount(br
|
1887
|
+
return BrotliCheckInputAmount(br);
|
1720
1888
|
}
|
1721
1889
|
|
1722
1890
|
#define BROTLI_SAFE(METHOD) \
|
@@ -1737,8 +1905,9 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
|
|
1737
1905
|
int i = s->loop_counter;
|
1738
1906
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
1739
1907
|
BrotliBitReader* br = &s->br;
|
1908
|
+
int compound_dictionary_size = GetCompoundDictionarySize(s);
|
1740
1909
|
|
1741
|
-
if (!CheckInputAmount(safe, br
|
1910
|
+
if (!CheckInputAmount(safe, br)) {
|
1742
1911
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1743
1912
|
goto saveStateAndReturn;
|
1744
1913
|
}
|
@@ -1756,14 +1925,14 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
|
|
1756
1925
|
} else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
|
1757
1926
|
goto CommandPostWrapCopy;
|
1758
1927
|
} else {
|
1759
|
-
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
1928
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */
|
1760
1929
|
}
|
1761
1930
|
|
1762
1931
|
CommandBegin:
|
1763
1932
|
if (safe) {
|
1764
1933
|
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
1765
1934
|
}
|
1766
|
-
if (!CheckInputAmount(safe, br
|
1935
|
+
if (!CheckInputAmount(safe, br)) {
|
1767
1936
|
s->state = BROTLI_STATE_COMMAND_BEGIN;
|
1768
1937
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1769
1938
|
goto saveStateAndReturn;
|
@@ -1787,25 +1956,23 @@ CommandInner:
|
|
1787
1956
|
}
|
1788
1957
|
/* Read the literals in the command. */
|
1789
1958
|
if (s->trivial_literal_context) {
|
1790
|
-
|
1791
|
-
|
1959
|
+
brotli_reg_t bits;
|
1960
|
+
brotli_reg_t value;
|
1792
1961
|
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
1793
1962
|
do {
|
1794
|
-
if (!CheckInputAmount(safe, br
|
1963
|
+
if (!CheckInputAmount(safe, br)) {
|
1795
1964
|
s->state = BROTLI_STATE_COMMAND_INNER;
|
1796
1965
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1797
1966
|
goto saveStateAndReturn;
|
1798
1967
|
}
|
1799
1968
|
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
|
1800
|
-
|
1801
|
-
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
1802
|
-
if (!s->trivial_literal_context) goto CommandInner;
|
1969
|
+
goto NextLiteralBlock;
|
1803
1970
|
}
|
1804
1971
|
if (!safe) {
|
1805
1972
|
s->ringbuffer[pos] =
|
1806
1973
|
(uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
|
1807
1974
|
} else {
|
1808
|
-
|
1975
|
+
brotli_reg_t literal;
|
1809
1976
|
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
|
1810
1977
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1811
1978
|
goto saveStateAndReturn;
|
@@ -1827,14 +1994,13 @@ CommandInner:
|
|
1827
1994
|
do {
|
1828
1995
|
const HuffmanCode* hc;
|
1829
1996
|
uint8_t context;
|
1830
|
-
if (!CheckInputAmount(safe, br
|
1997
|
+
if (!CheckInputAmount(safe, br)) {
|
1831
1998
|
s->state = BROTLI_STATE_COMMAND_INNER;
|
1832
1999
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1833
2000
|
goto saveStateAndReturn;
|
1834
2001
|
}
|
1835
2002
|
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
|
1836
|
-
|
1837
|
-
if (s->trivial_literal_context) goto CommandInner;
|
2003
|
+
goto NextLiteralBlock;
|
1838
2004
|
}
|
1839
2005
|
context = BROTLI_CONTEXT(p1, p2, s->context_lookup);
|
1840
2006
|
BROTLI_LOG_UINT(context);
|
@@ -1843,7 +2009,7 @@ CommandInner:
|
|
1843
2009
|
if (!safe) {
|
1844
2010
|
p1 = (uint8_t)ReadSymbol(hc, br);
|
1845
2011
|
} else {
|
1846
|
-
|
2012
|
+
brotli_reg_t literal;
|
1847
2013
|
if (!SafeReadSymbol(hc, br, &literal)) {
|
1848
2014
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1849
2015
|
goto saveStateAndReturn;
|
@@ -1903,20 +2069,75 @@ CommandPostDecodeLiterals:
|
|
1903
2069
|
pos, s->distance_code, i, s->meta_block_remaining_len));
|
1904
2070
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DISTANCE);
|
1905
2071
|
}
|
1906
|
-
if (
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
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;
|
1914
2096
|
int mask = (int)BitMask(shift);
|
1915
2097
|
int word_idx = address & mask;
|
1916
2098
|
int transform_idx = address >> shift;
|
1917
2099
|
/* Compensate double distance-ring-buffer roll. */
|
1918
2100
|
s->dist_rb_idx += s->distance_context;
|
1919
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
|
+
}
|
1920
2141
|
if (BROTLI_PREDICT_FALSE(!words->data)) {
|
1921
2142
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET);
|
1922
2143
|
}
|
@@ -1933,6 +2154,10 @@ CommandPostDecodeLiterals:
|
|
1933
2154
|
BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s],"
|
1934
2155
|
" transform_idx = %d, transformed: [%.*s]\n",
|
1935
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
|
+
}
|
1936
2161
|
}
|
1937
2162
|
pos += len;
|
1938
2163
|
s->meta_block_remaining_len -= len;
|
@@ -2014,6 +2239,10 @@ CommandPostWrapCopy:
|
|
2014
2239
|
goto CommandBegin;
|
2015
2240
|
}
|
2016
2241
|
|
2242
|
+
NextLiteralBlock:
|
2243
|
+
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
|
2244
|
+
goto CommandInner;
|
2245
|
+
|
2017
2246
|
saveStateAndReturn:
|
2018
2247
|
s->pos = pos;
|
2019
2248
|
s->loop_counter = i;
|
@@ -2033,8 +2262,10 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands(
|
|
2033
2262
|
}
|
2034
2263
|
|
2035
2264
|
BrotliDecoderResult BrotliDecoderDecompress(
|
2036
|
-
size_t encoded_size,
|
2037
|
-
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)]) {
|
2038
2269
|
BrotliDecoderState s;
|
2039
2270
|
BrotliDecoderResult result;
|
2040
2271
|
size_t total_out = 0;
|
@@ -2071,6 +2302,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2071
2302
|
size_t* available_out, uint8_t** next_out, size_t* total_out) {
|
2072
2303
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
2073
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)
|
2074
2308
|
/* Ensure that |total_out| is set, even if no data will ever be pushed out. */
|
2075
2309
|
if (total_out) {
|
2076
2310
|
*total_out = s->partial_pos_out;
|
@@ -2080,19 +2314,18 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2080
2314
|
return BROTLI_DECODER_RESULT_ERROR;
|
2081
2315
|
}
|
2082
2316
|
if (*available_out && (!next_out || !*next_out)) {
|
2083
|
-
return
|
2084
|
-
|
2317
|
+
return BROTLI_SAVE_ERROR_CODE(
|
2318
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
|
2085
2319
|
}
|
2086
2320
|
if (!*available_out) next_out = 0;
|
2087
2321
|
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
|
2088
|
-
br
|
2089
|
-
br->next_in = *next_in;
|
2322
|
+
BrotliBitReaderSetInput(br, *next_in, *available_in);
|
2090
2323
|
} else {
|
2091
2324
|
/* At least one byte of input is required. More than one byte of input may
|
2092
2325
|
be required to complete the transaction -> reading more data must be
|
2093
2326
|
done in a loop -> do it in a main loop. */
|
2094
2327
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2095
|
-
br
|
2328
|
+
BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length);
|
2096
2329
|
}
|
2097
2330
|
/* State machine */
|
2098
2331
|
for (;;) {
|
@@ -2109,23 +2342,23 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2109
2342
|
}
|
2110
2343
|
}
|
2111
2344
|
if (s->buffer_length != 0) { /* Used with internal buffer. */
|
2112
|
-
if (br->
|
2345
|
+
if (br->next_in == br->last_in) {
|
2113
2346
|
/* Successfully finished read transaction.
|
2114
2347
|
Accumulator contains less than 8 bits, because internal buffer
|
2115
2348
|
is expanded byte-by-byte until it is enough to complete read. */
|
2116
2349
|
s->buffer_length = 0;
|
2117
2350
|
/* Switch to input stream and restart. */
|
2118
2351
|
result = BROTLI_DECODER_SUCCESS;
|
2119
|
-
br
|
2120
|
-
br->next_in = *next_in;
|
2352
|
+
BrotliBitReaderSetInput(br, *next_in, *available_in);
|
2121
2353
|
continue;
|
2122
2354
|
} else if (*available_in != 0) {
|
2123
2355
|
/* Not enough data in buffer, but can take one more byte from
|
2124
2356
|
input stream. */
|
2125
2357
|
result = BROTLI_DECODER_SUCCESS;
|
2358
|
+
BROTLI_DCHECK(s->buffer_length < 8);
|
2126
2359
|
s->buffer.u8[s->buffer_length] = **next_in;
|
2127
2360
|
s->buffer_length++;
|
2128
|
-
br->
|
2361
|
+
BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length);
|
2129
2362
|
(*next_in)++;
|
2130
2363
|
(*available_in)--;
|
2131
2364
|
/* Retry with more data in buffer. */
|
@@ -2136,7 +2369,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2136
2369
|
} else { /* Input stream doesn't contain enough input. */
|
2137
2370
|
/* Copy tail to internal buffer and return. */
|
2138
2371
|
*next_in = br->next_in;
|
2139
|
-
*available_in = br
|
2372
|
+
*available_in = BrotliBitReaderGetAvailIn(br);
|
2140
2373
|
while (*available_in) {
|
2141
2374
|
s->buffer.u8[s->buffer_length] = **next_in;
|
2142
2375
|
s->buffer_length++;
|
@@ -2159,7 +2392,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2159
2392
|
stream it has less than 8 bits in accumulator, so it is safe to
|
2160
2393
|
return unused accumulator bits there. */
|
2161
2394
|
BrotliBitReaderUnload(br);
|
2162
|
-
*available_in = br
|
2395
|
+
*available_in = BrotliBitReaderGetAvailIn(br);
|
2163
2396
|
*next_in = br->next_in;
|
2164
2397
|
}
|
2165
2398
|
break;
|
@@ -2183,17 +2416,20 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2183
2416
|
s->state = BROTLI_STATE_INITIALIZE;
|
2184
2417
|
break;
|
2185
2418
|
|
2186
|
-
case BROTLI_STATE_LARGE_WINDOW_BITS:
|
2187
|
-
|
2419
|
+
case BROTLI_STATE_LARGE_WINDOW_BITS: {
|
2420
|
+
brotli_reg_t bits;
|
2421
|
+
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
2188
2422
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2189
2423
|
break;
|
2190
2424
|
}
|
2425
|
+
s->window_bits = bits & 63u;
|
2191
2426
|
if (s->window_bits < BROTLI_LARGE_MIN_WBITS ||
|
2192
2427
|
s->window_bits > BROTLI_LARGE_MAX_WBITS) {
|
2193
2428
|
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
|
2194
2429
|
break;
|
2195
2430
|
}
|
2196
2431
|
s->state = BROTLI_STATE_INITIALIZE;
|
2432
|
+
}
|
2197
2433
|
/* Fall through. */
|
2198
2434
|
|
2199
2435
|
case BROTLI_STATE_INITIALIZE:
|
@@ -2238,6 +2474,10 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2238
2474
|
}
|
2239
2475
|
if (s->is_metadata) {
|
2240
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
|
+
}
|
2241
2481
|
break;
|
2242
2482
|
}
|
2243
2483
|
if (s->meta_block_remaining_len == 0) {
|
@@ -2287,7 +2527,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2287
2527
|
/* Fall through. */
|
2288
2528
|
|
2289
2529
|
case BROTLI_STATE_HUFFMAN_CODE_1: {
|
2290
|
-
|
2530
|
+
brotli_reg_t alphabet_size = s->num_block_types[s->loop_counter] + 2;
|
2291
2531
|
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
|
2292
2532
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
2293
2533
|
&s->block_type_trees[tree_offset], NULL, s);
|
@@ -2297,7 +2537,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2297
2537
|
/* Fall through. */
|
2298
2538
|
|
2299
2539
|
case BROTLI_STATE_HUFFMAN_CODE_2: {
|
2300
|
-
|
2540
|
+
brotli_reg_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;
|
2301
2541
|
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
|
2302
2542
|
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
2303
2543
|
&s->block_len_trees[tree_offset], NULL, s);
|
@@ -2330,21 +2570,15 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2330
2570
|
}
|
2331
2571
|
|
2332
2572
|
case BROTLI_STATE_METADATA:
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
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;
|
2573
|
+
result = SkipMetadataBlock(s);
|
2574
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
2575
|
+
break;
|
2343
2576
|
}
|
2577
|
+
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2344
2578
|
break;
|
2345
2579
|
|
2346
2580
|
case BROTLI_STATE_METABLOCK_HEADER_2: {
|
2347
|
-
|
2581
|
+
brotli_reg_t bits;
|
2348
2582
|
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
2349
2583
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
2350
2584
|
break;
|
@@ -2385,15 +2619,16 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2385
2619
|
/* Fall through. */
|
2386
2620
|
|
2387
2621
|
case BROTLI_STATE_CONTEXT_MAP_2: {
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
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(
|
2391
2625
|
npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
|
2392
|
-
|
2626
|
+
brotli_reg_t distance_alphabet_size_limit = distance_alphabet_size_max;
|
2393
2627
|
BROTLI_BOOL allocation_success = BROTLI_TRUE;
|
2394
2628
|
if (s->large_window) {
|
2395
2629
|
BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
|
2396
|
-
BROTLI_MAX_ALLOWED_DISTANCE, npostfix,
|
2630
|
+
BROTLI_MAX_ALLOWED_DISTANCE, (uint32_t)npostfix,
|
2631
|
+
(uint32_t)ndirect);
|
2397
2632
|
distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
2398
2633
|
npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
|
2399
2634
|
distance_alphabet_size_limit = limit.max_alphabet_size;
|
@@ -2414,7 +2649,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2414
2649
|
s, &s->distance_hgroup, distance_alphabet_size_max,
|
2415
2650
|
distance_alphabet_size_limit, s->num_dist_htrees);
|
2416
2651
|
if (!allocation_success) {
|
2417
|
-
return
|
2652
|
+
return BROTLI_SAVE_ERROR_CODE(
|
2418
2653
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
|
2419
2654
|
}
|
2420
2655
|
s->loop_counter = 0;
|
@@ -2428,8 +2663,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2428
2663
|
case 0: hgroup = &s->literal_hgroup; break;
|
2429
2664
|
case 1: hgroup = &s->insert_copy_hgroup; break;
|
2430
2665
|
case 2: hgroup = &s->distance_hgroup; break;
|
2431
|
-
default: return
|
2432
|
-
BROTLI_DECODER_ERROR_UNREACHABLE));
|
2666
|
+
default: return BROTLI_SAVE_ERROR_CODE(BROTLI_FAILURE(
|
2667
|
+
BROTLI_DECODER_ERROR_UNREACHABLE)); /* COV_NF_LINE */
|
2433
2668
|
}
|
2434
2669
|
result = HuffmanTreeGroupDecode(hgroup, s);
|
2435
2670
|
if (result != BROTLI_DECODER_SUCCESS) break;
|
@@ -2481,6 +2716,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2481
2716
|
s->max_distance = s->max_backward_distance;
|
2482
2717
|
}
|
2483
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
|
+
}
|
2484
2724
|
if (s->meta_block_remaining_len == 0) {
|
2485
2725
|
/* Next metablock, if any. */
|
2486
2726
|
s->state = BROTLI_STATE_METABLOCK_DONE;
|
@@ -2519,7 +2759,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2519
2759
|
}
|
2520
2760
|
if (s->buffer_length == 0) {
|
2521
2761
|
BrotliBitReaderUnload(br);
|
2522
|
-
*available_in = br
|
2762
|
+
*available_in = BrotliBitReaderGetAvailIn(br);
|
2523
2763
|
*next_in = br->next_in;
|
2524
2764
|
}
|
2525
2765
|
s->state = BROTLI_STATE_DONE;
|
@@ -2533,10 +2773,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2533
2773
|
break;
|
2534
2774
|
}
|
2535
2775
|
}
|
2536
|
-
return
|
2776
|
+
return BROTLI_SAVE_ERROR_CODE(result);
|
2537
2777
|
}
|
2538
2778
|
}
|
2539
|
-
return
|
2779
|
+
return BROTLI_SAVE_ERROR_CODE(result);
|
2780
|
+
#undef BROTLI_SAVE_ERROR_CODE
|
2540
2781
|
}
|
2541
2782
|
|
2542
2783
|
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {
|
@@ -2566,7 +2807,7 @@ const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) {
|
|
2566
2807
|
} else {
|
2567
2808
|
/* ... or stream is broken. Normally this should be caught by
|
2568
2809
|
BrotliDecoderDecompressStream, this is just a safeguard. */
|
2569
|
-
if ((int)status < 0) SaveErrorCode(s, status);
|
2810
|
+
if ((int)status < 0) SaveErrorCode(s, status, 0);
|
2570
2811
|
*size = 0;
|
2571
2812
|
result = 0;
|
2572
2813
|
}
|
@@ -2590,7 +2831,7 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
|
|
2590
2831
|
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
2591
2832
|
switch (c) {
|
2592
2833
|
#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \
|
2593
|
-
case BROTLI_DECODER ## PREFIX ## NAME: return #NAME;
|
2834
|
+
case BROTLI_DECODER ## PREFIX ## NAME: return #PREFIX #NAME;
|
2594
2835
|
#define BROTLI_NOTHING_
|
2595
2836
|
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_)
|
2596
2837
|
#undef BROTLI_ERROR_CODE_CASE_
|
@@ -2599,10 +2840,36 @@ const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
|
2599
2840
|
}
|
2600
2841
|
}
|
2601
2842
|
|
2602
|
-
uint32_t BrotliDecoderVersion() {
|
2843
|
+
uint32_t BrotliDecoderVersion(void) {
|
2603
2844
|
return BROTLI_VERSION;
|
2604
2845
|
}
|
2605
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
|
+
|
2606
2873
|
#if defined(__cplusplus) || defined(c_plusplus)
|
2607
2874
|
} /* extern "C" */
|
2608
2875
|
#endif
|