extbrotli 0.0.1.PROTOTYPE

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +28 -0
  3. data/README.md +67 -0
  4. data/Rakefile +158 -0
  5. data/contrib/brotli/LICENSE +202 -0
  6. data/contrib/brotli/README.md +18 -0
  7. data/contrib/brotli/dec/bit_reader.c +55 -0
  8. data/contrib/brotli/dec/bit_reader.h +256 -0
  9. data/contrib/brotli/dec/context.h +260 -0
  10. data/contrib/brotli/dec/decode.c +1573 -0
  11. data/contrib/brotli/dec/decode.h +160 -0
  12. data/contrib/brotli/dec/dictionary.h +9494 -0
  13. data/contrib/brotli/dec/huffman.c +325 -0
  14. data/contrib/brotli/dec/huffman.h +77 -0
  15. data/contrib/brotli/dec/port.h +148 -0
  16. data/contrib/brotli/dec/prefix.h +756 -0
  17. data/contrib/brotli/dec/state.c +149 -0
  18. data/contrib/brotli/dec/state.h +185 -0
  19. data/contrib/brotli/dec/streams.c +99 -0
  20. data/contrib/brotli/dec/streams.h +100 -0
  21. data/contrib/brotli/dec/transform.h +315 -0
  22. data/contrib/brotli/dec/types.h +36 -0
  23. data/contrib/brotli/enc/backward_references.cc +769 -0
  24. data/contrib/brotli/enc/backward_references.h +50 -0
  25. data/contrib/brotli/enc/bit_cost.h +147 -0
  26. data/contrib/brotli/enc/block_splitter.cc +418 -0
  27. data/contrib/brotli/enc/block_splitter.h +78 -0
  28. data/contrib/brotli/enc/brotli_bit_stream.cc +884 -0
  29. data/contrib/brotli/enc/brotli_bit_stream.h +149 -0
  30. data/contrib/brotli/enc/cluster.h +290 -0
  31. data/contrib/brotli/enc/command.h +140 -0
  32. data/contrib/brotli/enc/context.h +185 -0
  33. data/contrib/brotli/enc/dictionary.h +9485 -0
  34. data/contrib/brotli/enc/dictionary_hash.h +4125 -0
  35. data/contrib/brotli/enc/encode.cc +715 -0
  36. data/contrib/brotli/enc/encode.h +196 -0
  37. data/contrib/brotli/enc/encode_parallel.cc +354 -0
  38. data/contrib/brotli/enc/encode_parallel.h +37 -0
  39. data/contrib/brotli/enc/entropy_encode.cc +492 -0
  40. data/contrib/brotli/enc/entropy_encode.h +88 -0
  41. data/contrib/brotli/enc/fast_log.h +179 -0
  42. data/contrib/brotli/enc/find_match_length.h +87 -0
  43. data/contrib/brotli/enc/hash.h +686 -0
  44. data/contrib/brotli/enc/histogram.cc +76 -0
  45. data/contrib/brotli/enc/histogram.h +100 -0
  46. data/contrib/brotli/enc/literal_cost.cc +172 -0
  47. data/contrib/brotli/enc/literal_cost.h +38 -0
  48. data/contrib/brotli/enc/metablock.cc +544 -0
  49. data/contrib/brotli/enc/metablock.h +88 -0
  50. data/contrib/brotli/enc/port.h +151 -0
  51. data/contrib/brotli/enc/prefix.h +85 -0
  52. data/contrib/brotli/enc/ringbuffer.h +108 -0
  53. data/contrib/brotli/enc/static_dict.cc +441 -0
  54. data/contrib/brotli/enc/static_dict.h +40 -0
  55. data/contrib/brotli/enc/static_dict_lut.h +12063 -0
  56. data/contrib/brotli/enc/streams.cc +127 -0
  57. data/contrib/brotli/enc/streams.h +129 -0
  58. data/contrib/brotli/enc/transform.h +250 -0
  59. data/contrib/brotli/enc/write_bits.h +91 -0
  60. data/ext/extbrotli.cc +24 -0
  61. data/ext/extbrotli.h +73 -0
  62. data/ext/extconf.rb +35 -0
  63. data/ext/lldecoder.c +220 -0
  64. data/ext/llencoder.cc +433 -0
  65. data/gemstub.rb +21 -0
  66. data/lib/extbrotli.rb +243 -0
  67. data/lib/extbrotli/version.rb +3 -0
  68. metadata +140 -0
@@ -0,0 +1,1573 @@
1
+ /* Copyright 2013 Google Inc. All Rights Reserved.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+ */
15
+
16
+ #include <stdlib.h>
17
+ #include <stdio.h>
18
+ #include <string.h>
19
+ #include "./bit_reader.h"
20
+ #include "./context.h"
21
+ #include "./decode.h"
22
+ #include "./dictionary.h"
23
+ #include "./port.h"
24
+ #include "./transform.h"
25
+ #include "./huffman.h"
26
+ #include "./prefix.h"
27
+
28
+ #ifdef __ARM_NEON__
29
+ #include <arm_neon.h>
30
+ #endif
31
+
32
+ #if defined(__cplusplus) || defined(c_plusplus)
33
+ extern "C" {
34
+ #endif
35
+
36
+ #ifdef BROTLI_DECODE_DEBUG
37
+ #define BROTLI_LOG_UINT(name) \
38
+ printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))
39
+ #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
40
+ printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
41
+ (unsigned long)(idx), (unsigned long)array_name[idx])
42
+ #define BROTLI_LOG(x) printf x
43
+ #else
44
+ #define BROTLI_LOG_UINT(name)
45
+ #define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
46
+ #define BROTLI_LOG(x)
47
+ #endif
48
+
49
+ static const uint8_t kDefaultCodeLength = 8;
50
+ static const uint8_t kCodeLengthRepeatCode = 16;
51
+ static const int kNumLiteralCodes = 256;
52
+ static const int kNumInsertAndCopyCodes = 704;
53
+ static const int kNumBlockLengthCodes = 26;
54
+ static const int kLiteralContextBits = 6;
55
+ static const int kDistanceContextBits = 2;
56
+
57
+ #define HUFFMAN_TABLE_BITS 8
58
+ #define HUFFMAN_TABLE_MASK 0xff
59
+
60
+ #define CODE_LENGTH_CODES 18
61
+ static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
62
+ 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
63
+ };
64
+
65
+ #define NUM_DISTANCE_SHORT_CODES 16
66
+
67
+
68
+ static uint32_t DecodeWindowBits(BrotliBitReader* br) {
69
+ uint32_t n;
70
+ if (BrotliReadBits(br, 1) == 0) {
71
+ return 16;
72
+ }
73
+ n = BrotliReadBits(br, 3);
74
+ if (n != 0) {
75
+ return 17 + n;
76
+ }
77
+ n = BrotliReadBits(br, 3);
78
+ if (n != 0) {
79
+ return 8 + n;
80
+ }
81
+ return 17;
82
+ }
83
+
84
+ static BROTLI_INLINE BROTLI_NO_ASAN void memmove16(
85
+ uint8_t* dst, uint8_t* src) {
86
+ #ifdef __ARM_NEON__
87
+ vst1q_u8(dst, vld1q_u8(src));
88
+ #else
89
+ /* memcpy is unsafe for overlapping regions and ASAN detects this.
90
+ But, because of optimizations, it works exactly as memmove:
91
+ copies data to registers first, and then stores them to dst. */
92
+ memcpy(dst, src, 16);
93
+ #endif
94
+ }
95
+
96
+ /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
97
+ static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) {
98
+ if (BrotliReadBits(br, 1)) {
99
+ int nbits = (int)BrotliReadBits(br, 3);
100
+ if (nbits == 0) {
101
+ return 1;
102
+ } else {
103
+ return (int)BrotliReadBits(br, nbits) + (1 << nbits);
104
+ }
105
+ }
106
+ return 0;
107
+ }
108
+
109
+ static BrotliResult DecodeMetaBlockLength(BrotliBitReader* br,
110
+ int* meta_block_length,
111
+ int* input_end,
112
+ int* is_metadata,
113
+ int* is_uncompressed) {
114
+ int size_nibbles;
115
+ int size_bytes;
116
+ int i;
117
+ *input_end = (int)BrotliReadBits(br, 1);
118
+ *meta_block_length = 0;
119
+ *is_uncompressed = 0;
120
+ *is_metadata = 0;
121
+ if (*input_end && BrotliReadBits(br, 1)) {
122
+ return BROTLI_RESULT_SUCCESS;
123
+ }
124
+ size_nibbles = (int)BrotliReadBits(br, 2) + 4;
125
+ if (size_nibbles == 7) {
126
+ *is_metadata = 1;
127
+ /* Verify reserved bit. */
128
+ if (BrotliReadBits(br, 1) != 0) {
129
+ return BROTLI_FAILURE();
130
+ }
131
+ size_bytes = (int)BrotliReadBits(br, 2);
132
+ if (size_bytes == 0) {
133
+ return BROTLI_RESULT_SUCCESS;
134
+ }
135
+ for (i = 0; i < size_bytes; ++i) {
136
+ int next_byte = (int)BrotliReadBits(br, 8);
137
+ if (i + 1 == size_bytes && size_bytes > 1 && next_byte == 0) {
138
+ return BROTLI_FAILURE();
139
+ }
140
+ *meta_block_length |= next_byte << (i * 8);
141
+ }
142
+ } else {
143
+ for (i = 0; i < size_nibbles; ++i) {
144
+ int next_nibble = (int)BrotliReadBits(br, 4);
145
+ if (i + 1 == size_nibbles && size_nibbles > 4 && next_nibble == 0) {
146
+ return BROTLI_FAILURE();
147
+ }
148
+ *meta_block_length |= next_nibble << (i * 4);
149
+ }
150
+ }
151
+ ++(*meta_block_length);
152
+ if (!*input_end && !*is_metadata) {
153
+ *is_uncompressed = (int)BrotliReadBits(br, 1);
154
+ }
155
+ return BROTLI_RESULT_SUCCESS;
156
+ }
157
+
158
+ /* Decodes the next Huffman code from bit-stream. */
159
+ static BROTLI_INLINE int ReadSymbol(const HuffmanCode* table,
160
+ BrotliBitReader* br) {
161
+ /* Read the bits for two reads at once. */
162
+ uint32_t val = BrotliGetBitsUnmasked(br, 15);
163
+ table += val & HUFFMAN_TABLE_MASK;
164
+ if (table->bits > HUFFMAN_TABLE_BITS) {
165
+ int nbits = table->bits - HUFFMAN_TABLE_BITS;
166
+ BrotliDropBits(br, HUFFMAN_TABLE_BITS);
167
+ table += table->value;
168
+ table += (int)(val >> HUFFMAN_TABLE_BITS) & (int)BitMask(nbits);
169
+ }
170
+ BrotliDropBits(br, table->bits);
171
+ return table->value;
172
+ }
173
+
174
+ static BROTLI_INLINE void PreloadSymbol(const HuffmanCode* table,
175
+ BrotliBitReader* br,
176
+ unsigned* bits,
177
+ unsigned* value) {
178
+ table += BrotliGetBits(br, HUFFMAN_TABLE_BITS);
179
+ *bits = table->bits;
180
+ *value = table->value;
181
+ }
182
+
183
+ static BROTLI_INLINE unsigned ReadPreloadedSymbol(const HuffmanCode* table,
184
+ BrotliBitReader* br,
185
+ unsigned* bits,
186
+ unsigned* value) {
187
+ unsigned result = *value;
188
+ if (PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
189
+ uint32_t val = BrotliGetBitsUnmasked(br, 15);
190
+ const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
191
+ int mask = (int)BitMask((int)(*bits - HUFFMAN_TABLE_BITS));
192
+ BrotliDropBits(br, HUFFMAN_TABLE_BITS);
193
+ ext += (int)(val >> HUFFMAN_TABLE_BITS) & mask;
194
+ BrotliDropBits(br, ext->bits);
195
+ result = ext->value;
196
+ } else {
197
+ BrotliDropBits(br, (int)*bits);
198
+ }
199
+ PreloadSymbol(table, br, bits, value);
200
+ return result;
201
+ }
202
+
203
+ static BrotliResult ReadHuffmanCode(int alphabet_size,
204
+ HuffmanCode* table,
205
+ int* opt_table_size,
206
+ BrotliState* s) {
207
+ BrotliBitReader* br = &s->br;
208
+ /* simple_code_or_skip is used as follows:
209
+ 1 for simple code;
210
+ 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
211
+ int simple_code_or_skip;
212
+ unsigned symbol = s->symbol;
213
+ uint32_t repeat = s->repeat;
214
+ uint8_t prev_code_len = s->prev_code_len;
215
+ uint8_t repeat_code_len = s->repeat_code_len;
216
+ uint32_t space = s->space;
217
+ uint16_t* symbol_lists = s->symbol_lists;
218
+ int* next_symbol = s->next_symbol;
219
+ int i = 0;
220
+ /* Unnecessary masking, but might be good for safety. */
221
+ alphabet_size &= 0x3ff;
222
+ /* State machine */
223
+ if (s->sub1_state == BROTLI_STATE_SUB1_NONE) {
224
+ if (!BrotliCheckInputAmount(br, 32)) {
225
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
226
+ }
227
+ simple_code_or_skip = (int)BrotliReadBits(br, 2);
228
+ BROTLI_LOG_UINT(simple_code_or_skip);
229
+ if (simple_code_or_skip == 1) {
230
+ /* Read symbols, codes & code lengths directly. */
231
+ int table_size;
232
+ int max_bits_counter = alphabet_size - 1;
233
+ int max_bits = 0;
234
+ uint16_t symbols[4] = { 0 };
235
+ uint32_t num_symbols = BrotliReadBits(br, 2);
236
+ i = 0;
237
+ while (max_bits_counter) {
238
+ max_bits_counter >>= 1;
239
+ ++max_bits;
240
+ }
241
+ do {
242
+ int k;
243
+ uint32_t v = BrotliReadBits(br, max_bits);
244
+ if (v >= alphabet_size) {
245
+ return BROTLI_FAILURE();
246
+ }
247
+ symbols[i] = (uint16_t)v;
248
+ for (k = 0; k < i; k++) {
249
+ if (symbols[k] == (uint16_t)v) {
250
+ return BROTLI_FAILURE();
251
+ }
252
+ }
253
+ } while (++i <= num_symbols);
254
+ if (num_symbols == 3) {
255
+ num_symbols += BrotliReadBits(br, 1);
256
+ }
257
+ BROTLI_LOG_UINT(num_symbols);
258
+ table_size = BrotliBuildSimpleHuffmanTable(
259
+ table, HUFFMAN_TABLE_BITS, symbols, num_symbols);
260
+ if (opt_table_size) {
261
+ *opt_table_size = table_size;
262
+ }
263
+ s->sub1_state = BROTLI_STATE_SUB1_NONE;
264
+ return BROTLI_RESULT_SUCCESS;
265
+ } else { /* Decode Huffman-coded code lengths. */
266
+ int i;
267
+ int8_t num_codes = 0;
268
+ /* Static Huffman code for the code length code lengths. */
269
+ static const uint8_t huff_len[16] = {
270
+ 2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4,
271
+ };
272
+ static const uint8_t huff_val[16] = {
273
+ 0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,
274
+ };
275
+ space = 32;
276
+ memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));
277
+ memset(&s->code_length_code_lengths[0], 0,
278
+ sizeof(s->code_length_code_lengths));
279
+ for (i = simple_code_or_skip;
280
+ i < CODE_LENGTH_CODES; ++i) {
281
+ const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
282
+ uint8_t ix = (uint8_t)BrotliGetBits(br, 4);
283
+ uint8_t v = huff_val[ix];
284
+ BrotliDropBits(br, huff_len[ix]);
285
+ s->code_length_code_lengths[code_len_idx] = v;
286
+ BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx);
287
+ if (v != 0) {
288
+ space = space - (32U >> v);
289
+ ++num_codes;
290
+ ++s->code_length_histo[v];
291
+ if (space - 1U >= 32U) {
292
+ /* space is 0 or wrapped around */
293
+ break;
294
+ }
295
+ }
296
+ }
297
+ if (!(num_codes == 1 || space == 0)) {
298
+ return BROTLI_FAILURE();
299
+ }
300
+ }
301
+ BrotliBuildCodeLengthsHuffmanTable(s->table,
302
+ s->code_length_code_lengths,
303
+ s->code_length_histo);
304
+ memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));
305
+ for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {
306
+ next_symbol[i] = i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
307
+ symbol_lists[i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1)] = 0xFFFF;
308
+ }
309
+
310
+ symbol = 0;
311
+ prev_code_len = kDefaultCodeLength;
312
+ repeat = 0;
313
+ repeat_code_len = 0;
314
+ space = 32768;
315
+ s->sub1_state = BROTLI_STATE_SUB1_HUFFMAN_LENGTH_SYMBOLS;
316
+ }
317
+
318
+ while (symbol < alphabet_size && space > 0) {
319
+ uint32_t milestone;
320
+ if (!BrotliCheckInputAmount(br, 128)) {
321
+ s->symbol = (uint32_t)symbol;
322
+ s->repeat = repeat;
323
+ s->prev_code_len = prev_code_len;
324
+ s->repeat_code_len = repeat_code_len;
325
+ s->space = space;
326
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
327
+ }
328
+ /* We use at most 5 bits per symbol. 128 * 8 / 5 = 204.8 */
329
+ milestone = symbol + 204;
330
+ if (milestone > alphabet_size) {
331
+ milestone = (uint32_t)alphabet_size;
332
+ }
333
+ while (symbol < milestone && space > 0) {
334
+ const HuffmanCode* p = s->table;
335
+ uint8_t code_len;
336
+ p += BrotliGetBits(br, BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
337
+ BrotliDropBits(br, p->bits);
338
+ code_len = (uint8_t)p->value;
339
+ if (code_len < kCodeLengthRepeatCode) {
340
+ repeat = 0;
341
+ if (code_len != 0) {
342
+ symbol_lists[next_symbol[code_len]] = (uint16_t)symbol;
343
+ next_symbol[code_len] = (int)symbol;
344
+ prev_code_len = code_len;
345
+ space -= 32768U >> code_len;
346
+ s->code_length_histo[code_len]++;
347
+ }
348
+ symbol++;
349
+ } else {
350
+ const int extra_bits = code_len - 14;
351
+ uint32_t old_repeat;
352
+ uint32_t repeat_delta;
353
+ uint8_t new_len = 0;
354
+ if (code_len == kCodeLengthRepeatCode) {
355
+ new_len = prev_code_len;
356
+ }
357
+ if (repeat_code_len != new_len) {
358
+ repeat = 0;
359
+ repeat_code_len = new_len;
360
+ }
361
+ old_repeat = repeat;
362
+ if (repeat > 0) {
363
+ repeat -= 2;
364
+ repeat <<= extra_bits;
365
+ }
366
+ repeat += BrotliReadBits(br, extra_bits) + 3;
367
+ repeat_delta = repeat - old_repeat;
368
+ if (symbol + repeat_delta > alphabet_size) {
369
+ return BROTLI_FAILURE();
370
+ }
371
+ if (repeat_code_len != 0) {
372
+ unsigned last = symbol + repeat_delta;
373
+ i = next_symbol[repeat_code_len];
374
+ do {
375
+ symbol_lists[i] = (uint16_t)symbol;
376
+ i = (int)symbol;
377
+ } while (++symbol != last);
378
+ next_symbol[repeat_code_len] = i;
379
+ space -= repeat_delta << (15 - repeat_code_len);
380
+ s->code_length_histo[repeat_code_len] = (uint16_t)
381
+ (s->code_length_histo[repeat_code_len] + repeat_delta);
382
+ } else {
383
+ symbol += repeat_delta;
384
+ }
385
+ }
386
+ }
387
+ }
388
+ if (space != 0) {
389
+ BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", space));
390
+ return BROTLI_FAILURE();
391
+ }
392
+ {
393
+ int table_size = BrotliBuildHuffmanTable(
394
+ table, HUFFMAN_TABLE_BITS, symbol_lists,
395
+ s->code_length_histo);
396
+ if (opt_table_size) {
397
+ *opt_table_size = table_size;
398
+ }
399
+ }
400
+ s->sub1_state = BROTLI_STATE_SUB1_NONE;
401
+ return BROTLI_RESULT_SUCCESS;
402
+ }
403
+
404
+ static BROTLI_INLINE int ReadBlockLength(const HuffmanCode* table,
405
+ BrotliBitReader* br) {
406
+ int code;
407
+ int nbits;
408
+ code = ReadSymbol(table, br);
409
+ nbits = kBlockLengthPrefixCode[code].nbits;
410
+ return kBlockLengthPrefixCode[code].offset + (int)BrotliReadBits(br, nbits);
411
+ }
412
+
413
+ /* Transform:
414
+ 1) initialize list L with values 0, 1,... 255
415
+ 2) For each input element X:
416
+ 2.1) let Y = L[X]
417
+ 2.2) remove X-th element from L
418
+ 2.3) prepend Y to L
419
+ 2.4) append Y to output
420
+
421
+ In most cases max(Y) <= 7, so most of L remains intact.
422
+ To reduce the cost of initialization, we reuse L, remember the upper bound
423
+ of Y values, and reinitialize only first elements in L.
424
+
425
+ Most of input values are 0 and 1. To reduce number of brances, we replace
426
+ inner for loop with do-while.
427
+ */
428
+ static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v, int v_len,
429
+ BrotliState* state) {
430
+ /* Reinitialize elements that could have been changed. */
431
+ int i = 4;
432
+ int upper_bound = state->mtf_upper_bound;
433
+ uint8_t* mtf = state->mtf;
434
+ /* Load endian-aware constant. */
435
+ const uint8_t b0123[4] = {0, 1, 2, 3};
436
+ uint32_t pattern;
437
+ memcpy(&pattern, &b0123, 4);
438
+
439
+ /* Initialize list using 4 consequent values pattern. */
440
+ *(uint32_t*)mtf = pattern;
441
+ do {
442
+ pattern += 0x04040404; /* Advance all 4 values by 4. */
443
+ *(uint32_t*)(mtf + i) = pattern;
444
+ i += 4;
445
+ } while (i <= upper_bound);
446
+
447
+ /* Transform the input. */
448
+ upper_bound = 0;
449
+ for (i = 0; i < v_len; ++i) {
450
+ int index = v[i];
451
+ uint8_t value = mtf[index];
452
+ v[i] = value;
453
+ upper_bound |= index;
454
+ do {
455
+ index--;
456
+ mtf[index + 1] = mtf[index];
457
+ } while (index > 0);
458
+ mtf[0] = value;
459
+ }
460
+ /* Remember amount of elements to be reinitialized. */
461
+ state->mtf_upper_bound = upper_bound;
462
+ }
463
+
464
+ /* Expose function for testing. Will be removed by linker as unused. */
465
+ void InverseMoveToFrontTransformForTesting(uint8_t* v, int l, BrotliState* s) {
466
+ InverseMoveToFrontTransform(v, l, s);
467
+ }
468
+
469
+
470
+ static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
471
+ BrotliState* s) {
472
+ if (s->sub0_state != BROTLI_STATE_SUB0_TREE_GROUP) {
473
+ s->next = group->codes;
474
+ s->htree_index = 0;
475
+ s->sub0_state = BROTLI_STATE_SUB0_TREE_GROUP;
476
+ }
477
+ while (s->htree_index < group->num_htrees) {
478
+ int table_size;
479
+ BrotliResult result =
480
+ ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);
481
+ if (result != BROTLI_RESULT_SUCCESS) return result;
482
+ group->htrees[s->htree_index] = s->next;
483
+ s->next += table_size;
484
+ if (table_size == 0) {
485
+ return BROTLI_FAILURE();
486
+ }
487
+ ++s->htree_index;
488
+ }
489
+ s->sub0_state = BROTLI_STATE_SUB0_NONE;
490
+ return BROTLI_RESULT_SUCCESS;
491
+ }
492
+
493
+ static BrotliResult DecodeContextMap(int context_map_size,
494
+ int* num_htrees,
495
+ uint8_t** context_map_arg,
496
+ BrotliState* s) {
497
+ BrotliBitReader* br = &s->br;
498
+ BrotliResult result = BROTLI_RESULT_SUCCESS;
499
+ int use_rle_for_zeros;
500
+
501
+ switch((int)s->sub0_state) {
502
+ case BROTLI_STATE_SUB0_NONE:
503
+ if (!BrotliCheckInputAmount(br, 32)) {
504
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
505
+ }
506
+ *num_htrees = DecodeVarLenUint8(br) + 1;
507
+ s->context_index = 0;
508
+ BROTLI_LOG_UINT(context_map_size);
509
+ BROTLI_LOG_UINT(*num_htrees);
510
+ *context_map_arg = (uint8_t*)malloc((size_t)context_map_size);
511
+ if (*context_map_arg == 0) {
512
+ return BROTLI_FAILURE();
513
+ }
514
+ if (*num_htrees <= 1) {
515
+ memset(*context_map_arg, 0, (size_t)context_map_size);
516
+ return BROTLI_RESULT_SUCCESS;
517
+ }
518
+ use_rle_for_zeros = (int)BrotliReadBits(br, 1);
519
+ if (use_rle_for_zeros) {
520
+ s->max_run_length_prefix = (int)BrotliReadBits(br, 4) + 1;
521
+ } else {
522
+ s->max_run_length_prefix = 0;
523
+ }
524
+ s->sub0_state = BROTLI_STATE_SUB0_CONTEXT_MAP_HUFFMAN;
525
+ /* No break, continue to next state. */
526
+ case BROTLI_STATE_SUB0_CONTEXT_MAP_HUFFMAN:
527
+ result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix,
528
+ s->context_map_table, NULL, s);
529
+ if (result != BROTLI_RESULT_SUCCESS) return result;
530
+ s->sub0_state = BROTLI_STATE_SUB0_CONTEXT_MAPS;
531
+ /* No break, continue to next state. */
532
+ case BROTLI_STATE_SUB0_CONTEXT_MAPS: {
533
+ int context_index = s->context_index;
534
+ int max_run_length_prefix = s->max_run_length_prefix;
535
+ uint8_t* context_map = *context_map_arg;
536
+ int code;
537
+ while (context_index < context_map_size) {
538
+ if (!BrotliCheckInputAmount(br, 32)) {
539
+ s->context_index = context_index;
540
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
541
+ }
542
+ code = ReadSymbol(s->context_map_table, br);
543
+ if (code == 0) {
544
+ context_map[context_index++] = 0;
545
+ } else if (code - max_run_length_prefix <= 0) {
546
+ int reps = (1 << code) + (int)BrotliReadBits(br, code);
547
+ if (context_index + reps > context_map_size) {
548
+ return BROTLI_FAILURE();
549
+ }
550
+ do {
551
+ context_map[context_index++] = 0;
552
+ } while (--reps);
553
+ } else {
554
+ context_map[context_index++] =
555
+ (uint8_t)(code - max_run_length_prefix);
556
+ }
557
+ }
558
+ if (BrotliReadBits(br, 1)) {
559
+ InverseMoveToFrontTransform(context_map, context_map_size, s);
560
+ }
561
+ s->sub0_state = BROTLI_STATE_SUB0_NONE;
562
+ return BROTLI_RESULT_SUCCESS;
563
+ }
564
+ }
565
+
566
+ return BROTLI_FAILURE();
567
+ }
568
+
569
+ static void DecodeBlockType(const int max_block_type,
570
+ const HuffmanCode* trees,
571
+ int tree_type,
572
+ int* ringbuffers,
573
+ BrotliBitReader* br) {
574
+ int* ringbuffer = ringbuffers + tree_type * 2;
575
+ int block_type =
576
+ ReadSymbol(&trees[tree_type * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br) - 2;
577
+ if (block_type == -1) {
578
+ block_type = ringbuffer[1] + 1;
579
+ } else if (block_type == -2) {
580
+ block_type = ringbuffer[0];
581
+ }
582
+ if (block_type >= max_block_type) {
583
+ block_type -= max_block_type;
584
+ }
585
+ ringbuffer[0] = ringbuffer[1];
586
+ ringbuffer[1] = block_type;
587
+ }
588
+
589
+ /* Decodes the block type and updates the state for literal context. */
590
+ static void DecodeBlockTypeWithContext(BrotliState* s,
591
+ BrotliBitReader* br) {
592
+ uint8_t context_mode;
593
+ int context_offset;
594
+ DecodeBlockType(s->num_block_types[0], s->block_type_trees, 0,
595
+ s->block_type_rb, br);
596
+ s->block_length[0] = ReadBlockLength(s->block_len_trees, br);
597
+ context_offset = s->block_type_rb[1] << kLiteralContextBits;
598
+ s->context_map_slice = s->context_map + context_offset;
599
+ s->literal_htree_index = s->context_map_slice[0];
600
+ s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
601
+ context_mode = s->context_modes[s->block_type_rb[1]];
602
+ s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];
603
+ s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];
604
+ }
605
+
606
+ BrotliResult WriteRingBuffer(BrotliOutput output,
607
+ BrotliState* s) {
608
+ int num_written = BrotliWrite(
609
+ output, s->ringbuffer + s->partially_written,
610
+ (size_t)(s->to_write - s->partially_written));
611
+ if (num_written < 0) {
612
+ return BROTLI_FAILURE();
613
+ }
614
+ s->partially_written += num_written;
615
+ if (s->partially_written < s->to_write) {
616
+ return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
617
+ }
618
+ return BROTLI_RESULT_SUCCESS;
619
+ }
620
+
621
+ BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
622
+ int pos,
623
+ BrotliState* s) {
624
+ BrotliResult result;
625
+ int num_read;
626
+ /* State machine */
627
+ for (;;) {
628
+ switch ((int)s->sub0_state) {
629
+ case BROTLI_STATE_SUB0_NONE:
630
+ /* For short lengths copy byte-by-byte */
631
+ if (s->meta_block_remaining_len < 8 ||
632
+ s->meta_block_remaining_len < BrotliGetRemainingBytes(&s->br)) {
633
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_SHORT;
634
+ break;
635
+ }
636
+ /* Copy remaining bytes from s->br.buf_ to ringbuffer. */
637
+ s->nbytes = (int)BrotliGetRemainingBytes(&s->br);
638
+ BrotliCopyBytes(&s->ringbuffer[pos], &s->br, (size_t)s->nbytes);
639
+ pos += s->nbytes;
640
+ s->meta_block_remaining_len -= s->nbytes;
641
+ if (pos >= s->ringbuffer_size) {
642
+ s->to_write = s->ringbuffer_size;
643
+ s->partially_written = 0;
644
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_1;
645
+ break;
646
+ }
647
+ if (pos + s->meta_block_remaining_len >= s->ringbuffer_size) {
648
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_FILL;
649
+ } else {
650
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_COPY;
651
+ }
652
+ break;
653
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_SHORT:
654
+ while (s->meta_block_remaining_len > 0) {
655
+ if (!BrotliCheckInputAmount(&s->br, 32)) {
656
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
657
+ }
658
+ s->ringbuffer[pos++] = (uint8_t)BrotliReadBits(&s->br, 8);
659
+ s->meta_block_remaining_len--;
660
+ }
661
+ if (pos >= s->ringbuffer_size) {
662
+ s->to_write = s->ringbuffer_size;
663
+ s->partially_written = 0;
664
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_2;
665
+ } else {
666
+ s->sub0_state = BROTLI_STATE_SUB0_NONE;
667
+ return BROTLI_RESULT_SUCCESS;
668
+ }
669
+ /* No break, if state is updated, continue to next state */
670
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_1:
671
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_2:
672
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_3:
673
+ result = WriteRingBuffer(output, s);
674
+ if (result != BROTLI_RESULT_SUCCESS) {
675
+ return result;
676
+ }
677
+ pos &= s->ringbuffer_mask;
678
+ s->max_distance = s->max_backward_distance;
679
+ if (s->sub0_state == BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_2) {
680
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_SHORT;
681
+ break;
682
+ }
683
+ if (s->sub0_state == BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_1) {
684
+ s->meta_block_remaining_len -= s->ringbuffer_size;
685
+ /* If we wrote past the logical end of the ringbuffer, copy the tail
686
+ of the ringbuffer to its beginning and flush the ringbuffer to the
687
+ output. */
688
+ memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
689
+ }
690
+ if (pos + s->meta_block_remaining_len >= s->ringbuffer_size) {
691
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_FILL;
692
+ } else {
693
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_COPY;
694
+ break;
695
+ }
696
+ /* No break, continue to next state */
697
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_FILL:
698
+ /* If we have more to copy than the remaining size of the ringbuffer,
699
+ then we first fill the ringbuffer from the input and then flush the
700
+ ringbuffer to the output */
701
+ s->nbytes = s->ringbuffer_size - pos;
702
+ num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
703
+ (size_t)s->nbytes);
704
+ s->meta_block_remaining_len -= num_read;
705
+ if (num_read < s->nbytes) {
706
+ if (num_read < 0) return BROTLI_FAILURE();
707
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
708
+ }
709
+ s->to_write = s->ringbuffer_size;
710
+ s->partially_written = 0;
711
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_3;
712
+ break;
713
+ /* No break, continue to next state */
714
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_COPY:
715
+ /* Copy straight from the input onto the ringbuffer. The ringbuffer will
716
+ be flushed to the output at a later time. */
717
+ num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
718
+ (size_t)s->meta_block_remaining_len);
719
+ s->meta_block_remaining_len -= num_read;
720
+ if (s->meta_block_remaining_len > 0) {
721
+ if (num_read < 0) return BROTLI_FAILURE();
722
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
723
+ }
724
+ s->sub0_state = BROTLI_STATE_SUB0_UNCOMPRESSED_WARMUP;
725
+ /* No break, continue to next state */
726
+ case BROTLI_STATE_SUB0_UNCOMPRESSED_WARMUP:
727
+ if (!BrotliCheckInputAmount(&s->br, 32)) {
728
+ return BROTLI_RESULT_NEEDS_MORE_INPUT;
729
+ }
730
+ BrotliWarmupBitReader(&s->br);
731
+ s->sub0_state = BROTLI_STATE_SUB0_NONE;
732
+ return BROTLI_RESULT_SUCCESS;
733
+ }
734
+ }
735
+ return BROTLI_FAILURE();
736
+ }
737
+
738
+ int BrotliDecompressedSize(size_t encoded_size,
739
+ const uint8_t* encoded_buffer,
740
+ size_t* decoded_size) {
741
+ int i;
742
+ uint64_t val = 0;
743
+ int bit_pos = 0;
744
+ int is_last;
745
+ int is_uncompressed = 0;
746
+ int size_nibbles;
747
+ int meta_block_len = 0;
748
+ if (encoded_size == 0) {
749
+ return 0;
750
+ }
751
+ /* Look at the first 8 bytes, it is enough to decode the length of the first
752
+ meta-block. */
753
+ for (i = 0; (size_t)i < encoded_size && i < 8; ++i) {
754
+ val |= (uint64_t)encoded_buffer[i] << (8 * i);
755
+ }
756
+ /* Skip the window bits. */
757
+ ++bit_pos;
758
+ if (val & 1) {
759
+ bit_pos += 3;
760
+ if (((val >> 1) & 7) == 0) {
761
+ bit_pos += 3;
762
+ }
763
+ }
764
+ /* Decode the ISLAST bit. */
765
+ is_last = (val >> bit_pos) & 1;
766
+ ++bit_pos;
767
+ if (is_last) {
768
+ /* Decode the ISEMPTY bit, if it is set to 1, we are done. */
769
+ if ((val >> bit_pos) & 1) {
770
+ *decoded_size = 0;
771
+ return 1;
772
+ }
773
+ ++bit_pos;
774
+ }
775
+ /* Decode the length of the first meta-block. */
776
+ size_nibbles = (int)((val >> bit_pos) & 3) + 4;
777
+ if (size_nibbles == 7) {
778
+ /* First meta-block contains metadata, this case is not supported here. */
779
+ return 0;
780
+ }
781
+ bit_pos += 2;
782
+ for (i = 0; i < size_nibbles; ++i) {
783
+ meta_block_len |= (int)((val >> bit_pos) & 0xf) << (4 * i);
784
+ bit_pos += 4;
785
+ }
786
+ ++meta_block_len;
787
+ if (is_last) {
788
+ /* If this meta-block is the only one, we are done. */
789
+ *decoded_size = (size_t)meta_block_len;
790
+ return 1;
791
+ }
792
+ is_uncompressed = (val >> bit_pos) & 1;
793
+ ++bit_pos;
794
+ if (is_uncompressed) {
795
+ /* If the first meta-block is uncompressed, we skip it and look at the
796
+ first two bits (ISLAST and ISEMPTY) of the next meta-block, and if
797
+ both are set to 1, we have a stream with an uncompressed meta-block
798
+ followed by an empty one, so the decompressed size is the size of the
799
+ first meta-block. */
800
+ size_t offset = (size_t)((bit_pos + 7) >> 3) + (size_t)meta_block_len;
801
+ if (offset < encoded_size && ((encoded_buffer[offset] & 3) == 3)) {
802
+ *decoded_size = (size_t)meta_block_len;
803
+ return 1;
804
+ }
805
+ }
806
+ /* Could not get the size because the file has multiple meta-blocks */
807
+ return 0;
808
+ }
809
+
810
+ BrotliResult BrotliDecompressBuffer(size_t encoded_size,
811
+ const uint8_t* encoded_buffer,
812
+ size_t* decoded_size,
813
+ uint8_t* decoded_buffer) {
814
+ BrotliMemInput memin;
815
+ BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
816
+ BrotliMemOutput mout;
817
+ BrotliOutput out = BrotliInitMemOutput(decoded_buffer, *decoded_size, &mout);
818
+ BrotliResult success = BrotliDecompress(in, out);
819
+ *decoded_size = mout.pos;
820
+ return success;
821
+ }
822
+
823
+ BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output) {
824
+ BrotliState s;
825
+ BrotliResult result;
826
+ BrotliStateInit(&s);
827
+ result = BrotliDecompressStreaming(input, output, 1, &s);
828
+ if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
829
+ /* Not ok: it didn't finish even though this is a non-streaming function. */
830
+ result = BROTLI_FAILURE();
831
+ }
832
+ BrotliStateCleanup(&s);
833
+ return result;
834
+ }
835
+
836
+ BrotliResult BrotliDecompressBufferStreaming(size_t* available_in,
837
+ const uint8_t** next_in,
838
+ int finish,
839
+ size_t* available_out,
840
+ uint8_t** next_out,
841
+ size_t* total_out,
842
+ BrotliState* s) {
843
+ BrotliMemInput memin;
844
+ BrotliInput in = BrotliInitMemInput(*next_in, *available_in, &memin);
845
+ BrotliMemOutput memout;
846
+ BrotliOutput out = BrotliInitMemOutput(*next_out, *available_out, &memout);
847
+ BrotliResult result = BrotliDecompressStreaming(in, out, finish, s);
848
+ /* The current implementation reads everything, so 0 bytes are available. */
849
+ *next_in += memin.pos;
850
+ *available_in -= memin.pos;
851
+ /* Update the output position to where we write next. */
852
+ *next_out += memout.pos;
853
+ *available_out -= memout.pos;
854
+ *total_out += memout.pos;
855
+ return result;
856
+ }
857
+
858
+ BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
859
+ int finish, BrotliState* s) {
860
+ uint8_t context;
861
+ int pos = s->pos;
862
+ int i = s->loop_counter;
863
+ BrotliResult result = BROTLI_RESULT_SUCCESS;
864
+ BrotliBitReader* br = &s->br;
865
+ int initial_remaining_len;
866
+ int bytes_copied;
867
+ int is_metadata;
868
+ int is_uncompressed;
869
+ uint8_t *copy_src;
870
+ uint8_t *copy_dst;
871
+ /* We need the slack region for the following reasons:
872
+ - doing up to two 16-byte copies for fast backward copying
873
+ - transforms
874
+ - flushing the input s->ringbuffer when decoding uncompressed blocks */
875
+ static const int kRingBufferWriteAheadSlack =
876
+ BROTLI_IMPLICIT_ZEROES + BROTLI_READ_SIZE;
877
+ s->br.input_ = input;
878
+ /* State machine */
879
+ for (;;) {
880
+ if (result != BROTLI_RESULT_SUCCESS) {
881
+ if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
882
+ if (BrotliReadInput(br, finish)) {
883
+ result = BROTLI_RESULT_SUCCESS;
884
+ continue;
885
+ }
886
+ if (finish) {
887
+ BROTLI_LOG(("Unexpected end of input. State: %d\n", s->state));
888
+ result = BROTLI_FAILURE();
889
+ }
890
+ }
891
+ break; /* Fail, or partial data. */
892
+ }
893
+ switch (s->state) {
894
+ case BROTLI_STATE_UNINITED:
895
+ pos = 0;
896
+ BrotliInitBitReader(br, input);
897
+
898
+ s->state = BROTLI_STATE_BITREADER_WARMUP;
899
+ /* No break, continue to next state */
900
+ case BROTLI_STATE_BITREADER_WARMUP:
901
+ if (!BrotliCheckInputAmount(br, 32)) {
902
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
903
+ break;
904
+ }
905
+ BrotliWarmupBitReader(br);
906
+ /* Decode window size. */
907
+ s->window_bits = DecodeWindowBits(br);
908
+ if (s->window_bits == 9) {
909
+ /* Value 9 is reserved for future use. */
910
+ result = BROTLI_FAILURE();
911
+ break;
912
+ }
913
+ /* Allocate the ringbuffer */
914
+ {
915
+ size_t known_size = 0;
916
+ s->ringbuffer_size = 1 << s->window_bits;
917
+
918
+ /* If we know the data size is small, do not allocate more ringbuffer
919
+ size than needed to reduce memory usage. Since this happens after
920
+ the first BrotliCheckInputAmount call, we can read the bitreader
921
+ buffer at position 0.
922
+ We need at least 2 bytes of ring buffer size to get the last two
923
+ bytes for context from there */
924
+ if (BrotliDecompressedSize(BROTLI_READ_SIZE, br->buf_, &known_size)) {
925
+ while (s->ringbuffer_size >= known_size * 2
926
+ && s->ringbuffer_size > 32) {
927
+ s->ringbuffer_size >>= 1;
928
+ }
929
+ }
930
+
931
+ /* But make it fit the custom dictionary if there is one. */
932
+ while (s->ringbuffer_size < s->custom_dict_size) {
933
+ s->ringbuffer_size <<= 1;
934
+ }
935
+
936
+ s->ringbuffer_mask = s->ringbuffer_size - 1;
937
+ s->ringbuffer = (uint8_t*)malloc((size_t)(s->ringbuffer_size +
938
+ kRingBufferWriteAheadSlack +
939
+ kMaxDictionaryWordLength));
940
+ if (!s->ringbuffer) {
941
+ result = BROTLI_FAILURE();
942
+ break;
943
+ }
944
+ s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;
945
+ s->ringbuffer[s->ringbuffer_size - 2] = 0;
946
+ s->ringbuffer[s->ringbuffer_size - 1] = 0;
947
+ if (s->custom_dict) {
948
+ memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
949
+ s->custom_dict, (size_t)s->custom_dict_size);
950
+ }
951
+ }
952
+ s->max_backward_distance = (1 << s->window_bits) - 16;
953
+ s->max_backward_distance_minus_custom_dict_size =
954
+ s->max_backward_distance - s->custom_dict_size;
955
+
956
+ /* Allocate memory for both block_type_trees and block_len_trees. */
957
+ s->block_type_trees = (HuffmanCode*)malloc(
958
+ 6 * BROTLI_HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode));
959
+
960
+ if (s->block_type_trees == NULL) {
961
+ result = BROTLI_FAILURE();
962
+ break;
963
+ }
964
+ s->block_len_trees = s->block_type_trees +
965
+ 3 * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
966
+
967
+ s->state = BROTLI_STATE_METABLOCK_BEGIN;
968
+ /* No break, continue to next state */
969
+ case BROTLI_STATE_METABLOCK_BEGIN:
970
+ if (s->input_end) {
971
+ s->to_write = pos;
972
+ s->partially_written = 0;
973
+ s->state = BROTLI_STATE_DONE;
974
+ break;
975
+ }
976
+ BrotliStateMetablockBegin(s);
977
+ s->state = BROTLI_STATE_METABLOCK_HEADER_1;
978
+ /* No break, continue to next state */
979
+ case BROTLI_STATE_METABLOCK_HEADER_1:
980
+ if (!BrotliCheckInputAmount(br, 32)) {
981
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
982
+ break;
983
+ }
984
+ BROTLI_LOG_UINT(pos);
985
+ if (!DecodeMetaBlockLength(br,
986
+ &s->meta_block_remaining_len,
987
+ &s->input_end,
988
+ &is_metadata,
989
+ &is_uncompressed)) {
990
+ result = BROTLI_FAILURE();
991
+ break;
992
+ }
993
+ BROTLI_LOG_UINT(s->meta_block_remaining_len);
994
+ if (is_metadata) {
995
+ if (!BrotliJumpToByteBoundary(br)) {
996
+ result = BROTLI_FAILURE();
997
+ break;
998
+ }
999
+ s->state = BROTLI_STATE_METADATA;
1000
+ break;
1001
+ }
1002
+ if (s->meta_block_remaining_len == 0) {
1003
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1004
+ break;
1005
+ }
1006
+ if (is_uncompressed) {
1007
+ if (!BrotliJumpToByteBoundary(br)) {
1008
+ result = BROTLI_FAILURE();
1009
+ break;
1010
+ }
1011
+ s->state = BROTLI_STATE_UNCOMPRESSED;
1012
+ break;
1013
+ }
1014
+ i = 0;
1015
+ s->state = BROTLI_STATE_HUFFMAN_CODE_0;
1016
+ break;
1017
+ case BROTLI_STATE_UNCOMPRESSED:
1018
+ initial_remaining_len = s->meta_block_remaining_len;
1019
+ /* pos is given as argument since s->pos is only updated at the end. */
1020
+ result = CopyUncompressedBlockToOutput(output, pos, s);
1021
+ bytes_copied = initial_remaining_len - s->meta_block_remaining_len;
1022
+ pos = (pos + bytes_copied) & s->ringbuffer_mask;
1023
+ if (result != BROTLI_RESULT_SUCCESS) {
1024
+ break;
1025
+ }
1026
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1027
+ break;
1028
+ case BROTLI_STATE_METADATA:
1029
+ for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
1030
+ if (!BrotliCheckInputAmount(br, 32)) {
1031
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1032
+ break;
1033
+ }
1034
+ /* Read one byte and ignore it. */
1035
+ BrotliReadBits(br, 8);
1036
+ }
1037
+ if (result == BROTLI_RESULT_SUCCESS) {
1038
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1039
+ }
1040
+ break;
1041
+ case BROTLI_STATE_HUFFMAN_CODE_0:
1042
+ if (i >= 3) {
1043
+ BROTLI_LOG_UINT(s->num_block_type_rb[0]);
1044
+ BROTLI_LOG_UINT(s->num_block_type_rb[2]);
1045
+ BROTLI_LOG_UINT(s->num_block_type_rb[4]);
1046
+ BROTLI_LOG_UINT(s->block_length[0]);
1047
+ BROTLI_LOG_UINT(s->block_length[1]);
1048
+ BROTLI_LOG_UINT(s->block_length[2]);
1049
+ s->state = BROTLI_STATE_METABLOCK_HEADER_2;
1050
+ break;
1051
+ }
1052
+ s->num_block_types[i] = DecodeVarLenUint8(br) + 1;
1053
+ s->state = BROTLI_STATE_HUFFMAN_CODE_1;
1054
+ /* No break, continue to next state */
1055
+ case BROTLI_STATE_HUFFMAN_CODE_1:
1056
+ if (s->num_block_types[i] >= 2) {
1057
+ result = ReadHuffmanCode(s->num_block_types[i] + 2,
1058
+ &s->block_type_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE],
1059
+ NULL, s);
1060
+ if (result != BROTLI_RESULT_SUCCESS) break;
1061
+ s->state = BROTLI_STATE_HUFFMAN_CODE_2;
1062
+ } else {
1063
+ i++;
1064
+ s->state = BROTLI_STATE_HUFFMAN_CODE_0;
1065
+ break;
1066
+ }
1067
+ /* No break, continue to next state */
1068
+ case BROTLI_STATE_HUFFMAN_CODE_2:
1069
+ result = ReadHuffmanCode(kNumBlockLengthCodes,
1070
+ &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE],
1071
+ NULL, s);
1072
+ if (result != BROTLI_RESULT_SUCCESS) break;
1073
+ s->block_length[i] = ReadBlockLength(
1074
+ &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
1075
+ i++;
1076
+ s->state = BROTLI_STATE_HUFFMAN_CODE_0;
1077
+ break;
1078
+ case BROTLI_STATE_METABLOCK_HEADER_2:
1079
+ /* We need up to 256 * 2 + 6 bits, this fits in 128 bytes. */
1080
+ if (!BrotliCheckInputAmount(br, 128)) {
1081
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1082
+ break;
1083
+ }
1084
+ s->distance_postfix_bits = (int)BrotliReadBits(br, 2);
1085
+ s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
1086
+ ((int)BrotliReadBits(br, 4) << s->distance_postfix_bits);
1087
+ s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
1088
+ s->context_modes = (uint8_t*)malloc((size_t)s->num_block_types[0]);
1089
+ if (s->context_modes == 0) {
1090
+ result = BROTLI_FAILURE();
1091
+ break;
1092
+ }
1093
+ for (i = 0; i < s->num_block_types[0]; ++i) {
1094
+ s->context_modes[i] = (uint8_t)(BrotliReadBits(br, 2) << 1);
1095
+ BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);
1096
+ }
1097
+ BROTLI_LOG_UINT(s->num_direct_distance_codes);
1098
+ BROTLI_LOG_UINT(s->distance_postfix_bits);
1099
+ s->state = BROTLI_STATE_CONTEXT_MAP_1;
1100
+ /* No break, continue to next state */
1101
+ case BROTLI_STATE_CONTEXT_MAP_1:
1102
+ result = DecodeContextMap(s->num_block_types[0] << kLiteralContextBits,
1103
+ &s->num_literal_htrees, &s->context_map, s);
1104
+ if (result != BROTLI_RESULT_SUCCESS) {
1105
+ break;
1106
+ }
1107
+ s->trivial_literal_context = 1;
1108
+ for (i = 0; i < s->num_block_types[0] << kLiteralContextBits; i++) {
1109
+ if (s->context_map[i] != i >> kLiteralContextBits) {
1110
+ s->trivial_literal_context = 0;
1111
+ break;
1112
+ }
1113
+ }
1114
+ s->state = BROTLI_STATE_CONTEXT_MAP_2;
1115
+ /* No break, continue to next state */
1116
+ case BROTLI_STATE_CONTEXT_MAP_2:
1117
+ {
1118
+ int num_dist_htrees;
1119
+ int num_distance_codes =
1120
+ s->num_direct_distance_codes + (48 << s->distance_postfix_bits);
1121
+ result = DecodeContextMap(
1122
+ s->num_block_types[2] << kDistanceContextBits,
1123
+ &num_dist_htrees, &s->dist_context_map, s);
1124
+ if (result != BROTLI_RESULT_SUCCESS) {
1125
+ break;
1126
+ }
1127
+ BrotliHuffmanTreeGroupInit(
1128
+ &s->literal_hgroup, kNumLiteralCodes, s->num_literal_htrees);
1129
+ BrotliHuffmanTreeGroupInit(
1130
+ &s->insert_copy_hgroup, kNumInsertAndCopyCodes,
1131
+ s->num_block_types[1]);
1132
+ BrotliHuffmanTreeGroupInit(
1133
+ &s->distance_hgroup, num_distance_codes, num_dist_htrees);
1134
+ }
1135
+ i = 0;
1136
+ s->state = BROTLI_STATE_TREE_GROUP;
1137
+ /* No break, continue to next state */
1138
+ case BROTLI_STATE_TREE_GROUP:
1139
+ switch (i) {
1140
+ case 0:
1141
+ result = HuffmanTreeGroupDecode(&s->literal_hgroup, s);
1142
+ break;
1143
+ case 1:
1144
+ result = HuffmanTreeGroupDecode(&s->insert_copy_hgroup, s);
1145
+ break;
1146
+ case 2:
1147
+ result = HuffmanTreeGroupDecode(&s->distance_hgroup, s);
1148
+ break;
1149
+ }
1150
+ if (result != BROTLI_RESULT_SUCCESS) break;
1151
+ i++;
1152
+ if (i >= 3) {
1153
+ uint8_t context_mode = s->context_modes[s->block_type_rb[1]];
1154
+ s->context_map_slice = s->context_map;
1155
+ s->dist_context_map_slice = s->dist_context_map;
1156
+ s->context_lookup1 =
1157
+ &kContextLookup[kContextLookupOffsets[context_mode]];
1158
+ s->context_lookup2 =
1159
+ &kContextLookup[kContextLookupOffsets[context_mode + 1]];
1160
+ s->htree_command = s->insert_copy_hgroup.htrees[0];
1161
+ s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
1162
+ s->state = BROTLI_STATE_COMMAND_BEGIN;
1163
+ }
1164
+ break;
1165
+ case BROTLI_STATE_COMMAND_BEGIN:
1166
+ if (s->meta_block_remaining_len <= 0) {
1167
+ /* Next metablock, if any */
1168
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1169
+ break;
1170
+ }
1171
+ /* Decoding of Brotli commands is the inner loop, jumping with goto makes it
1172
+ 3% faster */
1173
+ CommandBegin:
1174
+ if (!BrotliCheckInputAmount(br, 32)) {
1175
+ s->state = BROTLI_STATE_COMMAND_BEGIN;
1176
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1177
+ break;
1178
+ }
1179
+ /* Read the insert/copy length in the command */
1180
+ if (s->block_length[1] == 0) {
1181
+ /* Block switch for insert/copy length */
1182
+ DecodeBlockType(s->num_block_types[1],
1183
+ s->block_type_trees, 1,
1184
+ s->block_type_rb, br);
1185
+ s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
1186
+ s->block_length[1] = ReadBlockLength(
1187
+ &s->block_len_trees[BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
1188
+ }
1189
+ {
1190
+ int cmd_code = ReadSymbol(s->htree_command, br);
1191
+ CmdLutElement v;
1192
+ --s->block_length[1];
1193
+ v = kCmdLut[cmd_code];
1194
+ s->distance_code = v.distance_code;
1195
+ s->distance_context = v.context;
1196
+ s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
1197
+ i = (int)BrotliReadBits(br, v.insert_len_extra_bits) +
1198
+ v.insert_len_offset;
1199
+ s->copy_length = (int)BrotliReadBits(br, v.copy_len_extra_bits) +
1200
+ v.copy_len_offset;
1201
+ }
1202
+ BROTLI_LOG_UINT(i);
1203
+ BROTLI_LOG_UINT(s->copy_length);
1204
+ BROTLI_LOG_UINT(s->distance_code);
1205
+ if (i == 0) {
1206
+ goto postDecodeLiterals;
1207
+ }
1208
+ s->meta_block_remaining_len -= i;
1209
+ /* No break, go to next state */
1210
+ case BROTLI_STATE_COMMAND_INNER:
1211
+ /* Read the literals in the command */
1212
+ if (s->trivial_literal_context) {
1213
+ unsigned bits;
1214
+ unsigned value;
1215
+ PreloadSymbol(s->literal_htree, br, &bits, &value);
1216
+ do {
1217
+ if (!BrotliCheckInputAmount(br, 64)) {
1218
+ s->state = BROTLI_STATE_COMMAND_INNER;
1219
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1220
+ break;
1221
+ }
1222
+ if (PREDICT_FALSE(s->block_length[0] == 0)) {
1223
+ /* Block switch for literals */
1224
+ DecodeBlockTypeWithContext(s, br);
1225
+ PreloadSymbol(s->literal_htree, br, &bits, &value);
1226
+ }
1227
+ s->ringbuffer[pos] =
1228
+ (uint8_t)ReadPreloadedSymbol(s->literal_htree,
1229
+ br, &bits, &value);
1230
+ --s->block_length[0];
1231
+ BROTLI_LOG_UINT(s->literal_htree_index);
1232
+ BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
1233
+ ++pos;
1234
+ if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
1235
+ s->to_write = s->ringbuffer_size;
1236
+ s->partially_written = 0;
1237
+ s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
1238
+ --i;
1239
+ goto innerWrite;
1240
+ }
1241
+ } while (--i != 0);
1242
+ } else {
1243
+ uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask];
1244
+ uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask];
1245
+ do {
1246
+ const HuffmanCode* hc;
1247
+ if (!BrotliCheckInputAmount(br, 64)) {
1248
+ s->state = BROTLI_STATE_COMMAND_INNER;
1249
+ result = BROTLI_RESULT_NEEDS_MORE_INPUT;
1250
+ break;
1251
+ }
1252
+ if (PREDICT_FALSE(s->block_length[0] == 0)) {
1253
+ /* Block switch for literals */
1254
+ DecodeBlockTypeWithContext(s, br);
1255
+ }
1256
+ context = s->context_lookup1[p1] | s->context_lookup2[p2];
1257
+ BROTLI_LOG_UINT(context);
1258
+ hc = s->literal_hgroup.htrees[s->context_map_slice[context]];
1259
+ --s->block_length[0];
1260
+ p2 = p1;
1261
+ p1 = (uint8_t)ReadSymbol(hc, br);
1262
+ s->ringbuffer[pos] = p1;
1263
+ BROTLI_LOG_UINT(s->context_map_slice[context]);
1264
+ BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);
1265
+ ++pos;
1266
+ if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
1267
+ s->to_write = s->ringbuffer_size;
1268
+ s->partially_written = 0;
1269
+ s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
1270
+ --i;
1271
+ goto innerWrite;
1272
+ }
1273
+ } while (--i != 0);
1274
+ }
1275
+ if (result != BROTLI_RESULT_SUCCESS) break;
1276
+ if (s->meta_block_remaining_len <= 0) {
1277
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1278
+ break;
1279
+ }
1280
+ postDecodeLiterals:
1281
+ if (s->distance_code >= 0) {
1282
+ --s->dist_rb_idx;
1283
+ s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
1284
+ goto postReadDistance; /* We already have the implicit distance */
1285
+ }
1286
+ /* Read distance code in the command, unless it was implicitely zero. */
1287
+ BROTLI_DCHECK(s->distance_code < 0);
1288
+ if (s->block_length[2] == 0) {
1289
+ /* Block switch for distance codes */
1290
+ int dist_context_offset;
1291
+ DecodeBlockType(s->num_block_types[2],
1292
+ s->block_type_trees, 2,
1293
+ s->block_type_rb, br);
1294
+ s->block_length[2] = ReadBlockLength(
1295
+ &s->block_len_trees[2 * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
1296
+ dist_context_offset = s->block_type_rb[5] << kDistanceContextBits;
1297
+ s->dist_context_map_slice =
1298
+ s->dist_context_map + dist_context_offset;
1299
+ s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
1300
+ }
1301
+ --s->block_length[2];
1302
+ s->distance_code =
1303
+ ReadSymbol(s->distance_hgroup.htrees[s->dist_htree_index], br);
1304
+ /* Convert the distance code to the actual distance by possibly */
1305
+ /* looking up past distances from the s->ringbuffer. */
1306
+ if ((s->distance_code & ~0xf) == 0) {
1307
+ if (s->distance_code == 0) {
1308
+ --s->dist_rb_idx;
1309
+ s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
1310
+ } else {
1311
+ int distance_code = s->distance_code << 1;
1312
+ /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */
1313
+ /* 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */
1314
+ const uint32_t kDistanceShortCodeIndexOffset = 0xaaafff1b;
1315
+ /* kDistanceShortCodeValueOffset has 2-bit values from LSB: */
1316
+ /* 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3 */
1317
+ const uint32_t kDistanceShortCodeValueOffset = 0xfa5fa500;
1318
+ int v = (s->dist_rb_idx +
1319
+ (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;
1320
+ s->distance_code = s->dist_rb[v];
1321
+ v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3;
1322
+ if ((distance_code & 0x3) != 0) {
1323
+ s->distance_code += v;
1324
+ } else {
1325
+ s->distance_code -= v;
1326
+ if (s->distance_code <= 0) {
1327
+ /* A huge distance will cause a BROTLI_FAILURE() soon. */
1328
+ /* This is a little faster than failing here. */
1329
+ s->distance_code = 0x0fffffff;
1330
+ }
1331
+ }
1332
+ }
1333
+ } else {
1334
+ int distval = s->distance_code - s->num_direct_distance_codes;
1335
+ if (distval >= 0) {
1336
+ int nbits;
1337
+ int postfix;
1338
+ int offset;
1339
+ if (s->distance_postfix_bits == 0) {
1340
+ nbits = (distval >> 1) + 1;
1341
+ offset = ((2 + (distval & 1)) << nbits) - 4;
1342
+ s->distance_code = s->num_direct_distance_codes +
1343
+ offset + (int)BrotliReadBits(br, nbits);
1344
+ } else {
1345
+ postfix = distval & s->distance_postfix_mask;
1346
+ distval >>= s->distance_postfix_bits;
1347
+ nbits = (distval >> 1) + 1;
1348
+ offset = ((2 + (distval & 1)) << nbits) - 4;
1349
+ s->distance_code = s->num_direct_distance_codes +
1350
+ ((offset + (int)BrotliReadBits(br, nbits)) <<
1351
+ s->distance_postfix_bits) + postfix;
1352
+ }
1353
+ }
1354
+ s->distance_code = s->distance_code - NUM_DISTANCE_SHORT_CODES + 1;
1355
+ }
1356
+ postReadDistance:
1357
+ BROTLI_LOG_UINT(s->distance_code);
1358
+ if (s->max_distance != s->max_backward_distance) {
1359
+ if (pos < s->max_backward_distance_minus_custom_dict_size) {
1360
+ s->max_distance = pos + s->custom_dict_size;
1361
+ } else {
1362
+ s->max_distance = s->max_backward_distance;
1363
+ }
1364
+ }
1365
+ i = s->copy_length;
1366
+ /* Apply copy of LZ77 back-reference, or static dictionary reference if
1367
+ the distance is larger than the max LZ77 distance */
1368
+ if (s->distance_code > s->max_distance) {
1369
+ if (i >= kMinDictionaryWordLength &&
1370
+ i <= kMaxDictionaryWordLength) {
1371
+ int offset = kBrotliDictionaryOffsetsByLength[i];
1372
+ int word_id = s->distance_code - s->max_distance - 1;
1373
+ int shift = kBrotliDictionarySizeBitsByLength[i];
1374
+ int mask = (int)BitMask(shift);
1375
+ int word_idx = word_id & mask;
1376
+ int transform_idx = word_id >> shift;
1377
+ offset += word_idx * i;
1378
+ if (transform_idx < kNumTransforms) {
1379
+ const uint8_t* word = &kBrotliDictionary[offset];
1380
+ int len = i;
1381
+ if (transform_idx == 0) {
1382
+ memcpy(&s->ringbuffer[pos], word, (size_t)len);
1383
+ } else {
1384
+ len = TransformDictionaryWord(
1385
+ &s->ringbuffer[pos], word, len, transform_idx);
1386
+ }
1387
+ pos += len;
1388
+ s->meta_block_remaining_len -= len;
1389
+ if (pos >= s->ringbuffer_size) {
1390
+ s->to_write = s->ringbuffer_size;
1391
+ s->partially_written = 0;
1392
+ s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;
1393
+ break;
1394
+ }
1395
+ } else {
1396
+ BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
1397
+ "len: %d bytes left: %d\n",
1398
+ pos, s->distance_code, i,
1399
+ s->meta_block_remaining_len));
1400
+ result = BROTLI_FAILURE();
1401
+ break;
1402
+ }
1403
+ } else {
1404
+ BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
1405
+ "len: %d bytes left: %d\n", pos, s->distance_code, i,
1406
+ s->meta_block_remaining_len));
1407
+ result = BROTLI_FAILURE();
1408
+ break;
1409
+ }
1410
+ } else {
1411
+ const uint8_t *ringbuffer_end_minus_copy_length =
1412
+ s->ringbuffer_end - i;
1413
+ copy_src = &s->ringbuffer[(pos - s->distance_code) &
1414
+ s->ringbuffer_mask];
1415
+ copy_dst = &s->ringbuffer[pos];
1416
+ /* update the recent distances cache */
1417
+ s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
1418
+ ++s->dist_rb_idx;
1419
+ s->meta_block_remaining_len -= i;
1420
+ if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
1421
+ BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
1422
+ "len: %d bytes left: %d\n", pos, s->distance_code, i,
1423
+ s->meta_block_remaining_len));
1424
+ result = BROTLI_FAILURE();
1425
+ break;
1426
+ }
1427
+ /* There is 128+ bytes of slack in the ringbuffer allocation.
1428
+ Also, we have 16 short codes, that make these 16 bytes irrelevant
1429
+ in the ringbuffer. Let's copy over them as a first guess.
1430
+ */
1431
+ memmove16(copy_dst, copy_src);
1432
+ /* Now check if the copy extends over the ringbuffer end,
1433
+ or if the copy overlaps with itself, if yes, do wrap-copy. */
1434
+ if (copy_src < copy_dst) {
1435
+ if (copy_dst >= ringbuffer_end_minus_copy_length) {
1436
+ goto postWrapCopy;
1437
+ }
1438
+ if (copy_src + i > copy_dst) {
1439
+ goto postSelfintersecting;
1440
+ }
1441
+ } else {
1442
+ if (copy_src >= ringbuffer_end_minus_copy_length) {
1443
+ goto postWrapCopy;
1444
+ }
1445
+ if (copy_dst + i > copy_src) {
1446
+ goto postSelfintersecting;
1447
+ }
1448
+ }
1449
+ pos += i;
1450
+ if (i > 16) {
1451
+ if (i > 32) {
1452
+ memcpy(copy_dst + 16, copy_src + 16, (size_t)(i - 16));
1453
+ } else {
1454
+ /* This branch covers about 45% cases.
1455
+ Fixed size short copy allows more compiler optimizations. */
1456
+ memmove16(copy_dst + 16, copy_src + 16);
1457
+ }
1458
+ }
1459
+ }
1460
+ if (s->meta_block_remaining_len <= 0) {
1461
+ /* Next metablock, if any */
1462
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1463
+ break;
1464
+ } else {
1465
+ goto CommandBegin;
1466
+ }
1467
+ postSelfintersecting:
1468
+ while (--i >= 0) {
1469
+ s->ringbuffer[pos] =
1470
+ s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
1471
+ ++pos;
1472
+ }
1473
+ if (s->meta_block_remaining_len <= 0) {
1474
+ /* Next metablock, if any */
1475
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1476
+ break;
1477
+ } else {
1478
+ goto CommandBegin;
1479
+ }
1480
+ postWrapCopy:
1481
+ s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
1482
+ /* No break, go to next state */
1483
+ case BROTLI_STATE_COMMAND_POST_WRAP_COPY:
1484
+ while (--i >= 0) {
1485
+ s->ringbuffer[pos] =
1486
+ s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
1487
+ ++pos;
1488
+ if (pos == s->ringbuffer_size) {
1489
+ s->to_write = s->ringbuffer_size;
1490
+ s->partially_written = 0;
1491
+ s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
1492
+ break;
1493
+ }
1494
+ }
1495
+ if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
1496
+ if (s->meta_block_remaining_len <= 0) {
1497
+ /* Next metablock, if any */
1498
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1499
+ break;
1500
+ } else {
1501
+ goto CommandBegin;
1502
+ }
1503
+ }
1504
+ break;
1505
+ case BROTLI_STATE_COMMAND_INNER_WRITE:
1506
+ case BROTLI_STATE_COMMAND_POST_WRITE_1:
1507
+ case BROTLI_STATE_COMMAND_POST_WRITE_2:
1508
+ innerWrite:
1509
+ result = WriteRingBuffer(output, s);
1510
+ if (result != BROTLI_RESULT_SUCCESS) {
1511
+ break;
1512
+ }
1513
+ pos -= s->ringbuffer_size;
1514
+ s->max_distance = s->max_backward_distance;
1515
+ if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
1516
+ memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
1517
+ if (s->meta_block_remaining_len <= 0) {
1518
+ /* Next metablock, if any */
1519
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1520
+ break;
1521
+ } else {
1522
+ goto CommandBegin;
1523
+ }
1524
+ } else if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_2) {
1525
+ s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
1526
+ } else { /* BROTLI_STATE_COMMAND_INNER_WRITE */
1527
+ if (i == 0) {
1528
+ if (s->meta_block_remaining_len <= 0) {
1529
+ s->state = BROTLI_STATE_METABLOCK_DONE;
1530
+ break;
1531
+ }
1532
+ goto postDecodeLiterals;
1533
+ }
1534
+ s->state = BROTLI_STATE_COMMAND_INNER;
1535
+ }
1536
+ break;
1537
+ case BROTLI_STATE_METABLOCK_DONE:
1538
+ BrotliStateCleanupAfterMetablock(s);
1539
+ s->state = BROTLI_STATE_METABLOCK_BEGIN;
1540
+ break;
1541
+ case BROTLI_STATE_DONE:
1542
+ if (s->ringbuffer != 0) {
1543
+ result = WriteRingBuffer(output, s);
1544
+ if (result != BROTLI_RESULT_SUCCESS) {
1545
+ break;
1546
+ }
1547
+ }
1548
+ if (!BrotliJumpToByteBoundary(br)) {
1549
+ result = BROTLI_FAILURE();
1550
+ }
1551
+ if (BrotliGetRemainingBytes(br) < BROTLI_IMPLICIT_ZEROES) {
1552
+ /* The brotli input stream was too small, does not follow the spec. It
1553
+ might have decompressed fine because of the implicit 128 zeroes added.
1554
+ NOTE: larger input is allowed, smaller not. */
1555
+ result = BROTLI_FAILURE();
1556
+ }
1557
+ return result;
1558
+ }
1559
+ }
1560
+ s->pos = pos;
1561
+ s->loop_counter = i;
1562
+ return result;
1563
+ }
1564
+
1565
+ void BrotliSetCustomDictionary(
1566
+ size_t size, const uint8_t* dict, BrotliState* s) {
1567
+ s->custom_dict = dict;
1568
+ s->custom_dict_size = (int) size;
1569
+ }
1570
+
1571
+ #if defined(__cplusplus) || defined(c_plusplus)
1572
+ } /* extern "C" */
1573
+ #endif