brotli 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +6 -3
  3. data/.github/workflows/publish.yml +7 -17
  4. data/.gitmodules +1 -1
  5. data/README.md +2 -2
  6. data/ext/brotli/brotli.c +1 -0
  7. data/ext/brotli/extconf.rb +6 -0
  8. data/lib/brotli/version.rb +1 -1
  9. data/test/brotli_test.rb +4 -1
  10. data/vendor/brotli/c/common/constants.c +1 -1
  11. data/vendor/brotli/c/common/constants.h +2 -1
  12. data/vendor/brotli/c/common/context.c +1 -1
  13. data/vendor/brotli/c/common/dictionary.c +5 -3
  14. data/vendor/brotli/c/common/platform.c +2 -1
  15. data/vendor/brotli/c/common/platform.h +60 -113
  16. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  17. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  18. data/vendor/brotli/c/common/transform.c +1 -1
  19. data/vendor/brotli/c/common/version.h +31 -6
  20. data/vendor/brotli/c/dec/bit_reader.c +10 -8
  21. data/vendor/brotli/c/dec/bit_reader.h +172 -100
  22. data/vendor/brotli/c/dec/decode.c +467 -200
  23. data/vendor/brotli/c/dec/huffman.c +7 -4
  24. data/vendor/brotli/c/dec/huffman.h +2 -1
  25. data/vendor/brotli/c/dec/prefix.h +2 -1
  26. data/vendor/brotli/c/dec/state.c +33 -9
  27. data/vendor/brotli/c/dec/state.h +70 -35
  28. data/vendor/brotli/c/enc/backward_references.c +81 -19
  29. data/vendor/brotli/c/enc/backward_references.h +5 -4
  30. data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
  31. data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
  32. data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
  33. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  34. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  35. data/vendor/brotli/c/enc/block_splitter.c +37 -14
  36. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  37. data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
  38. data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
  39. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  40. data/vendor/brotli/c/enc/cluster.c +10 -9
  41. data/vendor/brotli/c/enc/cluster.h +7 -6
  42. data/vendor/brotli/c/enc/cluster_inc.h +25 -20
  43. data/vendor/brotli/c/enc/command.c +1 -1
  44. data/vendor/brotli/c/enc/command.h +5 -4
  45. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  46. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  47. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  48. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  49. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
  50. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  51. data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
  52. data/vendor/brotli/c/enc/encode.c +473 -404
  53. data/vendor/brotli/c/enc/encoder_dict.c +611 -4
  54. data/vendor/brotli/c/enc/encoder_dict.h +117 -3
  55. data/vendor/brotli/c/enc/entropy_encode.c +3 -2
  56. data/vendor/brotli/c/enc/entropy_encode.h +2 -1
  57. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  58. data/vendor/brotli/c/enc/fast_log.c +1 -1
  59. data/vendor/brotli/c/enc/fast_log.h +2 -1
  60. data/vendor/brotli/c/enc/find_match_length.h +15 -22
  61. data/vendor/brotli/c/enc/hash.h +285 -45
  62. data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
  63. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
  64. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
  65. data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
  66. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
  67. data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
  68. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
  69. data/vendor/brotli/c/enc/histogram.c +4 -4
  70. data/vendor/brotli/c/enc/histogram.h +7 -6
  71. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  72. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  73. data/vendor/brotli/c/enc/memory.c +29 -5
  74. data/vendor/brotli/c/enc/memory.h +19 -2
  75. data/vendor/brotli/c/enc/metablock.c +72 -58
  76. data/vendor/brotli/c/enc/metablock.h +9 -8
  77. data/vendor/brotli/c/enc/metablock_inc.h +8 -6
  78. data/vendor/brotli/c/enc/params.h +4 -3
  79. data/vendor/brotli/c/enc/prefix.h +3 -2
  80. data/vendor/brotli/c/enc/quality.h +40 -3
  81. data/vendor/brotli/c/enc/ringbuffer.h +4 -3
  82. data/vendor/brotli/c/enc/state.h +104 -0
  83. data/vendor/brotli/c/enc/static_dict.c +60 -4
  84. data/vendor/brotli/c/enc/static_dict.h +3 -2
  85. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  86. data/vendor/brotli/c/enc/utf8_util.c +1 -1
  87. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  88. data/vendor/brotli/c/enc/write_bits.h +2 -1
  89. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  90. data/vendor/brotli/c/include/brotli/encode.h +55 -2
  91. data/vendor/brotli/c/include/brotli/port.h +28 -11
  92. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  93. 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 "./bit_reader.h"
19
- #include "./huffman.h"
20
- #include "./prefix.h"
21
- #include "./state.h"
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
- 5 prefix + 24 base + 8 suffix */
46
- static const uint32_t kRingBufferWriteAheadSlack = 42;
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
- uint32_t n;
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 = 17 + n;
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 = 8 + n;
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, uint32_t* value) {
183
- uint32_t bits;
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
- uint32_t bits;
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 uint32_t DecodeSymbol(uint32_t bits,
351
- const HuffmanCode* table,
352
- BrotliBitReader* br) {
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
- uint32_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
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 uint32_t ReadSymbol(const HuffmanCode* table,
369
- BrotliBitReader* br) {
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, uint32_t* result) {
377
- uint32_t val;
378
- uint32_t available_bits = BrotliGetAvailableBits(br);
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 = (uint32_t)BrotliGetBitsUnmasked(br);
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, uint32_t* result) {
417
- uint32_t val;
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
- uint32_t* bits,
430
- uint32_t* value) {
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 uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
448
+ static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
443
449
  BrotliBitReader* br,
444
- uint32_t* bits,
445
- uint32_t* value) {
446
- uint32_t result = *value;
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
- uint32_t val = BrotliGet16BitsUnmasked(br);
454
+ brotli_reg_t val = BrotliGet16BitsUnmasked(br);
449
455
  const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
450
- uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
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 uint32_t Log2Floor(uint32_t x) {
464
- uint32_t result = 0;
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
- uint32_t alphabet_size_max, uint32_t alphabet_size_limit,
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
- uint32_t max_bits = Log2Floor(alphabet_size_max - 1);
482
- uint32_t i = h->sub_loop_counter;
483
- uint32_t num_symbols = h->symbol;
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
- uint32_t v;
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
- uint32_t k = i + 1;
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(uint32_t code_len,
519
- uint32_t* symbol, uint32_t* repeat, uint32_t* space,
520
- uint32_t* prev_code_len, uint16_t* symbol_lists,
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(uint32_t code_len,
546
- uint32_t repeat_delta, uint32_t alphabet_size, uint32_t* symbol,
547
- uint32_t* repeat, uint32_t* space, uint32_t* prev_code_len,
548
- uint32_t* repeat_code_len, uint16_t* symbol_lists,
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
- uint32_t old_repeat;
551
- uint32_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
552
- uint32_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
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
- unsigned last = *symbol + repeat_delta;
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
- uint32_t alphabet_size, BrotliDecoderState* s) {
600
+ brotli_reg_t alphabet_size, BrotliDecoderState* s) {
595
601
  BrotliBitReader* br = &s->br;
596
602
  BrotliMetablockHeaderArena* h = &s->arena.header;
597
- uint32_t symbol = h->symbol;
598
- uint32_t repeat = h->repeat;
599
- uint32_t space = h->space;
600
- uint32_t prev_code_len = h->prev_code_len;
601
- uint32_t repeat_code_len = h->repeat_code_len;
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
- uint32_t code_len;
616
+ brotli_reg_t code_len;
611
617
  BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
612
- if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
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
- uint32_t extra_bits =
635
+ brotli_reg_t extra_bits =
630
636
  (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;
631
- uint32_t repeat_delta =
632
- (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
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
- uint32_t alphabet_size, BrotliDecoderState* s) {
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
- uint32_t code_len;
651
- uint32_t available_bits;
652
- uint32_t bits = 0;
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
- uint32_t extra_bits = code_len - 14U;
674
- uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
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
- uint32_t num_codes = h->repeat;
696
- unsigned space = h->space;
697
- uint32_t i = h->sub_loop_counter;
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
- uint32_t ix;
701
- uint32_t v;
706
+ brotli_reg_t ix;
707
+ brotli_reg_t v;
702
708
  if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
703
- uint32_t available_bits = BrotliGetAvailableBits(br);
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(uint32_t alphabet_size_max,
749
- uint32_t alphabet_size_limit,
754
+ static BrotliDecoderErrorCode ReadHuffmanCode(brotli_reg_t alphabet_size_max,
755
+ brotli_reg_t alphabet_size_limit,
750
756
  HuffmanCode* table,
751
- uint32_t* opt_table_size,
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
- uint32_t table_size;
803
+ brotli_reg_t table_size;
798
804
  if (h->symbol == 3) {
799
- uint32_t bits;
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
- table, HUFFMAN_TABLE_BITS, h->symbols_lists_array, h->symbol);
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
- uint32_t i;
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
- uint32_t table_size;
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 uint32_t ReadBlockLength(const HuffmanCode* table,
874
- BrotliBitReader* br) {
875
- uint32_t code;
876
- uint32_t nbits;
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, uint32_t* result, const HuffmanCode* table,
892
+ BrotliDecoderState* s, brotli_reg_t* result, const HuffmanCode* table,
886
893
  BrotliBitReader* br) {
887
- uint32_t index;
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
- uint32_t bits;
897
- uint32_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
898
- uint32_t offset = _kBrotliPrefixCodeRanges[index].offset;
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, uint32_t v_len, BrotliDecoderState* state) {
932
+ uint8_t* v, brotli_reg_t v_len, BrotliDecoderState* state) {
926
933
  /* Reinitialize elements that could have been changed. */
927
- uint32_t i = 1;
928
- uint32_t upper_bound = state->mtf_upper_bound;
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
- uint32_t table_size;
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(uint32_t context_map_size,
992
- uint32_t* num_htrees,
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
- uint32_t bits;
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
- uint32_t alphabet_size = *num_htrees + h->max_run_length_prefix;
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
- uint32_t context_index = h->context_index;
1052
- uint32_t max_run_length_prefix = h->max_run_length_prefix;
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
- uint32_t code = h->code;
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
- uint32_t reps;
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
- uint32_t bits;
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
- uint32_t max_block_type = s->num_block_types[tree_type];
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
- uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2];
1129
- uint32_t block_type;
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
- BROTLI_REPEAT(4, error |= s->context_map[offset + j++] ^ sample;)
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
- uint32_t block_type = s->block_type_rb[1];
1186
- uint32_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS;
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
- uint32_t bits;
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, uint32_t n_bits, uint32_t* val) {
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, uint32_t n_bits, uint32_t* val) {
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
- uint32_t npostfix = s->distance_postfix_bits;
1586
- uint32_t ndirect = s->num_direct_distance_codes;
1587
- uint32_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
1588
- uint32_t postfix = 1u << npostfix;
1589
- uint32_t j;
1590
- uint32_t bits = 1;
1591
- uint32_t half = 0;
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
- uint32_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
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
- uint32_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
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
- uint32_t code;
1622
- uint32_t bits;
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
- uint32_t cmd_code;
1669
- uint32_t insert_len_extra = 0;
1670
- uint32_t copy_length;
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, size_t num) {
1883
+ int safe, BrotliBitReader* const br) {
1716
1884
  if (safe) {
1717
1885
  return BROTLI_TRUE;
1718
1886
  }
1719
- return BrotliCheckInputAmount(br, num);
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, 28)) {
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, 28)) { /* 156 bits + 7 bytes */
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
- uint32_t bits;
1791
- uint32_t value;
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, 28)) { /* 162 bits + 7 bytes */
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
- BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
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
- uint32_t literal;
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, 28)) { /* 162 bits + 7 bytes */
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
- BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
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
- uint32_t literal;
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 (i >= BROTLI_MIN_DICTIONARY_WORD_LENGTH &&
1907
- i <= BROTLI_MAX_DICTIONARY_WORD_LENGTH) {
1908
- int address = s->distance_code - s->max_distance - 1;
1909
- const BrotliDictionary* words = s->dictionary;
1910
- const BrotliTransforms* transforms = s->transforms;
1911
- int offset = (int)s->dictionary->offsets_by_length[i];
1912
- uint32_t shift = s->dictionary->size_bits_by_length[i];
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, const uint8_t* encoded_buffer, size_t* decoded_size,
2037
- uint8_t* decoded_buffer) {
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 SaveErrorCode(
2084
- s, BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
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->avail_in = *available_in;
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->next_in = &s->buffer.u8[0];
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->avail_in == 0) {
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->avail_in = *available_in;
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->avail_in = s->buffer_length;
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->avail_in;
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->avail_in;
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
- if (!BrotliSafeReadBits(br, 6, &s->window_bits)) {
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
- uint32_t alphabet_size = s->num_block_types[s->loop_counter] + 2;
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
- uint32_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;
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
- for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
2334
- uint32_t bits;
2335
- /* Read one byte and ignore it. */
2336
- if (!BrotliSafeReadBits(br, 8, &bits)) {
2337
- result = BROTLI_DECODER_NEEDS_MORE_INPUT;
2338
- break;
2339
- }
2340
- }
2341
- if (result == BROTLI_DECODER_SUCCESS) {
2342
- s->state = BROTLI_STATE_METABLOCK_DONE;
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
- uint32_t bits;
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
- uint32_t npostfix = s->distance_postfix_bits;
2389
- uint32_t ndirect = s->num_direct_distance_codes;
2390
- uint32_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
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
- uint32_t distance_alphabet_size_limit = distance_alphabet_size_max;
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, ndirect);
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 SaveErrorCode(s,
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 SaveErrorCode(s, BROTLI_FAILURE(
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->avail_in;
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 SaveErrorCode(s, result);
2776
+ return BROTLI_SAVE_ERROR_CODE(result);
2537
2777
  }
2538
2778
  }
2539
- return SaveErrorCode(s, result);
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