brotli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/ext/brotli/brotli.cc +114 -24
  3. data/ext/brotli/brotli.h +0 -1
  4. data/ext/brotli/extconf.rb +30 -23
  5. data/lib/brotli/version.rb +1 -1
  6. data/vendor/brotli/LICENSE +1 -1
  7. data/vendor/brotli/dec/Makefile +1 -1
  8. data/vendor/brotli/dec/bit_reader.c +3 -3
  9. data/vendor/brotli/dec/bit_reader.h +25 -27
  10. data/vendor/brotli/dec/context.h +4 -4
  11. data/vendor/brotli/dec/decode.c +410 -486
  12. data/vendor/brotli/dec/decode.h +101 -105
  13. data/vendor/brotli/dec/dictionary.c +1 -1
  14. data/vendor/brotli/dec/dictionary.h +7 -8
  15. data/vendor/brotli/dec/huffman.c +103 -105
  16. data/vendor/brotli/dec/huffman.h +18 -18
  17. data/vendor/brotli/dec/port.h +52 -40
  18. data/vendor/brotli/dec/prefix.h +2 -0
  19. data/vendor/brotli/dec/state.c +13 -19
  20. data/vendor/brotli/dec/state.h +25 -39
  21. data/vendor/brotli/dec/transform.h +38 -44
  22. data/vendor/brotli/dec/types.h +2 -2
  23. data/vendor/brotli/enc/Makefile +1 -1
  24. data/vendor/brotli/enc/backward_references.cc +455 -359
  25. data/vendor/brotli/enc/backward_references.h +79 -3
  26. data/vendor/brotli/enc/bit_cost.h +54 -32
  27. data/vendor/brotli/enc/block_splitter.cc +285 -193
  28. data/vendor/brotli/enc/block_splitter.h +4 -12
  29. data/vendor/brotli/enc/brotli_bit_stream.cc +623 -324
  30. data/vendor/brotli/enc/brotli_bit_stream.h +76 -37
  31. data/vendor/brotli/enc/cluster.h +161 -120
  32. data/vendor/brotli/enc/command.h +60 -37
  33. data/vendor/brotli/enc/compress_fragment.cc +701 -0
  34. data/vendor/brotli/enc/compress_fragment.h +47 -0
  35. data/vendor/brotli/enc/compress_fragment_two_pass.cc +524 -0
  36. data/vendor/brotli/enc/compress_fragment_two_pass.h +40 -0
  37. data/vendor/brotli/enc/compressor.h +15 -0
  38. data/vendor/brotli/enc/context.h +1 -1
  39. data/vendor/brotli/enc/dictionary.h +2 -2
  40. data/vendor/brotli/enc/encode.cc +819 -286
  41. data/vendor/brotli/enc/encode.h +38 -15
  42. data/vendor/brotli/enc/encode_parallel.cc +40 -42
  43. data/vendor/brotli/enc/entropy_encode.cc +144 -147
  44. data/vendor/brotli/enc/entropy_encode.h +32 -8
  45. data/vendor/brotli/enc/entropy_encode_static.h +572 -0
  46. data/vendor/brotli/enc/fast_log.h +7 -40
  47. data/vendor/brotli/enc/find_match_length.h +9 -9
  48. data/vendor/brotli/enc/hash.h +462 -154
  49. data/vendor/brotli/enc/histogram.cc +6 -6
  50. data/vendor/brotli/enc/histogram.h +13 -13
  51. data/vendor/brotli/enc/literal_cost.cc +45 -45
  52. data/vendor/brotli/enc/metablock.cc +92 -89
  53. data/vendor/brotli/enc/metablock.h +12 -12
  54. data/vendor/brotli/enc/port.h +7 -16
  55. data/vendor/brotli/enc/prefix.h +23 -22
  56. data/vendor/brotli/enc/ringbuffer.h +75 -29
  57. data/vendor/brotli/enc/static_dict.cc +56 -48
  58. data/vendor/brotli/enc/static_dict.h +5 -5
  59. data/vendor/brotli/enc/streams.cc +1 -1
  60. data/vendor/brotli/enc/streams.h +5 -5
  61. data/vendor/brotli/enc/transform.h +40 -35
  62. data/vendor/brotli/enc/types.h +2 -0
  63. data/vendor/brotli/enc/utf8_util.cc +3 -2
  64. data/vendor/brotli/enc/write_bits.h +6 -6
  65. metadata +9 -5
  66. data/vendor/brotli/dec/streams.c +0 -102
  67. data/vendor/brotli/dec/streams.h +0 -95
@@ -4,38 +4,35 @@
4
4
  See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
5
  */
6
6
 
7
- #include <stdlib.h>
8
- #include <stdio.h>
9
- #include <string.h>
10
- #include "./bit_reader.h"
11
- #include "./context.h"
12
7
  #include "./decode.h"
13
- #include "./dictionary.h"
14
- #include "./port.h"
15
- #include "./transform.h"
16
- #include "./huffman.h"
17
- #include "./prefix.h"
18
8
 
19
9
  #ifdef __ARM_NEON__
20
10
  #include <arm_neon.h>
21
11
  #endif
22
12
 
13
+ #include <stdlib.h> /* free, malloc */
14
+ #include <string.h> /* memcpy, memset */
15
+
16
+ #include "./bit_reader.h"
17
+ #include "./context.h"
18
+ #include "./dictionary.h"
19
+ #include "./huffman.h"
20
+ #include "./port.h"
21
+ #include "./prefix.h"
22
+ #include "./state.h"
23
+ #include "./transform.h"
24
+
23
25
  #if defined(__cplusplus) || defined(c_plusplus)
24
26
  extern "C" {
25
27
  #endif
26
28
 
27
- #ifdef BROTLI_DECODE_DEBUG
28
- #define BROTLI_LOG_UINT(name) \
29
- printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))
30
- #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
31
- printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
32
- (unsigned long)(idx), (unsigned long)array_name[idx])
33
- #define BROTLI_LOG(x) printf x
34
- #else
35
- #define BROTLI_LOG_UINT(name)
36
- #define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
37
- #define BROTLI_LOG(x)
38
- #endif
29
+ #define BROTLI_FAILURE(CODE) (BROTLI_DUMP(), CODE)
30
+
31
+ #define BROTLI_LOG_UINT(name) \
32
+ BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)))
33
+ #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
34
+ BROTLI_LOG(("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
35
+ (unsigned long)(idx), (unsigned long)array_name[idx]))
39
36
 
40
37
  static const uint32_t kDefaultCodeLength = 8;
41
38
  static const uint32_t kCodeLengthRepeatCode = 16;
@@ -45,8 +42,8 @@ static const uint32_t kNumBlockLengthCodes = 26;
45
42
  static const int kLiteralContextBits = 6;
46
43
  static const int kDistanceContextBits = 2;
47
44
 
48
- #define HUFFMAN_TABLE_BITS 8U
49
- #define HUFFMAN_TABLE_MASK 0xff
45
+ #define HUFFMAN_TABLE_BITS 8U
46
+ #define HUFFMAN_TABLE_MASK 0xff
50
47
 
51
48
  #define CODE_LENGTH_CODES 18
52
49
  static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
@@ -73,10 +70,11 @@ BrotliState* BrotliCreateState(
73
70
  state = (BrotliState*)alloc_func(opaque, sizeof(BrotliState));
74
71
  }
75
72
  if (state == 0) {
76
- (void)BROTLI_FAILURE();
73
+ BROTLI_DUMP();
77
74
  return 0;
78
75
  }
79
76
  BrotliStateInitWithCustomAllocators(state, alloc_func, free_func, opaque);
77
+ state->error_code = BROTLI_NO_ERROR;
80
78
  return state;
81
79
  }
82
80
 
@@ -92,6 +90,18 @@ void BrotliDestroyState(BrotliState* state) {
92
90
  }
93
91
  }
94
92
 
93
+ /* Saves error code and converts it to BrotliResult */
94
+ static BROTLI_NOINLINE BrotliResult SaveErrorCode(
95
+ BrotliState* s, BrotliErrorCode e) {
96
+ s->error_code = (int)e;
97
+ switch (e) {
98
+ case BROTLI_SUCCESS: return BROTLI_RESULT_SUCCESS;
99
+ case BROTLI_NEEDS_MORE_INPUT: return BROTLI_RESULT_NEEDS_MORE_INPUT;
100
+ case BROTLI_NEEDS_MORE_OUTPUT: return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
101
+ default: return BROTLI_RESULT_ERROR;
102
+ }
103
+ }
104
+
95
105
  /* Decodes a number in the range [9..24], by reading 1 - 7 bits.
96
106
  Precondition: bit-reader accumulator has at least 7 bits. */
97
107
  static uint32_t DecodeWindowBits(BrotliBitReader* br) {
@@ -111,51 +121,40 @@ static uint32_t DecodeWindowBits(BrotliBitReader* br) {
111
121
  return 17;
112
122
  }
113
123
 
114
- static BROTLI_INLINE BROTLI_NO_ASAN void memmove16(
115
- uint8_t* dst, uint8_t* src) {
116
- #if BROTLI_SAFE_MEMMOVE
117
- /* For x86 this compiles to the same binary as signle memcpy.
118
- On ARM memcpy is not inlined, so it works slower.
119
- This implementation makes decompression 1% slower than regular one,
120
- and 2% slower than NEON implementation.
121
- */
124
+ static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
125
+ #if defined(__ARM_NEON__)
126
+ vst1q_u8(dst, vld1q_u8(src));
127
+ #else
122
128
  uint32_t buffer[4];
123
129
  memcpy(buffer, src, 16);
124
130
  memcpy(dst, buffer, 16);
125
- #elif defined(__ARM_NEON__)
126
- vst1q_u8(dst, vld1q_u8(src));
127
- #else
128
- /* memcpy is unsafe for overlapping regions and ASAN detects this.
129
- But, because of optimizations, it works exactly as memmove:
130
- copies data to registers first, and then stores them to dst. */
131
- memcpy(dst, src, 16);
132
131
  #endif
133
132
  }
134
133
 
135
134
  /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
136
- static BROTLI_NOINLINE BrotliResult DecodeVarLenUint8(BrotliState* s,
135
+ static BROTLI_NOINLINE BrotliErrorCode DecodeVarLenUint8(BrotliState* s,
137
136
  BrotliBitReader* br, uint32_t* value) {
138
137
  uint32_t bits;
139
138
  switch (s->substate_decode_uint8) {
140
139
  case BROTLI_STATE_DECODE_UINT8_NONE:
141
140
  if (PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
142
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
141
+ return BROTLI_NEEDS_MORE_INPUT;
143
142
  }
144
143
  if (bits == 0) {
145
144
  *value = 0;
146
- return BROTLI_RESULT_SUCCESS;
145
+ return BROTLI_SUCCESS;
147
146
  }
148
147
  /* No break, transit to the next state. */
149
148
 
150
149
  case BROTLI_STATE_DECODE_UINT8_SHORT:
151
150
  if (PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) {
152
151
  s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT;
153
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
152
+ return BROTLI_NEEDS_MORE_INPUT;
154
153
  }
155
154
  if (bits == 0) {
156
155
  *value = 1;
157
156
  s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
158
- return BROTLI_RESULT_SUCCESS;
157
+ return BROTLI_SUCCESS;
159
158
  }
160
159
  /* Use output value as a temporary storage. It MUST be persisted. */
161
160
  *value = bits;
@@ -164,27 +163,27 @@ static BROTLI_NOINLINE BrotliResult DecodeVarLenUint8(BrotliState* s,
164
163
  case BROTLI_STATE_DECODE_UINT8_LONG:
165
164
  if (PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) {
166
165
  s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG;
167
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
166
+ return BROTLI_NEEDS_MORE_INPUT;
168
167
  }
169
168
  *value = (1U << *value) + bits;
170
169
  s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
171
- return BROTLI_RESULT_SUCCESS;
170
+ return BROTLI_SUCCESS;
172
171
 
173
172
  default:
174
- return BROTLI_FAILURE();
173
+ return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
175
174
  }
176
175
  }
177
176
 
178
177
  /* Decodes a metablock length and flags by reading 2 - 31 bits. */
179
- static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
180
- BrotliBitReader* br) {
178
+ static BrotliErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
179
+ BrotliState* s, BrotliBitReader* br) {
181
180
  uint32_t bits;
182
181
  int i;
183
182
  for (;;) {
184
183
  switch (s->substate_metablock_header) {
185
184
  case BROTLI_STATE_METABLOCK_HEADER_NONE:
186
185
  if (!BrotliSafeReadBits(br, 1, &bits)) {
187
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
186
+ return BROTLI_NEEDS_MORE_INPUT;
188
187
  }
189
188
  s->is_last_metablock = (uint8_t)bits;
190
189
  s->meta_block_remaining_len = 0;
@@ -199,18 +198,18 @@ static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
199
198
 
200
199
  case BROTLI_STATE_METABLOCK_HEADER_EMPTY:
201
200
  if (!BrotliSafeReadBits(br, 1, &bits)) {
202
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
201
+ return BROTLI_NEEDS_MORE_INPUT;
203
202
  }
204
203
  if (bits) {
205
204
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
206
- return BROTLI_RESULT_SUCCESS;
205
+ return BROTLI_SUCCESS;
207
206
  }
208
207
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
209
208
  /* No break, transit to the next state. */
210
209
 
211
210
  case BROTLI_STATE_METABLOCK_HEADER_NIBBLES:
212
211
  if (!BrotliSafeReadBits(br, 2, &bits)) {
213
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
212
+ return BROTLI_NEEDS_MORE_INPUT;
214
213
  }
215
214
  s->size_nibbles = (uint8_t)(bits + 4);
216
215
  s->loop_counter = 0;
@@ -227,10 +226,10 @@ static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
227
226
  for (; i < s->size_nibbles; ++i) {
228
227
  if (!BrotliSafeReadBits(br, 4, &bits)) {
229
228
  s->loop_counter = i;
230
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
229
+ return BROTLI_NEEDS_MORE_INPUT;
231
230
  }
232
231
  if (i + 1 == s->size_nibbles && s->size_nibbles > 4 && bits == 0) {
233
- return BROTLI_FAILURE();
232
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_EXUBERANT_NIBBLE);
234
233
  }
235
234
  s->meta_block_remaining_len |= (int)(bits << (i * 4));
236
235
  }
@@ -239,33 +238,33 @@ static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
239
238
  /* No break, transit to the next state. */
240
239
 
241
240
  case BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED:
242
- if (!s->is_last_metablock && !s->is_metadata) {
241
+ if (!s->is_last_metablock) {
243
242
  if (!BrotliSafeReadBits(br, 1, &bits)) {
244
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
243
+ return BROTLI_NEEDS_MORE_INPUT;
245
244
  }
246
245
  s->is_uncompressed = (uint8_t)bits;
247
246
  }
248
247
  ++s->meta_block_remaining_len;
249
248
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
250
- return BROTLI_RESULT_SUCCESS;
249
+ return BROTLI_SUCCESS;
251
250
 
252
251
  case BROTLI_STATE_METABLOCK_HEADER_RESERVED:
253
252
  if (!BrotliSafeReadBits(br, 1, &bits)) {
254
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
253
+ return BROTLI_NEEDS_MORE_INPUT;
255
254
  }
256
255
  if (bits != 0) {
257
- return BROTLI_FAILURE();
256
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_RESERVED);
258
257
  }
259
258
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_BYTES;
260
259
  /* No break, transit to the next state. */
261
260
 
262
261
  case BROTLI_STATE_METABLOCK_HEADER_BYTES:
263
262
  if (!BrotliSafeReadBits(br, 2, &bits)) {
264
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
263
+ return BROTLI_NEEDS_MORE_INPUT;
265
264
  }
266
265
  if (bits == 0) {
267
266
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
268
- return BROTLI_RESULT_SUCCESS;
267
+ return BROTLI_SUCCESS;
269
268
  }
270
269
  s->size_nibbles = (uint8_t)bits;
271
270
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_METADATA;
@@ -276,19 +275,19 @@ static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
276
275
  for (; i < s->size_nibbles; ++i) {
277
276
  if (!BrotliSafeReadBits(br, 8, &bits)) {
278
277
  s->loop_counter = i;
279
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
278
+ return BROTLI_NEEDS_MORE_INPUT;
280
279
  }
281
280
  if (i + 1 == s->size_nibbles && s->size_nibbles > 1 && bits == 0) {
282
- return BROTLI_FAILURE();
281
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
283
282
  }
284
283
  s->meta_block_remaining_len |= (int)(bits << (i * 8));
285
284
  }
286
- s->substate_metablock_header =
287
- BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
288
- break;
285
+ ++s->meta_block_remaining_len;
286
+ s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
287
+ return BROTLI_SUCCESS;
289
288
 
290
289
  default:
291
- return BROTLI_FAILURE();
290
+ return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
292
291
  }
293
292
  }
294
293
  }
@@ -371,7 +370,6 @@ static BROTLI_INLINE int SafeReadSymbol(const HuffmanCode* table,
371
370
  return SafeDecodeSymbol(table, br, result);
372
371
  }
373
372
 
374
-
375
373
  /* Makes a look-up in first level Huffman table. Peeks 8 bits. */
376
374
  static BROTLI_INLINE void PreloadSymbol(int safe,
377
375
  const HuffmanCode* table,
@@ -421,8 +419,8 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
421
419
  Totally 1..4 symbols are read, 1..10 bits each.
422
420
  The list of symbols MUST NOT contain duplicates.
423
421
  */
424
- static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
425
- BrotliState* s) {
422
+ static BrotliErrorCode ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
423
+ BrotliState* s) {
426
424
  /* max_bits == 1..10; symbol == 0..3; 1..40 bits will be read. */
427
425
  BrotliBitReader* br = &s->br;
428
426
  uint32_t max_bits = Log2Floor(alphabet_size - 1);
@@ -433,10 +431,10 @@ static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
433
431
  if (PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
434
432
  s->sub_loop_counter = i;
435
433
  s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
436
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
434
+ return BROTLI_NEEDS_MORE_INPUT;
437
435
  }
438
436
  if (v >= alphabet_size) {
439
- return BROTLI_FAILURE();
437
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
440
438
  }
441
439
  s->symbols_lists_array[i] = (uint16_t)v;
442
440
  BROTLI_LOG_UINT(s->symbols_lists_array[i]);
@@ -447,12 +445,12 @@ static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
447
445
  uint32_t k = i + 1;
448
446
  for (; k <= num_symbols; ++k) {
449
447
  if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
450
- return BROTLI_FAILURE();
448
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
451
449
  }
452
450
  }
453
451
  }
454
452
 
455
- return BROTLI_RESULT_SUCCESS;
453
+ return BROTLI_SUCCESS;
456
454
  }
457
455
 
458
456
  /* Process single decoded symbol code length:
@@ -473,6 +471,7 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
473
471
  *prev_code_len = code_len;
474
472
  *space -= 32768U >> code_len;
475
473
  code_length_histo[code_len]++;
474
+ BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", *symbol, code_len));
476
475
  }
477
476
  (*symbol)++;
478
477
  }
@@ -508,11 +507,13 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
508
507
  *repeat += repeat_delta + 3U;
509
508
  repeat_delta = *repeat - old_repeat;
510
509
  if (*symbol + repeat_delta > alphabet_size) {
511
- (void)BROTLI_FAILURE();
510
+ BROTLI_DUMP();
512
511
  *symbol = alphabet_size;
513
512
  *space = 0xFFFFF;
514
513
  return;
515
514
  }
515
+ BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
516
+ *symbol, *symbol + repeat_delta - 1, *repeat_code_len));
516
517
  if (*repeat_code_len != 0) {
517
518
  unsigned last = *symbol + repeat_delta;
518
519
  int next = next_symbol[*repeat_code_len];
@@ -522,15 +523,15 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
522
523
  } while (++(*symbol) != last);
523
524
  next_symbol[*repeat_code_len] = next;
524
525
  *space -= repeat_delta << (15 - *repeat_code_len);
525
- code_length_histo[*repeat_code_len] = (uint16_t)
526
- (code_length_histo[*repeat_code_len] + repeat_delta);
526
+ code_length_histo[*repeat_code_len] =
527
+ (uint16_t)(code_length_histo[*repeat_code_len] + repeat_delta);
527
528
  } else {
528
529
  *symbol += repeat_delta;
529
530
  }
530
531
  }
531
532
 
532
533
  /* Reads and decodes symbol codelengths. */
533
- static BrotliResult ReadSymbolCodeLengths(
534
+ static BrotliErrorCode ReadSymbolCodeLengths(
534
535
  uint32_t alphabet_size, BrotliState* s) {
535
536
  BrotliBitReader* br = &s->br;
536
537
  uint32_t symbol = s->symbol;
@@ -542,7 +543,7 @@ static BrotliResult ReadSymbolCodeLengths(
542
543
  uint16_t* code_length_histo = s->code_length_histo;
543
544
  int* next_symbol = s->next_symbol;
544
545
  if (!BrotliWarmupBitReader(br)) {
545
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
546
+ return BROTLI_NEEDS_MORE_INPUT;
546
547
  }
547
548
  while (symbol < alphabet_size && space > 0) {
548
549
  const HuffmanCode* p = s->table;
@@ -553,13 +554,13 @@ static BrotliResult ReadSymbolCodeLengths(
553
554
  s->prev_code_len = prev_code_len;
554
555
  s->repeat_code_len = repeat_code_len;
555
556
  s->space = space;
556
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
557
+ return BROTLI_NEEDS_MORE_INPUT;
557
558
  }
558
559
  BrotliFillBitWindow16(br);
559
560
  p += BrotliGetBitsUnmasked(br) &
560
561
  BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
561
- BrotliDropBits(br, p->bits); /* Use 1..5 bits */
562
- code_len = p->value; /* code_len == 0..17 */
562
+ BrotliDropBits(br, p->bits); /* Use 1..5 bits */
563
+ code_len = p->value; /* code_len == 0..17 */
563
564
  if (code_len < kCodeLengthRepeatCode) {
564
565
  ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
565
566
  &prev_code_len, symbol_lists, code_length_histo, next_symbol);
@@ -573,10 +574,10 @@ static BrotliResult ReadSymbolCodeLengths(
573
574
  }
574
575
  }
575
576
  s->space = space;
576
- return BROTLI_RESULT_SUCCESS;
577
+ return BROTLI_SUCCESS;
577
578
  }
578
579
 
579
- static BrotliResult SafeReadSymbolCodeLengths(
580
+ static BrotliErrorCode SafeReadSymbolCodeLengths(
580
581
  uint32_t alphabet_size, BrotliState* s) {
581
582
  BrotliBitReader* br = &s->br;
582
583
  while (s->symbol < alphabet_size && s->space > 0) {
@@ -609,15 +610,15 @@ static BrotliResult SafeReadSymbolCodeLengths(
609
610
 
610
611
  pullMoreInput:
611
612
  if (!BrotliPullByte(br)) {
612
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
613
+ return BROTLI_NEEDS_MORE_INPUT;
613
614
  }
614
615
  }
615
- return BROTLI_RESULT_SUCCESS;
616
+ return BROTLI_SUCCESS;
616
617
  }
617
618
 
618
619
  /* Reads and decodes 15..18 codes using static prefix code.
619
620
  Each code is 2..4 bits long. In total 30..72 bits are used. */
620
- static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
621
+ static BrotliErrorCode ReadCodeLengthCodeLengths(BrotliState* s) {
621
622
  BrotliBitReader* br = &s->br;
622
623
  uint32_t num_codes = s->repeat;
623
624
  unsigned space = s->space;
@@ -638,7 +639,7 @@ static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
638
639
  s->repeat = num_codes;
639
640
  s->space = space;
640
641
  s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
641
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
642
+ return BROTLI_NEEDS_MORE_INPUT;
642
643
  }
643
644
  }
644
645
  v = kCodeLengthPrefixValue[ix];
@@ -656,9 +657,9 @@ static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
656
657
  }
657
658
  }
658
659
  if (!(num_codes == 1 || space == 0)) {
659
- return BROTLI_FAILURE();
660
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_CL_SPACE);
660
661
  }
661
- return BROTLI_RESULT_SUCCESS;
662
+ return BROTLI_SUCCESS;
662
663
  }
663
664
 
664
665
  /* Decodes the Huffman tables.
@@ -673,10 +674,10 @@ static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
673
674
  B.2) Decoded table is used to decode code lengths of symbols in resulting
674
675
  Huffman table. In worst case 3520 bits are read.
675
676
  */
676
- static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
677
- HuffmanCode* table,
678
- uint32_t* opt_table_size,
679
- BrotliState* s) {
677
+ static BrotliErrorCode ReadHuffmanCode(uint32_t alphabet_size,
678
+ HuffmanCode* table,
679
+ uint32_t* opt_table_size,
680
+ BrotliState* s) {
680
681
  BrotliBitReader* br = &s->br;
681
682
  /* Unnecessary masking, but might be good for safety. */
682
683
  alphabet_size &= 0x3ff;
@@ -684,7 +685,7 @@ static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
684
685
  switch (s->substate_huffman) {
685
686
  case BROTLI_STATE_HUFFMAN_NONE:
686
687
  if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {
687
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
688
+ return BROTLI_NEEDS_MORE_INPUT;
688
689
  }
689
690
  BROTLI_LOG_UINT(s->sub_loop_counter);
690
691
  /* The value is used as follows:
@@ -706,13 +707,13 @@ static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
706
707
  /* Read symbols, codes & code lengths directly. */
707
708
  if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */
708
709
  s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
709
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
710
+ return BROTLI_NEEDS_MORE_INPUT;
710
711
  }
711
712
  s->sub_loop_counter = 0;
712
713
  /* No break, transit to the next state. */
713
714
  case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
714
- BrotliResult result = ReadSimpleHuffmanSymbols(alphabet_size, s);
715
- if (result != BROTLI_RESULT_SUCCESS) {
715
+ BrotliErrorCode result = ReadSimpleHuffmanSymbols(alphabet_size, s);
716
+ if (result != BROTLI_SUCCESS) {
716
717
  return result;
717
718
  }
718
719
  /* No break, transit to the next state. */
@@ -723,7 +724,7 @@ static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
723
724
  uint32_t bits;
724
725
  if (!BrotliSafeReadBits(br, 1, &bits)) {
725
726
  s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
726
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
727
+ return BROTLI_NEEDS_MORE_INPUT;
727
728
  }
728
729
  s->symbol += bits;
729
730
  }
@@ -734,14 +735,14 @@ static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
734
735
  *opt_table_size = table_size;
735
736
  }
736
737
  s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
737
- return BROTLI_RESULT_SUCCESS;
738
+ return BROTLI_SUCCESS;
738
739
  }
739
740
 
740
741
  Complex: /* Decode Huffman-coded code lengths. */
741
742
  case BROTLI_STATE_HUFFMAN_COMPLEX: {
742
743
  uint32_t i;
743
- BrotliResult result = ReadCodeLengthCodeLengths(s);
744
- if (result != BROTLI_RESULT_SUCCESS) {
744
+ BrotliErrorCode result = ReadCodeLengthCodeLengths(s);
745
+ if (result != BROTLI_SUCCESS) {
745
746
  return result;
746
747
  }
747
748
  BrotliBuildCodeLengthsHuffmanTable(s->table,
@@ -763,29 +764,29 @@ Complex: /* Decode Huffman-coded code lengths. */
763
764
  }
764
765
  case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
765
766
  uint32_t table_size;
766
- BrotliResult result = ReadSymbolCodeLengths(alphabet_size, s);
767
- if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
767
+ BrotliErrorCode result = ReadSymbolCodeLengths(alphabet_size, s);
768
+ if (result == BROTLI_NEEDS_MORE_INPUT) {
768
769
  result = SafeReadSymbolCodeLengths(alphabet_size, s);
769
770
  }
770
- if (result != BROTLI_RESULT_SUCCESS) {
771
+ if (result != BROTLI_SUCCESS) {
771
772
  return result;
772
773
  }
773
774
 
774
775
  if (s->space != 0) {
775
776
  BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
776
- return BROTLI_FAILURE();
777
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_HUFFMAN_SPACE);
777
778
  }
778
- table_size = BrotliBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
779
- s->symbol_lists, s->code_length_histo);
779
+ table_size = BrotliBuildHuffmanTable(
780
+ table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
780
781
  if (opt_table_size) {
781
782
  *opt_table_size = table_size;
782
783
  }
783
784
  s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
784
- return BROTLI_RESULT_SUCCESS;
785
+ return BROTLI_SUCCESS;
785
786
  }
786
787
 
787
788
  default:
788
- return BROTLI_FAILURE();
789
+ return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
789
790
  }
790
791
  }
791
792
 
@@ -847,7 +848,7 @@ static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v,
847
848
  /* Reinitialize elements that could have been changed. */
848
849
  uint32_t i = 4;
849
850
  uint32_t upper_bound = state->mtf_upper_bound;
850
- uint8_t* mtf = state->mtf;
851
+ uint8_t* mtf = &state->mtf[4]; /* Make mtf[-1] addressable. */
851
852
  /* Load endian-aware constant. */
852
853
  const uint8_t b0123[4] = {0, 1, 2, 3};
853
854
  uint32_t pattern;
@@ -868,20 +869,19 @@ static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v,
868
869
  uint8_t value = mtf[index];
869
870
  upper_bound |= v[i];
870
871
  v[i] = value;
872
+ mtf[-1] = value;
871
873
  do {
872
874
  index--;
873
875
  mtf[index + 1] = mtf[index];
874
- } while (index > 0);
875
- mtf[0] = value;
876
+ } while (index >= 0);
876
877
  }
877
878
  /* Remember amount of elements to be reinitialized. */
878
879
  state->mtf_upper_bound = upper_bound;
879
880
  }
880
881
 
881
-
882
882
  /* Decodes a series of Huffman table using ReadHuffmanCode function. */
883
- static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
884
- BrotliState* s) {
883
+ static BrotliErrorCode HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
884
+ BrotliState* s) {
885
885
  if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
886
886
  s->next = group->codes;
887
887
  s->htree_index = 0;
@@ -889,15 +889,15 @@ static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
889
889
  }
890
890
  while (s->htree_index < group->num_htrees) {
891
891
  uint32_t table_size;
892
- BrotliResult result =
892
+ BrotliErrorCode result =
893
893
  ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);
894
- if (result != BROTLI_RESULT_SUCCESS) return result;
894
+ if (result != BROTLI_SUCCESS) return result;
895
895
  group->htrees[s->htree_index] = s->next;
896
896
  s->next += table_size;
897
897
  ++s->htree_index;
898
898
  }
899
899
  s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
900
- return BROTLI_RESULT_SUCCESS;
900
+ return BROTLI_SUCCESS;
901
901
  }
902
902
 
903
903
  /* Decodes a context map.
@@ -909,17 +909,17 @@ static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
909
909
  3) Read context map items; "0" values could be run-length encoded.
910
910
  4) Optionally, apply InverseMoveToFront transform to the resulting map.
911
911
  */
912
- static BrotliResult DecodeContextMap(uint32_t context_map_size,
913
- uint32_t* num_htrees,
914
- uint8_t** context_map_arg,
915
- BrotliState* s) {
912
+ static BrotliErrorCode DecodeContextMap(uint32_t context_map_size,
913
+ uint32_t* num_htrees,
914
+ uint8_t** context_map_arg,
915
+ BrotliState* s) {
916
916
  BrotliBitReader* br = &s->br;
917
- BrotliResult result = BROTLI_RESULT_SUCCESS;
917
+ BrotliErrorCode result = BROTLI_SUCCESS;
918
918
 
919
- switch((int)s->substate_context_map) {
919
+ switch ((int)s->substate_context_map) {
920
920
  case BROTLI_STATE_CONTEXT_MAP_NONE:
921
921
  result = DecodeVarLenUint8(s, br, num_htrees);
922
- if (result != BROTLI_RESULT_SUCCESS) {
922
+ if (result != BROTLI_SUCCESS) {
923
923
  return result;
924
924
  }
925
925
  (*num_htrees)++;
@@ -928,11 +928,11 @@ static BrotliResult DecodeContextMap(uint32_t context_map_size,
928
928
  BROTLI_LOG_UINT(*num_htrees);
929
929
  *context_map_arg = (uint8_t*)BROTLI_ALLOC(s, (size_t)context_map_size);
930
930
  if (*context_map_arg == 0) {
931
- return BROTLI_FAILURE();
931
+ return BROTLI_FAILURE(BROTLI_ERROR_ALLOC_CONTEXT_MAP);
932
932
  }
933
933
  if (*num_htrees <= 1) {
934
934
  memset(*context_map_arg, 0, (size_t)context_map_size);
935
- return BROTLI_RESULT_SUCCESS;
935
+ return BROTLI_SUCCESS;
936
936
  }
937
937
  s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
938
938
  /* No break, continue to next state. */
@@ -941,7 +941,7 @@ static BrotliResult DecodeContextMap(uint32_t context_map_size,
941
941
  /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
942
942
  to peek 4 bits ahead. */
943
943
  if (!BrotliSafeGetBits(br, 5, &bits)) {
944
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
944
+ return BROTLI_NEEDS_MORE_INPUT;
945
945
  }
946
946
  if ((bits & 1) != 0) { /* Use RLE for zeroes. */
947
947
  s->max_run_length_prefix = (bits >> 1) + 1;
@@ -957,7 +957,7 @@ static BrotliResult DecodeContextMap(uint32_t context_map_size,
957
957
  case BROTLI_STATE_CONTEXT_MAP_HUFFMAN:
958
958
  result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix,
959
959
  s->context_map_table, NULL, s);
960
- if (result != BROTLI_RESULT_SUCCESS) return result;
960
+ if (result != BROTLI_SUCCESS) return result;
961
961
  s->code = 0xFFFF;
962
962
  s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
963
963
  /* No break, continue to next state. */
@@ -973,7 +973,7 @@ static BrotliResult DecodeContextMap(uint32_t context_map_size,
973
973
  if (!SafeReadSymbol(s->context_map_table, br, &code)) {
974
974
  s->code = 0xFFFF;
975
975
  s->context_index = context_index;
976
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
976
+ return BROTLI_NEEDS_MORE_INPUT;
977
977
  }
978
978
  BROTLI_LOG_UINT(code);
979
979
 
@@ -992,12 +992,12 @@ rleCode:
992
992
  if (!BrotliSafeReadBits(br, code, &reps)) {
993
993
  s->code = code;
994
994
  s->context_index = context_index;
995
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
995
+ return BROTLI_NEEDS_MORE_INPUT;
996
996
  }
997
997
  reps += 1U << code;
998
998
  BROTLI_LOG_UINT(reps);
999
999
  if (context_index + reps > context_map_size) {
1000
- return BROTLI_FAILURE();
1000
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_CONTEXT_MAP_REPEAT);
1001
1001
  }
1002
1002
  do {
1003
1003
  context_map[context_index++] = 0;
@@ -1010,17 +1010,17 @@ rleCode:
1010
1010
  uint32_t bits;
1011
1011
  if (!BrotliSafeReadBits(br, 1, &bits)) {
1012
1012
  s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
1013
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
1013
+ return BROTLI_NEEDS_MORE_INPUT;
1014
1014
  }
1015
1015
  if (bits != 0) {
1016
1016
  InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
1017
1017
  }
1018
1018
  s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
1019
- return BROTLI_RESULT_SUCCESS;
1019
+ return BROTLI_SUCCESS;
1020
1020
  }
1021
+ default:
1022
+ return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
1021
1023
  }
1022
-
1023
- return BROTLI_FAILURE();
1024
1024
  }
1025
1025
 
1026
1026
  /* Decodes a command or literal and updates block type ringbuffer.
@@ -1028,9 +1028,10 @@ rleCode:
1028
1028
  static BROTLI_INLINE int DecodeBlockTypeAndLength(int safe,
1029
1029
  BrotliState* s, int tree_type) {
1030
1030
  uint32_t max_block_type = s->num_block_types[tree_type];
1031
- int tree_offset = tree_type * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
1032
- const HuffmanCode* type_tree = &s->block_type_trees[tree_offset];
1033
- const HuffmanCode* len_tree = &s->block_len_trees[tree_offset];
1031
+ const HuffmanCode* type_tree = &s->block_type_trees[
1032
+ tree_type * BROTLI_HUFFMAN_MAX_SIZE_258];
1033
+ const HuffmanCode* len_tree = &s->block_len_trees[
1034
+ tree_type * BROTLI_HUFFMAN_MAX_SIZE_26];
1034
1035
  BrotliBitReader* br = &s->br;
1035
1036
  uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2];
1036
1037
  uint32_t block_type;
@@ -1065,22 +1066,45 @@ static BROTLI_INLINE int DecodeBlockTypeAndLength(int safe,
1065
1066
  return 1;
1066
1067
  }
1067
1068
 
1069
+ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(BrotliState* s) {
1070
+ size_t i;
1071
+ for (i = 0; i < 8; ++i) s->trivial_literal_contexts[i] = 0;
1072
+ for (i = 0; i < s->num_block_types[0]; i++) {
1073
+ size_t offset = i << kLiteralContextBits;
1074
+ size_t error = 0;
1075
+ size_t sample = s->context_map[offset];
1076
+ size_t j;
1077
+ for (j = 0; j < (1u << kLiteralContextBits);) {
1078
+ BROTLI_REPEAT(4, error |= s->context_map[offset + j++] ^ sample;)
1079
+ }
1080
+ if (error == 0) {
1081
+ s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31);
1082
+ }
1083
+ }
1084
+ }
1085
+
1086
+ static BROTLI_INLINE void PrepareLiteralDecoding(BrotliState* s) {
1087
+ uint8_t context_mode;
1088
+ size_t trivial;
1089
+ uint32_t block_type = s->block_type_rb[1];
1090
+ uint32_t context_offset = block_type << kLiteralContextBits;
1091
+ s->context_map_slice = s->context_map + context_offset;
1092
+ trivial = s->trivial_literal_contexts[block_type >> 5];
1093
+ s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;
1094
+ s->literal_htree = s->literal_hgroup.htrees[s->context_map_slice[0]];
1095
+ context_mode = s->context_modes[block_type];
1096
+ s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];
1097
+ s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];
1098
+ }
1099
+
1068
1100
  /* Decodes the block type and updates the state for literal context.
1069
1101
  Reads 3..54 bits. */
1070
1102
  static BROTLI_INLINE int DecodeLiteralBlockSwitchInternal(int safe,
1071
1103
  BrotliState* s) {
1072
- uint8_t context_mode;
1073
- uint32_t context_offset;
1074
1104
  if (!DecodeBlockTypeAndLength(safe, s, 0)) {
1075
1105
  return 0;
1076
1106
  }
1077
- context_offset = s->block_type_rb[1] << kLiteralContextBits;
1078
- s->context_map_slice = s->context_map + context_offset;
1079
- s->literal_htree_index = s->context_map_slice[0];
1080
- s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
1081
- context_mode = s->context_modes[s->block_type_rb[1]];
1082
- s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];
1083
- s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];
1107
+ PrepareLiteralDecoding(s);
1084
1108
  return 1;
1085
1109
  }
1086
1110
 
@@ -1131,38 +1155,81 @@ static int BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(BrotliState* s) {
1131
1155
  return DecodeDistanceBlockSwitchInternal(1, s);
1132
1156
  }
1133
1157
 
1134
- static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out,
1135
- size_t* total_out, BrotliState* s) {
1136
- size_t pos = (s->pos > s->ringbuffer_size) ?
1137
- (size_t)s->ringbuffer_size : (size_t)(s->pos);
1138
- uint8_t* start = s->ringbuffer
1139
- + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
1140
- size_t partial_pos_rb =
1141
- (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
1158
+ static BrotliErrorCode BROTLI_NOINLINE WriteRingBuffer(size_t* available_out,
1159
+ uint8_t** next_out, size_t* total_out, BrotliState* s) {
1160
+ size_t pos = (s->pos > s->ringbuffer_size) ? (size_t)s->ringbuffer_size
1161
+ : (size_t)(s->pos);
1162
+ uint8_t* start =
1163
+ s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
1164
+ size_t partial_pos_rb = (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
1142
1165
  size_t to_write = (partial_pos_rb - s->partial_pos_out);
1143
1166
  size_t num_written = *available_out;
1144
1167
  if (num_written > to_write) {
1145
1168
  num_written = to_write;
1146
1169
  }
1147
1170
  if (s->meta_block_remaining_len < 0) {
1148
- return BROTLI_FAILURE();
1171
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_BLOCK_LENGTH_1);
1149
1172
  }
1150
1173
  memcpy(*next_out, start, num_written);
1151
1174
  *next_out += num_written;
1152
1175
  *available_out -= num_written;
1153
1176
  BROTLI_LOG_UINT(to_write);
1154
1177
  BROTLI_LOG_UINT(num_written);
1155
- s->partial_pos_out += (size_t)num_written;
1156
- *total_out = s->partial_pos_out;
1178
+ s->partial_pos_out += num_written;
1179
+ if (total_out) *total_out = s->partial_pos_out;
1157
1180
  if (num_written < to_write) {
1158
- return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
1181
+ return BROTLI_NEEDS_MORE_OUTPUT;
1159
1182
  }
1160
- return BROTLI_RESULT_SUCCESS;
1183
+
1184
+ if (s->pos >= s->ringbuffer_size) {
1185
+ s->pos -= s->ringbuffer_size;
1186
+ s->rb_roundtrips++;
1187
+ }
1188
+ return BROTLI_SUCCESS;
1161
1189
  }
1162
1190
 
1163
- static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(
1191
+ /* Allocates ringbuffer.
1192
+
1193
+ s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before
1194
+ this function is called.
1195
+
1196
+ Last two bytes of ringbuffer are initialized to 0, so context calculation
1197
+ could be done uniformly for the first two and all other positions.
1198
+
1199
+ Custom dictionary, if any, is copied to the end of ringbuffer.
1200
+ */
1201
+ static int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s) {
1202
+ /* We need the slack region for the following reasons:
1203
+ - doing up to two 16-byte copies for fast backward copying
1204
+ - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */
1205
+ static const int kRingBufferWriteAheadSlack = 42;
1206
+ s->ringbuffer = (uint8_t*)BROTLI_ALLOC(s, (size_t)(s->ringbuffer_size +
1207
+ kRingBufferWriteAheadSlack));
1208
+ if (s->ringbuffer == 0) {
1209
+ return 0;
1210
+ }
1211
+
1212
+ s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;
1213
+
1214
+ s->ringbuffer[s->ringbuffer_size - 2] = 0;
1215
+ s->ringbuffer[s->ringbuffer_size - 1] = 0;
1216
+
1217
+ if (s->custom_dict) {
1218
+ memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
1219
+ s->custom_dict, (size_t)s->custom_dict_size);
1220
+ }
1221
+
1222
+ return 1;
1223
+ }
1224
+
1225
+ static BrotliErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
1164
1226
  size_t* available_out, uint8_t** next_out, size_t* total_out,
1165
1227
  BrotliState* s) {
1228
+ /* TODO: avoid allocation for single uncompressed block. */
1229
+ if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {
1230
+ return BROTLI_FAILURE(BROTLI_ERROR_ALLOC_RING_BUFFER_1);
1231
+ }
1232
+
1166
1233
  /* State machine */
1167
1234
  for (;;) {
1168
1235
  switch (s->substate_uncompressed) {
@@ -1180,29 +1247,26 @@ static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(
1180
1247
  s->meta_block_remaining_len -= nbytes;
1181
1248
  if (s->pos < s->ringbuffer_size) {
1182
1249
  if (s->meta_block_remaining_len == 0) {
1183
- return BROTLI_RESULT_SUCCESS;
1250
+ return BROTLI_SUCCESS;
1184
1251
  }
1185
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
1252
+ return BROTLI_NEEDS_MORE_INPUT;
1186
1253
  }
1187
1254
  s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
1188
- /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
1189
1255
  /* No break, continue to next state */
1190
1256
  }
1191
1257
  case BROTLI_STATE_UNCOMPRESSED_WRITE: {
1192
- BrotliResult result = WriteRingBuffer(
1193
- available_out, next_out, total_out, s);
1194
- if (result != BROTLI_RESULT_SUCCESS) {
1258
+ BrotliErrorCode result =
1259
+ WriteRingBuffer(available_out, next_out, total_out, s);
1260
+ if (result != BROTLI_SUCCESS) {
1195
1261
  return result;
1196
1262
  }
1197
- s->pos = 0;
1198
- s->rb_roundtrips++;
1199
1263
  s->max_distance = s->max_backward_distance;
1200
1264
  s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
1201
1265
  break;
1202
1266
  }
1203
1267
  }
1204
1268
  }
1205
- return BROTLI_FAILURE();
1269
+ BROTLI_DCHECK(0); /* Unreachable */
1206
1270
  }
1207
1271
 
1208
1272
  int BrotliDecompressedSize(size_t encoded_size,
@@ -1217,7 +1281,7 @@ int BrotliDecompressedSize(size_t encoded_size,
1217
1281
  return 0;
1218
1282
  }
1219
1283
  DecodeWindowBits(&s.br);
1220
- if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_RESULT_SUCCESS) {
1284
+ if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_SUCCESS) {
1221
1285
  return 0;
1222
1286
  }
1223
1287
  *decoded_size = (size_t)s.meta_block_remaining_len;
@@ -1231,29 +1295,24 @@ int BrotliDecompressedSize(size_t encoded_size,
1231
1295
  return (next_block_header != -1) && ((next_block_header & 3) == 3);
1232
1296
  }
1233
1297
 
1234
- /* Allocates the smallest feasible ring buffer.
1298
+ /* Calculates the smallest feasible ring buffer.
1235
1299
 
1236
1300
  If we know the data size is small, do not allocate more ringbuffer
1237
1301
  size than needed to reduce memory usage.
1238
1302
 
1239
- This method is called before the first non-empty non-metadata block is
1240
- processed. When this method is called, metablock size and flags MUST be
1241
- decoded.
1303
+ When this method is called, metablock size and flags MUST be decoded.
1242
1304
  */
1243
- static int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s,
1305
+ static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s,
1244
1306
  BrotliBitReader* br) {
1245
- /* We need the slack region for the following reasons:
1246
- - doing up to two 16-byte copies for fast backward copying
1247
- - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */
1248
- static const int kRingBufferWriteAheadSlack = 42;
1249
1307
  int is_last = s->is_last_metablock;
1250
- s->ringbuffer_size = 1 << s->window_bits;
1308
+ int window_size = 1 << s->window_bits;
1309
+ s->ringbuffer_size = window_size;
1251
1310
 
1252
1311
  if (s->is_uncompressed) {
1253
- int next_block_header = BrotliPeekByte(br,
1254
- (size_t)s->meta_block_remaining_len);
1255
- if (next_block_header != -1) { /* Peek succeeded */
1256
- if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */
1312
+ int next_block_header =
1313
+ BrotliPeekByte(br, (size_t)s->meta_block_remaining_len);
1314
+ if (next_block_header != -1) { /* Peek succeeded */
1315
+ if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */
1257
1316
  is_last = 1;
1258
1317
  }
1259
1318
  }
@@ -1262,36 +1321,17 @@ static int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s,
1262
1321
  /* We need at least 2 bytes of ring buffer size to get the last two
1263
1322
  bytes for context from there */
1264
1323
  if (is_last) {
1265
- while (s->ringbuffer_size >= s->meta_block_remaining_len * 2
1266
- && s->ringbuffer_size > 32) {
1324
+ int min_size_x2 = (s->meta_block_remaining_len + s->custom_dict_size) * 2;
1325
+ while (s->ringbuffer_size >= min_size_x2 && s->ringbuffer_size > 32) {
1267
1326
  s->ringbuffer_size >>= 1;
1268
1327
  }
1269
1328
  }
1270
1329
 
1271
- /* But make it fit the custom dictionary if there is one. */
1272
- while (s->ringbuffer_size < s->custom_dict_size) {
1273
- s->ringbuffer_size <<= 1;
1274
- }
1275
-
1276
1330
  s->ringbuffer_mask = s->ringbuffer_size - 1;
1277
- s->ringbuffer = (uint8_t*)BROTLI_ALLOC(s, (size_t)(s->ringbuffer_size +
1278
- kRingBufferWriteAheadSlack + kBrotliMaxDictionaryWordLength));
1279
- if (s->ringbuffer == 0) {
1280
- return 0;
1281
- }
1282
- s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;
1283
- s->ringbuffer[s->ringbuffer_size - 2] = 0;
1284
- s->ringbuffer[s->ringbuffer_size - 1] = 0;
1285
- if (s->custom_dict) {
1286
- memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
1287
- s->custom_dict, (size_t)s->custom_dict_size);
1288
- }
1289
-
1290
- return 1;
1291
1331
  }
1292
1332
 
1293
1333
  /* Reads 1..256 2-bit context modes. */
1294
- static BrotliResult ReadContextModes(BrotliState* s) {
1334
+ static BrotliErrorCode ReadContextModes(BrotliState* s) {
1295
1335
  BrotliBitReader* br = &s->br;
1296
1336
  int i = s->loop_counter;
1297
1337
 
@@ -1299,13 +1339,13 @@ static BrotliResult ReadContextModes(BrotliState* s) {
1299
1339
  uint32_t bits;
1300
1340
  if (!BrotliSafeReadBits(br, 2, &bits)) {
1301
1341
  s->loop_counter = i;
1302
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
1342
+ return BROTLI_NEEDS_MORE_INPUT;
1303
1343
  }
1304
1344
  s->context_modes[i] = (uint8_t)(bits << 1);
1305
1345
  BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);
1306
1346
  i++;
1307
1347
  }
1308
- return BROTLI_RESULT_SUCCESS;
1348
+ return BROTLI_SUCCESS;
1309
1349
  }
1310
1350
 
1311
1351
  static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliState* s) {
@@ -1378,8 +1418,8 @@ static BROTLI_INLINE int ReadDistanceInternal(int safe,
1378
1418
  if (!safe && (s->distance_postfix_bits == 0)) {
1379
1419
  nbits = ((uint32_t)distval >> 1) + 1;
1380
1420
  offset = ((2 + (distval & 1)) << nbits) - 4;
1381
- s->distance_code = (int)s->num_direct_distance_codes +
1382
- offset + (int)BrotliReadBits(br, nbits);
1421
+ s->distance_code = (int)s->num_direct_distance_codes + offset +
1422
+ (int)BrotliReadBits(br, nbits);
1383
1423
  } else {
1384
1424
  /* This branch also works well when s->distance_postfix_bits == 0 */
1385
1425
  uint32_t bits;
@@ -1461,13 +1501,6 @@ static BROTLI_INLINE int SafeReadCommand(BrotliState* s, BrotliBitReader* br,
1461
1501
  return ReadCommandInternal(1, s, br, insert_length);
1462
1502
  }
1463
1503
 
1464
- static BROTLI_INLINE int WarmupBitReader(int safe, BrotliBitReader* const br) {
1465
- if (safe) {
1466
- return 1;
1467
- }
1468
- return BrotliWarmupBitReader(br);
1469
- }
1470
-
1471
1504
  static BROTLI_INLINE int CheckInputAmount(int safe,
1472
1505
  BrotliBitReader* const br, size_t num) {
1473
1506
  if (safe) {
@@ -1476,28 +1509,32 @@ static BROTLI_INLINE int CheckInputAmount(int safe,
1476
1509
  return BrotliCheckInputAmount(br, num);
1477
1510
  }
1478
1511
 
1479
- #define BROTLI_SAFE(METHOD) { \
1480
- if (safe) { \
1481
- if (! Safe ## METHOD ) { \
1482
- result = BROTLI_RESULT_NEEDS_MORE_INPUT; \
1483
- goto saveStateAndReturn; \
1484
- } \
1485
- } else { \
1486
- METHOD ; \
1487
- } \
1488
- }
1512
+ #define BROTLI_SAFE(METHOD) \
1513
+ { \
1514
+ if (safe) { \
1515
+ if (!Safe##METHOD) { \
1516
+ result = BROTLI_NEEDS_MORE_INPUT; \
1517
+ goto saveStateAndReturn; \
1518
+ } \
1519
+ } else { \
1520
+ METHOD; \
1521
+ } \
1522
+ }
1489
1523
 
1490
- static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
1524
+ static BROTLI_INLINE BrotliErrorCode ProcessCommandsInternal(int safe,
1491
1525
  BrotliState* s) {
1492
1526
  int pos = s->pos;
1493
1527
  int i = s->loop_counter;
1494
- BrotliResult result = BROTLI_RESULT_SUCCESS;
1528
+ BrotliErrorCode result = BROTLI_SUCCESS;
1495
1529
  BrotliBitReader* br = &s->br;
1496
1530
 
1497
- if (!CheckInputAmount(safe, br, 28) || !WarmupBitReader(safe, br)) {
1498
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1531
+ if (!CheckInputAmount(safe, br, 28)) {
1532
+ result = BROTLI_NEEDS_MORE_INPUT;
1499
1533
  goto saveStateAndReturn;
1500
1534
  }
1535
+ if (!safe) {
1536
+ BROTLI_UNUSED(BrotliWarmupBitReader(br));
1537
+ }
1501
1538
 
1502
1539
  /* Jump into state machine. */
1503
1540
  if (s->state == BROTLI_STATE_COMMAND_BEGIN) {
@@ -1509,7 +1546,7 @@ static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
1509
1546
  } else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
1510
1547
  goto CommandPostWrapCopy;
1511
1548
  } else {
1512
- return BROTLI_FAILURE();
1549
+ return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
1513
1550
  }
1514
1551
 
1515
1552
  CommandBegin:
@@ -1518,7 +1555,7 @@ CommandBegin:
1518
1555
  }
1519
1556
  if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */
1520
1557
  s->state = BROTLI_STATE_COMMAND_BEGIN;
1521
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1558
+ result = BROTLI_NEEDS_MORE_INPUT;
1522
1559
  goto saveStateAndReturn;
1523
1560
  }
1524
1561
  if (PREDICT_FALSE(s->block_length[1] == 0)) {
@@ -1527,9 +1564,8 @@ CommandBegin:
1527
1564
  }
1528
1565
  /* Read the insert/copy length in the command */
1529
1566
  BROTLI_SAFE(ReadCommand(s, br, &i));
1530
- BROTLI_LOG_UINT(i);
1531
- BROTLI_LOG_UINT(s->copy_length);
1532
- BROTLI_LOG_UINT(s->distance_code);
1567
+ BROTLI_LOG(("[ProcessCommandsInternal] pos = %d insert = %d copy = %d\n",
1568
+ pos, i, s->copy_length));
1533
1569
  if (i == 0) {
1534
1570
  goto CommandPostDecodeLiterals;
1535
1571
  }
@@ -1547,26 +1583,26 @@ CommandInner:
1547
1583
  do {
1548
1584
  if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
1549
1585
  s->state = BROTLI_STATE_COMMAND_INNER;
1550
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1586
+ result = BROTLI_NEEDS_MORE_INPUT;
1551
1587
  goto saveStateAndReturn;
1552
1588
  }
1553
1589
  if (PREDICT_FALSE(s->block_length[0] == 0)) {
1554
1590
  BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
1555
1591
  PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
1592
+ if (!s->trivial_literal_context) goto CommandInner;
1556
1593
  }
1557
1594
  if (!safe) {
1558
- s->ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(
1559
- s->literal_htree, br, &bits, &value);
1595
+ s->ringbuffer[pos] =
1596
+ (uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
1560
1597
  } else {
1561
1598
  uint32_t literal;
1562
1599
  if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
1563
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1600
+ result = BROTLI_NEEDS_MORE_INPUT;
1564
1601
  goto saveStateAndReturn;
1565
1602
  }
1566
1603
  s->ringbuffer[pos] = (uint8_t)literal;
1567
1604
  }
1568
1605
  --s->block_length[0];
1569
- BROTLI_LOG_UINT(s->literal_htree_index);
1570
1606
  BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
1571
1607
  ++pos;
1572
1608
  if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
@@ -1583,11 +1619,12 @@ CommandInner:
1583
1619
  uint8_t context;
1584
1620
  if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
1585
1621
  s->state = BROTLI_STATE_COMMAND_INNER;
1586
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1622
+ result = BROTLI_NEEDS_MORE_INPUT;
1587
1623
  goto saveStateAndReturn;
1588
1624
  }
1589
1625
  if (PREDICT_FALSE(s->block_length[0] == 0)) {
1590
1626
  BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
1627
+ if (s->trivial_literal_context) goto CommandInner;
1591
1628
  }
1592
1629
  context = s->context_lookup1[p1] | s->context_lookup2[p2];
1593
1630
  BROTLI_LOG_UINT(context);
@@ -1598,7 +1635,7 @@ CommandInner:
1598
1635
  } else {
1599
1636
  uint32_t literal;
1600
1637
  if (!SafeReadSymbol(hc, br, &literal)) {
1601
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1638
+ result = BROTLI_NEEDS_MORE_INPUT;
1602
1639
  goto saveStateAndReturn;
1603
1640
  }
1604
1641
  p1 = (uint8_t)literal;
@@ -1615,7 +1652,8 @@ CommandInner:
1615
1652
  }
1616
1653
  } while (--i != 0);
1617
1654
  }
1618
- if (s->meta_block_remaining_len <= 0) {
1655
+ BROTLI_LOG_UINT(s->meta_block_remaining_len);
1656
+ if (PREDICT_FALSE(s->meta_block_remaining_len <= 0)) {
1619
1657
  s->state = BROTLI_STATE_METABLOCK_DONE;
1620
1658
  goto saveStateAndReturn;
1621
1659
  }
@@ -1635,7 +1673,8 @@ CommandPostDecodeLiterals:
1635
1673
  }
1636
1674
  BROTLI_SAFE(ReadDistance(s, br));
1637
1675
  postReadDistance:
1638
- BROTLI_LOG_UINT(s->distance_code);
1676
+ BROTLI_LOG(("[ProcessCommandsInternal] pos = %d distance = %d\n",
1677
+ pos, s->distance_code));
1639
1678
  if (s->max_distance != s->max_backward_distance) {
1640
1679
  if (pos < s->max_backward_distance_minus_custom_dict_size) {
1641
1680
  s->max_distance = pos + s->custom_dict_size;
@@ -1649,7 +1688,7 @@ postReadDistance:
1649
1688
  if (s->distance_code > s->max_distance) {
1650
1689
  if (i >= kBrotliMinDictionaryWordLength &&
1651
1690
  i <= kBrotliMaxDictionaryWordLength) {
1652
- int offset = kBrotliDictionaryOffsetsByLength[i];
1691
+ int offset = (int)kBrotliDictionaryOffsetsByLength[i];
1653
1692
  int word_id = s->distance_code - s->max_distance - 1;
1654
1693
  uint32_t shift = kBrotliDictionarySizeBitsByLength[i];
1655
1694
  int mask = (int)BitMask(shift);
@@ -1674,54 +1713,38 @@ postReadDistance:
1674
1713
  }
1675
1714
  } else {
1676
1715
  BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
1677
- "len: %d bytes left: %d\n",
1678
- pos, s->distance_code, i,
1679
- s->meta_block_remaining_len));
1680
- return BROTLI_FAILURE();
1716
+ "len: %d bytes left: %d\n",
1717
+ pos, s->distance_code, i, s->meta_block_remaining_len));
1718
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_TRANSFORM);
1681
1719
  }
1682
1720
  } else {
1683
1721
  BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
1684
- "len: %d bytes left: %d\n", pos, s->distance_code, i,
1685
- s->meta_block_remaining_len));
1686
- return BROTLI_FAILURE();
1722
+ "len: %d bytes left: %d\n",
1723
+ pos, s->distance_code, i, s->meta_block_remaining_len));
1724
+ return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_DICTIONARY);
1687
1725
  }
1688
1726
  } else {
1689
- const uint8_t *ringbuffer_end_minus_copy_length =
1690
- s->ringbuffer_end - i;
1691
- uint8_t* copy_src = &s->ringbuffer[
1692
- (pos - s->distance_code) & s->ringbuffer_mask];
1727
+ int src_start = (pos - s->distance_code) & s->ringbuffer_mask;
1693
1728
  uint8_t* copy_dst = &s->ringbuffer[pos];
1729
+ uint8_t* copy_src = &s->ringbuffer[src_start];
1730
+ int dst_end = pos + i;
1731
+ int src_end = src_start + i;
1694
1732
  /* update the recent distances cache */
1695
1733
  s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
1696
1734
  ++s->dist_rb_idx;
1697
1735
  s->meta_block_remaining_len -= i;
1698
- if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
1699
- BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
1700
- "len: %d bytes left: %d\n", pos, s->distance_code, i,
1701
- s->meta_block_remaining_len));
1702
- return BROTLI_FAILURE();
1703
- }
1704
- /* There is 128+ bytes of slack in the ringbuffer allocation.
1736
+ /* There are 32+ bytes of slack in the ringbuffer allocation.
1705
1737
  Also, we have 16 short codes, that make these 16 bytes irrelevant
1706
1738
  in the ringbuffer. Let's copy over them as a first guess.
1707
1739
  */
1708
1740
  memmove16(copy_dst, copy_src);
1709
- /* Now check if the copy extends over the ringbuffer end,
1710
- or if the copy overlaps with itself, if yes, do wrap-copy. */
1711
- if (copy_src < copy_dst) {
1712
- if (copy_dst >= ringbuffer_end_minus_copy_length) {
1713
- goto CommandPostWrapCopy;
1714
- }
1715
- if (copy_src + i > copy_dst) {
1716
- goto postSelfintersecting;
1717
- }
1718
- } else {
1719
- if (copy_src >= ringbuffer_end_minus_copy_length) {
1720
- goto CommandPostWrapCopy;
1721
- }
1722
- if (copy_dst + i > copy_src) {
1723
- goto postSelfintersecting;
1724
- }
1741
+ if (src_end > pos && dst_end > src_start) {
1742
+ /* Regions intersect. */
1743
+ goto CommandPostWrapCopy;
1744
+ }
1745
+ if (dst_end >= s->ringbuffer_size || src_end >= s->ringbuffer_size) {
1746
+ /* At least one region wraps. */
1747
+ goto CommandPostWrapCopy;
1725
1748
  }
1726
1749
  pos += i;
1727
1750
  if (i > 16) {
@@ -1734,6 +1757,7 @@ postReadDistance:
1734
1757
  }
1735
1758
  }
1736
1759
  }
1760
+ BROTLI_LOG_UINT(s->meta_block_remaining_len);
1737
1761
  if (s->meta_block_remaining_len <= 0) {
1738
1762
  /* Next metablock, if any */
1739
1763
  s->state = BROTLI_STATE_METABLOCK_DONE;
@@ -1741,30 +1765,17 @@ postReadDistance:
1741
1765
  } else {
1742
1766
  goto CommandBegin;
1743
1767
  }
1744
- postSelfintersecting:
1745
- while (--i >= 0) {
1746
- s->ringbuffer[pos] =
1747
- s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
1748
- ++pos;
1749
- }
1750
- if (s->meta_block_remaining_len <= 0) {
1751
- /* Next metablock, if any */
1752
- s->state = BROTLI_STATE_METABLOCK_DONE;
1753
- goto saveStateAndReturn;
1754
- } else {
1755
- goto CommandBegin;
1756
- }
1757
-
1758
1768
  CommandPostWrapCopy:
1759
- s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
1760
- while (--i >= 0) {
1761
- s->ringbuffer[pos] =
1762
- s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
1763
- ++pos;
1764
- if (pos == s->ringbuffer_size) {
1765
- /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
1766
- s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
1767
- goto saveStateAndReturn;
1769
+ {
1770
+ int wrap_guard = s->ringbuffer_size - pos;
1771
+ while (--i >= 0) {
1772
+ s->ringbuffer[pos] =
1773
+ s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
1774
+ ++pos;
1775
+ if (PREDICT_FALSE(--wrap_guard == 0)) {
1776
+ s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
1777
+ goto saveStateAndReturn;
1778
+ }
1768
1779
  }
1769
1780
  }
1770
1781
  if (s->meta_block_remaining_len <= 0) {
@@ -1783,11 +1794,11 @@ saveStateAndReturn:
1783
1794
 
1784
1795
  #undef BROTLI_SAFE
1785
1796
 
1786
- static BROTLI_NOINLINE BrotliResult ProcessCommands(BrotliState* s) {
1797
+ static BROTLI_NOINLINE BrotliErrorCode ProcessCommands(BrotliState* s) {
1787
1798
  return ProcessCommandsInternal(0, s);
1788
1799
  }
1789
1800
 
1790
- static BROTLI_NOINLINE BrotliResult SafeProcessCommands(BrotliState* s) {
1801
+ static BROTLI_NOINLINE BrotliErrorCode SafeProcessCommands(BrotliState* s) {
1791
1802
  return ProcessCommandsInternal(1, s);
1792
1803
  }
1793
1804
 
@@ -1813,113 +1824,6 @@ BrotliResult BrotliDecompressBuffer(size_t encoded_size,
1813
1824
  return result;
1814
1825
  }
1815
1826
 
1816
- BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output) {
1817
- BrotliState s;
1818
- BrotliResult result;
1819
- BrotliStateInit(&s);
1820
- result = BrotliDecompressStreaming(input, output, 1, &s);
1821
- if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
1822
- /* Not ok: it didn't finish even though this is a non-streaming function. */
1823
- result = BROTLI_FAILURE();
1824
- }
1825
- BrotliStateCleanup(&s);
1826
- return result;
1827
- }
1828
-
1829
- BrotliResult BrotliDecompressBufferStreaming(size_t* available_in,
1830
- const uint8_t** next_in,
1831
- int finish,
1832
- size_t* available_out,
1833
- uint8_t** next_out,
1834
- size_t* total_out,
1835
- BrotliState* s) {
1836
- BrotliResult result = BrotliDecompressStream(available_in, next_in,
1837
- available_out, next_out, total_out, s);
1838
- if (finish && result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
1839
- result = BROTLI_FAILURE();
1840
- }
1841
- return result;
1842
- }
1843
-
1844
- BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
1845
- int finish, BrotliState* s) {
1846
- const size_t kBufferSize = 65536;
1847
- BrotliResult result;
1848
- uint8_t* input_buffer;
1849
- uint8_t* output_buffer;
1850
- size_t avail_in;
1851
- const uint8_t* next_in;
1852
- size_t total_out;
1853
-
1854
- if (s->legacy_input_buffer == 0) {
1855
- s->legacy_input_buffer = (uint8_t*)BROTLI_ALLOC(s, kBufferSize);
1856
- }
1857
- if (s->legacy_output_buffer == 0) {
1858
- s->legacy_output_buffer = (uint8_t*)BROTLI_ALLOC(s, kBufferSize);
1859
- }
1860
- if (s->legacy_input_buffer == 0 || s->legacy_output_buffer == 0) {
1861
- return BROTLI_FAILURE();
1862
- }
1863
- input_buffer = s->legacy_input_buffer;
1864
- output_buffer = s->legacy_output_buffer;
1865
-
1866
- /* Push remaining output. */
1867
- if (s->legacy_output_len > s->legacy_output_pos) {
1868
- size_t to_write = s->legacy_output_len - s->legacy_output_pos;
1869
- int num_written = BrotliWrite(
1870
- output, output_buffer + s->legacy_output_pos, to_write);
1871
- if (num_written < 0) {
1872
- return BROTLI_FAILURE();
1873
- }
1874
- s->legacy_output_pos += (size_t)num_written;
1875
- if ((size_t)num_written < to_write) {
1876
- return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
1877
- }
1878
- }
1879
- s->legacy_output_pos = 0;
1880
-
1881
- avail_in = s->legacy_input_len - s->legacy_input_pos;
1882
- next_in = input_buffer + s->legacy_input_pos;
1883
-
1884
- while (1) {
1885
- size_t to_write;
1886
- int num_written;
1887
- size_t avail_out = kBufferSize;
1888
- uint8_t* next_out = output_buffer;
1889
- result = BrotliDecompressStream(&avail_in, &next_in,
1890
- &avail_out, &next_out, &total_out, s);
1891
- s->legacy_input_pos = (size_t)(next_out - input_buffer);
1892
- to_write = (size_t)(next_out - output_buffer);
1893
- num_written = BrotliWrite(output, output_buffer, to_write);
1894
- if (num_written < 0) {
1895
- return BROTLI_FAILURE();
1896
- }
1897
- if ((size_t)num_written < to_write) {
1898
- s->legacy_output_len = to_write;
1899
- s->legacy_output_pos = (size_t)num_written;
1900
- return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
1901
- }
1902
- if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
1903
- int num_read = BrotliRead(input, input_buffer, kBufferSize);
1904
- if (num_read < 0 || (num_read == 0 && finish)) {
1905
- return BROTLI_FAILURE();
1906
- }
1907
- if (num_read == 0) {
1908
- s->legacy_input_len = 0;
1909
- s->legacy_input_pos = 0;
1910
- return BROTLI_RESULT_NEEDS_MORE_INPUT;
1911
- }
1912
- avail_in = (size_t)num_read;
1913
- next_in = input_buffer;
1914
- s->legacy_input_len = avail_in;
1915
- s->legacy_input_pos = 0;
1916
- } else if (result != BROTLI_RESULT_NEEDS_MORE_OUTPUT) {
1917
- /* Success or failure. */
1918
- return result;
1919
- }
1920
- }
1921
- }
1922
-
1923
1827
  /* Invariant: input stream is never overconsumed:
1924
1828
  * invalid input implies that the whole stream is invalid -> any amount of
1925
1829
  input could be read and discarded
@@ -1935,7 +1839,7 @@ BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
1935
1839
  BrotliResult BrotliDecompressStream(size_t* available_in,
1936
1840
  const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
1937
1841
  size_t* total_out, BrotliState* s) {
1938
- BrotliResult result = BROTLI_RESULT_SUCCESS;
1842
+ BrotliErrorCode result = BROTLI_SUCCESS;
1939
1843
  BrotliBitReader* br = &s->br;
1940
1844
  if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
1941
1845
  br->avail_in = *available_in;
@@ -1944,13 +1848,13 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
1944
1848
  /* At least one byte of input is required. More than one byte of input may
1945
1849
  be required to complete the transaction -> reading more data must be
1946
1850
  done in a loop -> do it in a main loop. */
1947
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1851
+ result = BROTLI_NEEDS_MORE_INPUT;
1948
1852
  br->next_in = &s->buffer.u8[0];
1949
1853
  }
1950
1854
  /* State machine */
1951
1855
  for (;;) {
1952
- if (result != BROTLI_RESULT_SUCCESS) { /* Error | needs more input/output */
1953
- if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
1856
+ if (result != BROTLI_SUCCESS) { /* Error | needs more input/output */
1857
+ if (result == BROTLI_NEEDS_MORE_INPUT) {
1954
1858
  if (s->ringbuffer != 0) { /* Proactively push output. */
1955
1859
  WriteRingBuffer(available_out, next_out, total_out, s);
1956
1860
  }
@@ -1960,14 +1864,14 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
1960
1864
  is expanded byte-by-byte until it is enough to complete read. */
1961
1865
  s->buffer_length = 0;
1962
1866
  /* Switch to input stream and restart. */
1963
- result = BROTLI_RESULT_SUCCESS;
1867
+ result = BROTLI_SUCCESS;
1964
1868
  br->avail_in = *available_in;
1965
1869
  br->next_in = *next_in;
1966
1870
  continue;
1967
1871
  } else if (*available_in != 0) {
1968
1872
  /* Not enough data in buffer, but can take one more byte from
1969
1873
  input stream. */
1970
- result = BROTLI_RESULT_SUCCESS;
1874
+ result = BROTLI_SUCCESS;
1971
1875
  s->buffer.u8[s->buffer_length] = **next_in;
1972
1876
  s->buffer_length++;
1973
1877
  br->avail_in = s->buffer_length;
@@ -2013,7 +1917,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2013
1917
  case BROTLI_STATE_UNINITED:
2014
1918
  /* Prepare to the first read. */
2015
1919
  if (!BrotliWarmupBitReader(br)) {
2016
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1920
+ result = BROTLI_NEEDS_MORE_INPUT;
2017
1921
  break;
2018
1922
  }
2019
1923
  /* Decode window size. */
@@ -2021,22 +1925,29 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2021
1925
  BROTLI_LOG_UINT(s->window_bits);
2022
1926
  if (s->window_bits == 9) {
2023
1927
  /* Value 9 is reserved for future use. */
2024
- result = BROTLI_FAILURE();
1928
+ result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_WINDOW_BITS);
2025
1929
  break;
2026
1930
  }
1931
+ /* Maximum distance, see section 9.1. of the spec. */
2027
1932
  s->max_backward_distance = (1 << s->window_bits) - 16;
1933
+ /* Limit custom dictionary size. */
1934
+ if (s->custom_dict_size >= s->max_backward_distance) {
1935
+ s->custom_dict += s->custom_dict_size - s->max_backward_distance;
1936
+ s->custom_dict_size = s->max_backward_distance;
1937
+ }
2028
1938
  s->max_backward_distance_minus_custom_dict_size =
2029
1939
  s->max_backward_distance - s->custom_dict_size;
2030
1940
 
2031
1941
  /* Allocate memory for both block_type_trees and block_len_trees. */
2032
1942
  s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s,
2033
- 6 * BROTLI_HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode));
1943
+ sizeof(HuffmanCode) * 3 *
1944
+ (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26));
2034
1945
  if (s->block_type_trees == 0) {
2035
- result = BROTLI_FAILURE();
1946
+ result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_BLOCK_TYPE_TREES);
2036
1947
  break;
2037
1948
  }
2038
- s->block_len_trees = s->block_type_trees +
2039
- 3 * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
1949
+ s->block_len_trees =
1950
+ s->block_type_trees + 3 * BROTLI_HUFFMAN_MAX_SIZE_258;
2040
1951
 
2041
1952
  s->state = BROTLI_STATE_METABLOCK_BEGIN;
2042
1953
  /* No break, continue to next state */
@@ -2047,7 +1958,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2047
1958
  /* No break, continue to next state */
2048
1959
  case BROTLI_STATE_METABLOCK_HEADER:
2049
1960
  result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */
2050
- if (result != BROTLI_RESULT_SUCCESS) {
1961
+ if (result != BROTLI_SUCCESS) {
2051
1962
  break;
2052
1963
  }
2053
1964
  BROTLI_LOG_UINT(s->is_last_metablock);
@@ -2056,7 +1967,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2056
1967
  BROTLI_LOG_UINT(s->is_uncompressed);
2057
1968
  if (s->is_metadata || s->is_uncompressed) {
2058
1969
  if (!BrotliJumpToByteBoundary(br)) {
2059
- result = BROTLI_FAILURE();
1970
+ result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_PADDING_1);
2060
1971
  break;
2061
1972
  }
2062
1973
  }
@@ -2069,10 +1980,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2069
1980
  break;
2070
1981
  }
2071
1982
  if (!s->ringbuffer) {
2072
- if (!BrotliAllocateRingBuffer(s, br)) {
2073
- result = BROTLI_FAILURE();
2074
- break;
2075
- }
1983
+ BrotliCalculateRingBufferSize(s, br);
2076
1984
  }
2077
1985
  if (s->is_uncompressed) {
2078
1986
  s->state = BROTLI_STATE_UNCOMPRESSED;
@@ -2086,7 +1994,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2086
1994
  result = CopyUncompressedBlockToOutput(
2087
1995
  available_out, next_out, total_out, s);
2088
1996
  bytes_copied -= s->meta_block_remaining_len;
2089
- if (result != BROTLI_RESULT_SUCCESS) {
1997
+ if (result != BROTLI_SUCCESS) {
2090
1998
  break;
2091
1999
  }
2092
2000
  s->state = BROTLI_STATE_METABLOCK_DONE;
@@ -2097,11 +2005,11 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2097
2005
  uint32_t bits;
2098
2006
  /* Read one byte and ignore it. */
2099
2007
  if (!BrotliSafeReadBits(br, 8, &bits)) {
2100
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
2008
+ result = BROTLI_NEEDS_MORE_INPUT;
2101
2009
  break;
2102
2010
  }
2103
2011
  }
2104
- if (result == BROTLI_RESULT_SUCCESS) {
2012
+ if (result == BROTLI_SUCCESS) {
2105
2013
  s->state = BROTLI_STATE_METABLOCK_DONE;
2106
2014
  }
2107
2015
  break;
@@ -2112,7 +2020,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2112
2020
  }
2113
2021
  /* Reads 1..11 bits. */
2114
2022
  result = DecodeVarLenUint8(s, br, &s->num_block_types[s->loop_counter]);
2115
- if (result != BROTLI_RESULT_SUCCESS) {
2023
+ if (result != BROTLI_SUCCESS) {
2116
2024
  break;
2117
2025
  }
2118
2026
  s->num_block_types[s->loop_counter]++;
@@ -2124,26 +2032,26 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2124
2032
  s->state = BROTLI_STATE_HUFFMAN_CODE_1;
2125
2033
  /* No break, continue to next state */
2126
2034
  case BROTLI_STATE_HUFFMAN_CODE_1: {
2127
- int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
2035
+ int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
2128
2036
  result = ReadHuffmanCode(s->num_block_types[s->loop_counter] + 2,
2129
2037
  &s->block_type_trees[tree_offset], NULL, s);
2130
- if (result != BROTLI_RESULT_SUCCESS) break;
2038
+ if (result != BROTLI_SUCCESS) break;
2131
2039
  s->state = BROTLI_STATE_HUFFMAN_CODE_2;
2132
2040
  /* No break, continue to next state */
2133
2041
  }
2134
2042
  case BROTLI_STATE_HUFFMAN_CODE_2: {
2135
- int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
2043
+ int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
2136
2044
  result = ReadHuffmanCode(kNumBlockLengthCodes,
2137
2045
  &s->block_len_trees[tree_offset], NULL, s);
2138
- if (result != BROTLI_RESULT_SUCCESS) break;
2046
+ if (result != BROTLI_SUCCESS) break;
2139
2047
  s->state = BROTLI_STATE_HUFFMAN_CODE_3;
2140
2048
  /* No break, continue to next state */
2141
2049
  }
2142
2050
  case BROTLI_STATE_HUFFMAN_CODE_3: {
2143
- int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
2051
+ int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
2144
2052
  if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter],
2145
2053
  &s->block_len_trees[tree_offset], br)) {
2146
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
2054
+ result = BROTLI_NEEDS_MORE_INPUT;
2147
2055
  break;
2148
2056
  }
2149
2057
  BROTLI_LOG_UINT(s->block_length[s->loop_counter]);
@@ -2154,20 +2062,20 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2154
2062
  case BROTLI_STATE_METABLOCK_HEADER_2: {
2155
2063
  uint32_t bits;
2156
2064
  if (!BrotliSafeReadBits(br, 6, &bits)) {
2157
- result = BROTLI_RESULT_NEEDS_MORE_INPUT;
2065
+ result = BROTLI_NEEDS_MORE_INPUT;
2158
2066
  break;
2159
2067
  }
2160
2068
  s->distance_postfix_bits = bits & BitMask(2);
2161
2069
  bits >>= 2;
2162
- s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
2163
- (bits << s->distance_postfix_bits);
2070
+ s->num_direct_distance_codes =
2071
+ NUM_DISTANCE_SHORT_CODES + (bits << s->distance_postfix_bits);
2164
2072
  BROTLI_LOG_UINT(s->num_direct_distance_codes);
2165
2073
  BROTLI_LOG_UINT(s->distance_postfix_bits);
2166
2074
  s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
2167
2075
  s->context_modes =
2168
2076
  (uint8_t*)BROTLI_ALLOC(s, (size_t)s->num_block_types[0]);
2169
2077
  if (s->context_modes == 0) {
2170
- result = BROTLI_FAILURE();
2078
+ result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_CONTEXT_MODES);
2171
2079
  break;
2172
2080
  }
2173
2081
  s->loop_counter = 0;
@@ -2176,28 +2084,21 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2176
2084
  }
2177
2085
  case BROTLI_STATE_CONTEXT_MODES:
2178
2086
  result = ReadContextModes(s);
2179
- if (result != BROTLI_RESULT_SUCCESS) {
2087
+ if (result != BROTLI_SUCCESS) {
2180
2088
  break;
2181
2089
  }
2182
2090
  s->state = BROTLI_STATE_CONTEXT_MAP_1;
2183
2091
  /* No break, continue to next state */
2184
- case BROTLI_STATE_CONTEXT_MAP_1: {
2185
- uint32_t j;
2186
- result = DecodeContextMap(s->num_block_types[0] << kLiteralContextBits,
2187
- &s->num_literal_htrees, &s->context_map, s);
2188
- if (result != BROTLI_RESULT_SUCCESS) {
2092
+ case BROTLI_STATE_CONTEXT_MAP_1:
2093
+ result = DecodeContextMap(
2094
+ s->num_block_types[0] << kLiteralContextBits,
2095
+ &s->num_literal_htrees, &s->context_map, s);
2096
+ if (result != BROTLI_SUCCESS) {
2189
2097
  break;
2190
2098
  }
2191
- s->trivial_literal_context = 1;
2192
- for (j = 0; j < s->num_block_types[0] << kLiteralContextBits; j++) {
2193
- if (s->context_map[j] != j >> kLiteralContextBits) {
2194
- s->trivial_literal_context = 0;
2195
- break;
2196
- }
2197
- }
2099
+ DetectTrivialLiteralBlockTypes(s);
2198
2100
  s->state = BROTLI_STATE_CONTEXT_MAP_2;
2199
2101
  /* No break, continue to next state */
2200
- }
2201
2102
  case BROTLI_STATE_CONTEXT_MAP_2:
2202
2103
  {
2203
2104
  uint32_t num_distance_codes =
@@ -2205,20 +2106,21 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2205
2106
  result = DecodeContextMap(
2206
2107
  s->num_block_types[2] << kDistanceContextBits,
2207
2108
  &s->num_dist_htrees, &s->dist_context_map, s);
2208
- if (result != BROTLI_RESULT_SUCCESS) {
2109
+ if (result != BROTLI_SUCCESS) {
2209
2110
  break;
2210
2111
  }
2211
2112
  BrotliHuffmanTreeGroupInit(s, &s->literal_hgroup, kNumLiteralCodes,
2212
2113
  s->num_literal_htrees);
2213
2114
  BrotliHuffmanTreeGroupInit(s, &s->insert_copy_hgroup,
2214
2115
  kNumInsertAndCopyCodes,
2215
- s->num_block_types[1]);
2116
+ s->num_block_types[1]);
2216
2117
  BrotliHuffmanTreeGroupInit(s, &s->distance_hgroup, num_distance_codes,
2217
2118
  s->num_dist_htrees);
2218
2119
  if (s->literal_hgroup.codes == 0 ||
2219
2120
  s->insert_copy_hgroup.codes == 0 ||
2220
2121
  s->distance_hgroup.codes == 0) {
2221
- return BROTLI_FAILURE();
2122
+ return SaveErrorCode(s,
2123
+ BROTLI_FAILURE(BROTLI_ERROR_ALLOC_TREE_GROUPS));
2222
2124
  }
2223
2125
  }
2224
2126
  s->loop_counter = 0;
@@ -2237,21 +2139,22 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2237
2139
  case 2:
2238
2140
  hgroup = &s->distance_hgroup;
2239
2141
  break;
2142
+ default:
2143
+ return SaveErrorCode(s,
2144
+ BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE));
2240
2145
  }
2241
2146
  result = HuffmanTreeGroupDecode(hgroup, s);
2242
2147
  }
2243
- if (result != BROTLI_RESULT_SUCCESS) break;
2148
+ if (result != BROTLI_SUCCESS) break;
2244
2149
  s->loop_counter++;
2245
2150
  if (s->loop_counter >= 3) {
2246
- uint8_t context_mode = s->context_modes[s->block_type_rb[1]];
2247
- s->context_map_slice = s->context_map;
2151
+ PrepareLiteralDecoding(s);
2248
2152
  s->dist_context_map_slice = s->dist_context_map;
2249
- s->context_lookup1 =
2250
- &kContextLookup[kContextLookupOffsets[context_mode]];
2251
- s->context_lookup2 =
2252
- &kContextLookup[kContextLookupOffsets[context_mode + 1]];
2253
2153
  s->htree_command = s->insert_copy_hgroup.htrees[0];
2254
- s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
2154
+ if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {
2155
+ result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_RING_BUFFER_2);
2156
+ break;
2157
+ }
2255
2158
  s->state = BROTLI_STATE_COMMAND_BEGIN;
2256
2159
  }
2257
2160
  break;
@@ -2260,7 +2163,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2260
2163
  case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS:
2261
2164
  case BROTLI_STATE_COMMAND_POST_WRAP_COPY:
2262
2165
  result = ProcessCommands(s);
2263
- if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
2166
+ if (result == BROTLI_NEEDS_MORE_INPUT) {
2264
2167
  result = SafeProcessCommands(s);
2265
2168
  }
2266
2169
  break;
@@ -2268,15 +2171,13 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2268
2171
  case BROTLI_STATE_COMMAND_POST_WRITE_1:
2269
2172
  case BROTLI_STATE_COMMAND_POST_WRITE_2:
2270
2173
  result = WriteRingBuffer(available_out, next_out, total_out, s);
2271
- if (result != BROTLI_RESULT_SUCCESS) {
2174
+ if (result != BROTLI_SUCCESS) {
2272
2175
  break;
2273
2176
  }
2274
- s->pos -= s->ringbuffer_size;
2275
- s->rb_roundtrips++;
2276
2177
  s->max_distance = s->max_backward_distance;
2277
2178
  if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
2278
2179
  memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
2279
- if (s->meta_block_remaining_len <= 0) {
2180
+ if (s->meta_block_remaining_len == 0) {
2280
2181
  /* Next metablock, if any */
2281
2182
  s->state = BROTLI_STATE_METABLOCK_DONE;
2282
2183
  } else {
@@ -2287,7 +2188,7 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2287
2188
  s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2288
2189
  } else { /* BROTLI_STATE_COMMAND_INNER_WRITE */
2289
2190
  if (s->loop_counter == 0) {
2290
- if (s->meta_block_remaining_len <= 0) {
2191
+ if (s->meta_block_remaining_len == 0) {
2291
2192
  s->state = BROTLI_STATE_METABLOCK_DONE;
2292
2193
  } else {
2293
2194
  s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
@@ -2298,13 +2199,18 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2298
2199
  }
2299
2200
  break;
2300
2201
  case BROTLI_STATE_METABLOCK_DONE:
2202
+ if (s->meta_block_remaining_len < 0) {
2203
+ result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_BLOCK_LENGTH_2);
2204
+ break;
2205
+ }
2301
2206
  BrotliStateCleanupAfterMetablock(s);
2302
2207
  if (!s->is_last_metablock) {
2303
2208
  s->state = BROTLI_STATE_METABLOCK_BEGIN;
2304
2209
  break;
2305
2210
  }
2306
2211
  if (!BrotliJumpToByteBoundary(br)) {
2307
- result = BROTLI_FAILURE();
2212
+ result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_PADDING_2);
2213
+ break;
2308
2214
  }
2309
2215
  if (s->buffer_length == 0) {
2310
2216
  BrotliBitReaderUnload(br);
@@ -2316,23 +2222,41 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
2316
2222
  case BROTLI_STATE_DONE:
2317
2223
  if (s->ringbuffer != 0) {
2318
2224
  result = WriteRingBuffer(available_out, next_out, total_out, s);
2319
- if (result != BROTLI_RESULT_SUCCESS) {
2225
+ if (result != BROTLI_SUCCESS) {
2320
2226
  break;
2321
2227
  }
2322
2228
  }
2323
- return result;
2229
+ return SaveErrorCode(s, result);
2324
2230
  }
2325
2231
  }
2326
- return result;
2232
+ return SaveErrorCode(s, result);
2327
2233
  }
2328
2234
 
2329
2235
  void BrotliSetCustomDictionary(
2330
2236
  size_t size, const uint8_t* dict, BrotliState* s) {
2237
+ if (size > (1u << 24)) {
2238
+ return;
2239
+ }
2331
2240
  s->custom_dict = dict;
2332
- s->custom_dict_size = (int) size;
2241
+ s->custom_dict_size = (int)size;
2242
+ }
2243
+
2244
+ BrotliErrorCode BrotliGetErrorCode(const BrotliState* s) {
2245
+ return (BrotliErrorCode)s->error_code;
2333
2246
  }
2334
2247
 
2248
+ const char* BrotliErrorString(BrotliErrorCode c) {
2249
+ switch (c) {
2250
+ #define _BROTLI_ERROR_CODE_CASE(PREFIX, NAME, CODE) \
2251
+ case BROTLI ## PREFIX ## NAME: return #NAME;
2252
+ #define _BROTLI_NOTHING
2253
+ BROTLI_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_CASE, _BROTLI_NOTHING)
2254
+ #undef _BROTLI_ERROR_CODE_CASE
2255
+ #undef _BROTLI_NOTHING
2256
+ default: return "INVALID";
2257
+ }
2258
+ }
2335
2259
 
2336
2260
  #if defined(__cplusplus) || defined(c_plusplus)
2337
- } /* extern "C" */
2261
+ } /* extern "C" */
2338
2262
  #endif