brotli 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +6 -3
- data/.github/workflows/publish.yml +7 -17
- data/.gitmodules +1 -1
- data/README.md +2 -2
- data/ext/brotli/brotli.c +1 -0
- data/ext/brotli/extconf.rb +6 -0
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +4 -1
- 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
|