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.
- checksums.yaml +4 -4
- data/ext/brotli/brotli.cc +114 -24
- data/ext/brotli/brotli.h +0 -1
- data/ext/brotli/extconf.rb +30 -23
- data/lib/brotli/version.rb +1 -1
- data/vendor/brotli/LICENSE +1 -1
- data/vendor/brotli/dec/Makefile +1 -1
- data/vendor/brotli/dec/bit_reader.c +3 -3
- data/vendor/brotli/dec/bit_reader.h +25 -27
- data/vendor/brotli/dec/context.h +4 -4
- data/vendor/brotli/dec/decode.c +410 -486
- data/vendor/brotli/dec/decode.h +101 -105
- data/vendor/brotli/dec/dictionary.c +1 -1
- data/vendor/brotli/dec/dictionary.h +7 -8
- data/vendor/brotli/dec/huffman.c +103 -105
- data/vendor/brotli/dec/huffman.h +18 -18
- data/vendor/brotli/dec/port.h +52 -40
- data/vendor/brotli/dec/prefix.h +2 -0
- data/vendor/brotli/dec/state.c +13 -19
- data/vendor/brotli/dec/state.h +25 -39
- data/vendor/brotli/dec/transform.h +38 -44
- data/vendor/brotli/dec/types.h +2 -2
- data/vendor/brotli/enc/Makefile +1 -1
- data/vendor/brotli/enc/backward_references.cc +455 -359
- data/vendor/brotli/enc/backward_references.h +79 -3
- data/vendor/brotli/enc/bit_cost.h +54 -32
- data/vendor/brotli/enc/block_splitter.cc +285 -193
- data/vendor/brotli/enc/block_splitter.h +4 -12
- data/vendor/brotli/enc/brotli_bit_stream.cc +623 -324
- data/vendor/brotli/enc/brotli_bit_stream.h +76 -37
- data/vendor/brotli/enc/cluster.h +161 -120
- data/vendor/brotli/enc/command.h +60 -37
- data/vendor/brotli/enc/compress_fragment.cc +701 -0
- data/vendor/brotli/enc/compress_fragment.h +47 -0
- data/vendor/brotli/enc/compress_fragment_two_pass.cc +524 -0
- data/vendor/brotli/enc/compress_fragment_two_pass.h +40 -0
- data/vendor/brotli/enc/compressor.h +15 -0
- data/vendor/brotli/enc/context.h +1 -1
- data/vendor/brotli/enc/dictionary.h +2 -2
- data/vendor/brotli/enc/encode.cc +819 -286
- data/vendor/brotli/enc/encode.h +38 -15
- data/vendor/brotli/enc/encode_parallel.cc +40 -42
- data/vendor/brotli/enc/entropy_encode.cc +144 -147
- data/vendor/brotli/enc/entropy_encode.h +32 -8
- data/vendor/brotli/enc/entropy_encode_static.h +572 -0
- data/vendor/brotli/enc/fast_log.h +7 -40
- data/vendor/brotli/enc/find_match_length.h +9 -9
- data/vendor/brotli/enc/hash.h +462 -154
- data/vendor/brotli/enc/histogram.cc +6 -6
- data/vendor/brotli/enc/histogram.h +13 -13
- data/vendor/brotli/enc/literal_cost.cc +45 -45
- data/vendor/brotli/enc/metablock.cc +92 -89
- data/vendor/brotli/enc/metablock.h +12 -12
- data/vendor/brotli/enc/port.h +7 -16
- data/vendor/brotli/enc/prefix.h +23 -22
- data/vendor/brotli/enc/ringbuffer.h +75 -29
- data/vendor/brotli/enc/static_dict.cc +56 -48
- data/vendor/brotli/enc/static_dict.h +5 -5
- data/vendor/brotli/enc/streams.cc +1 -1
- data/vendor/brotli/enc/streams.h +5 -5
- data/vendor/brotli/enc/transform.h +40 -35
- data/vendor/brotli/enc/types.h +2 -0
- data/vendor/brotli/enc/utf8_util.cc +3 -2
- data/vendor/brotli/enc/write_bits.h +6 -6
- metadata +9 -5
- data/vendor/brotli/dec/streams.c +0 -102
- data/vendor/brotli/dec/streams.h +0 -95
data/vendor/brotli/dec/decode.c
CHANGED
@@ -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
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
49
|
-
#define HUFFMAN_TABLE_MASK
|
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
|
-
(
|
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
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
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
|
141
|
+
return BROTLI_NEEDS_MORE_INPUT;
|
143
142
|
}
|
144
143
|
if (bits == 0) {
|
145
144
|
*value = 0;
|
146
|
-
return
|
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
|
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
|
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
|
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
|
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
|
180
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
241
|
+
if (!s->is_last_metablock) {
|
243
242
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
244
|
-
return
|
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
|
249
|
+
return BROTLI_SUCCESS;
|
251
250
|
|
252
251
|
case BROTLI_STATE_METABLOCK_HEADER_RESERVED:
|
253
252
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
254
|
-
return
|
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
|
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
|
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
|
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->
|
287
|
-
|
288
|
-
|
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
|
425
|
-
|
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
|
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
|
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
|
-
(
|
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] =
|
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
|
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
|
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
|
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);
|
562
|
-
code_len = p->value;
|
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
|
577
|
+
return BROTLI_SUCCESS;
|
577
578
|
}
|
578
579
|
|
579
|
-
static
|
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
|
613
|
+
return BROTLI_NEEDS_MORE_INPUT;
|
613
614
|
}
|
614
615
|
}
|
615
|
-
return
|
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
|
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
|
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
|
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
|
677
|
-
|
678
|
-
|
679
|
-
|
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
|
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
|
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
|
-
|
715
|
-
if (result !=
|
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
|
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
|
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
|
-
|
744
|
-
if (result !=
|
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
|
-
|
767
|
-
if (result ==
|
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 !=
|
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(
|
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
|
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
|
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
|
884
|
-
|
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
|
-
|
892
|
+
BrotliErrorCode result =
|
893
893
|
ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);
|
894
|
-
if (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
|
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
|
913
|
-
|
914
|
-
|
915
|
-
|
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
|
-
|
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 !=
|
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
|
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
|
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 !=
|
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
|
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
|
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
|
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
|
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
|
-
|
1032
|
-
|
1033
|
-
const HuffmanCode* len_tree = &s->block_len_trees[
|
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
|
-
|
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
|
1135
|
-
size_t* total_out, BrotliState* s) {
|
1136
|
-
size_t pos = (s->pos > s->ringbuffer_size) ?
|
1137
|
-
|
1138
|
-
uint8_t* start =
|
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 +=
|
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
|
1181
|
+
return BROTLI_NEEDS_MORE_OUTPUT;
|
1159
1182
|
}
|
1160
|
-
|
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
|
-
|
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
|
1250
|
+
return BROTLI_SUCCESS;
|
1184
1251
|
}
|
1185
|
-
return
|
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
|
-
|
1193
|
-
available_out, next_out, total_out, s);
|
1194
|
-
if (result !=
|
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
|
-
|
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) !=
|
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
|
-
/*
|
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
|
-
|
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
|
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
|
-
|
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 =
|
1254
|
-
(size_t)s->meta_block_remaining_len);
|
1255
|
-
if (next_block_header != -1) {
|
1256
|
-
if ((next_block_header & 3) == 3) {
|
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
|
-
|
1266
|
-
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
1481
|
-
if (
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
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
|
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
|
-
|
1528
|
+
BrotliErrorCode result = BROTLI_SUCCESS;
|
1495
1529
|
BrotliBitReader* br = &s->br;
|
1496
1530
|
|
1497
|
-
if (!CheckInputAmount(safe, br, 28)
|
1498
|
-
result =
|
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 =
|
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
|
-
|
1531
|
-
|
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 =
|
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] =
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
1678
|
-
pos, s->distance_code, i,
|
1679
|
-
|
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
|
-
|
1685
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
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
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
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
|
1797
|
+
static BROTLI_NOINLINE BrotliErrorCode ProcessCommands(BrotliState* s) {
|
1787
1798
|
return ProcessCommandsInternal(0, s);
|
1788
1799
|
}
|
1789
1800
|
|
1790
|
-
static BROTLI_NOINLINE
|
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
|
-
|
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 =
|
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 !=
|
1953
|
-
if (result ==
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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 =
|
2039
|
-
3 *
|
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 !=
|
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
|
-
|
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 !=
|
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 =
|
2008
|
+
result = BROTLI_NEEDS_MORE_INPUT;
|
2101
2009
|
break;
|
2102
2010
|
}
|
2103
2011
|
}
|
2104
|
-
if (result ==
|
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 !=
|
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 *
|
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 !=
|
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 *
|
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 !=
|
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 *
|
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 =
|
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 =
|
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 =
|
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 !=
|
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
|
-
|
2186
|
-
|
2187
|
-
|
2188
|
-
if (result !=
|
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
|
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 !=
|
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
|
-
|
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
|
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 !=
|
2148
|
+
if (result != BROTLI_SUCCESS) break;
|
2244
2149
|
s->loop_counter++;
|
2245
2150
|
if (s->loop_counter >= 3) {
|
2246
|
-
|
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->
|
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 ==
|
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 !=
|
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
|
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
|
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 !=
|
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)
|
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
|
-
}
|
2261
|
+
} /* extern "C" */
|
2338
2262
|
#endif
|