brotli 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +7 -3
- data/brotli.gemspec +1 -1
- data/ext/brotli/brotli.c +4 -4
- data/ext/brotli/brotli.h +2 -2
- data/ext/brotli/extconf.rb +9 -16
- data/lib/brotli/version.rb +1 -1
- data/vendor/brotli/{common → c/common}/constants.h +11 -1
- data/vendor/brotli/c/common/dictionary.bin +432 -0
- data/vendor/brotli/c/common/dictionary.c +5905 -0
- data/vendor/brotli/c/common/dictionary.h +64 -0
- data/vendor/brotli/c/common/version.h +19 -0
- data/vendor/brotli/{dec → c/dec}/bit_reader.c +2 -2
- data/vendor/brotli/{dec → c/dec}/bit_reader.h +11 -34
- data/vendor/brotli/{dec → c/dec}/context.h +1 -1
- data/vendor/brotli/{dec → c/dec}/decode.c +389 -356
- data/vendor/brotli/{dec → c/dec}/huffman.c +24 -23
- data/vendor/brotli/{dec → c/dec}/huffman.h +1 -1
- data/vendor/brotli/{dec → c/dec}/port.h +19 -10
- data/vendor/brotli/{dec → c/dec}/prefix.h +1 -1
- data/vendor/brotli/{dec → c/dec}/state.c +23 -19
- data/vendor/brotli/{dec → c/dec}/state.h +18 -17
- data/vendor/brotli/{dec → c/dec}/transform.h +2 -2
- data/vendor/brotli/c/enc/backward_references.c +134 -0
- data/vendor/brotli/c/enc/backward_references.h +39 -0
- data/vendor/brotli/{enc/backward_references.c → c/enc/backward_references_hq.c} +144 -232
- data/vendor/brotli/{enc/backward_references.h → c/enc/backward_references_hq.h} +28 -31
- data/vendor/brotli/{enc → c/enc}/backward_references_inc.h +37 -31
- data/vendor/brotli/{enc → c/enc}/bit_cost.c +1 -1
- data/vendor/brotli/{enc → c/enc}/bit_cost.h +1 -1
- data/vendor/brotli/{enc → c/enc}/bit_cost_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/block_encoder_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/block_splitter.c +2 -4
- data/vendor/brotli/{enc → c/enc}/block_splitter.h +1 -1
- data/vendor/brotli/{enc → c/enc}/block_splitter_inc.h +6 -7
- data/vendor/brotli/{enc → c/enc}/brotli_bit_stream.c +22 -26
- data/vendor/brotli/{enc → c/enc}/brotli_bit_stream.h +1 -5
- data/vendor/brotli/{enc → c/enc}/cluster.c +1 -1
- data/vendor/brotli/{enc → c/enc}/cluster.h +1 -1
- data/vendor/brotli/{enc → c/enc}/cluster_inc.h +2 -0
- data/vendor/brotli/{enc → c/enc}/command.h +34 -17
- data/vendor/brotli/{enc → c/enc}/compress_fragment.c +97 -53
- data/vendor/brotli/{enc → c/enc}/compress_fragment.h +5 -2
- data/vendor/brotli/{enc → c/enc}/compress_fragment_two_pass.c +106 -51
- data/vendor/brotli/{enc → c/enc}/compress_fragment_two_pass.h +5 -2
- data/vendor/brotli/{enc → c/enc}/context.h +3 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +1120 -0
- data/vendor/brotli/c/enc/dictionary_hash.h +24 -0
- data/vendor/brotli/{enc → c/enc}/encode.c +442 -240
- data/vendor/brotli/{enc → c/enc}/entropy_encode.c +9 -9
- data/vendor/brotli/{enc → c/enc}/entropy_encode.h +4 -4
- data/vendor/brotli/{enc → c/enc}/entropy_encode_static.h +4 -4
- data/vendor/brotli/{enc → c/enc}/fast_log.h +3 -3
- data/vendor/brotli/{enc → c/enc}/find_match_length.h +8 -8
- data/vendor/brotli/c/enc/hash.h +446 -0
- data/vendor/brotli/{enc → c/enc}/hash_forgetful_chain_inc.h +72 -68
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +266 -0
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +258 -0
- data/vendor/brotli/{enc → c/enc}/hash_longest_match_quickly_inc.h +81 -77
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +326 -0
- data/vendor/brotli/{enc → c/enc}/histogram.c +4 -2
- data/vendor/brotli/{enc → c/enc}/histogram.h +1 -1
- data/vendor/brotli/{enc → c/enc}/histogram_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/literal_cost.c +4 -7
- data/vendor/brotli/{enc → c/enc}/literal_cost.h +2 -2
- data/vendor/brotli/{enc → c/enc}/memory.c +1 -1
- data/vendor/brotli/{enc → c/enc}/memory.h +3 -2
- data/vendor/brotli/{enc → c/enc}/metablock.c +136 -123
- data/vendor/brotli/{enc → c/enc}/metablock.h +2 -12
- data/vendor/brotli/{enc → c/enc}/metablock_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/port.h +49 -33
- data/vendor/brotli/{enc → c/enc}/prefix.h +4 -2
- data/vendor/brotli/{enc → c/enc}/quality.h +47 -17
- data/vendor/brotli/{enc → c/enc}/ringbuffer.h +6 -6
- data/vendor/brotli/{enc → c/enc}/static_dict.c +26 -22
- data/vendor/brotli/{enc → c/enc}/static_dict.h +3 -1
- data/vendor/brotli/c/enc/static_dict_lut.h +5864 -0
- data/vendor/brotli/{enc → c/enc}/utf8_util.c +1 -1
- data/vendor/brotli/{enc → c/enc}/utf8_util.h +2 -2
- data/vendor/brotli/{enc → c/enc}/write_bits.h +3 -3
- data/vendor/brotli/c/include/brotli/decode.h +339 -0
- data/vendor/brotli/c/include/brotli/encode.h +402 -0
- data/vendor/brotli/c/include/brotli/port.h +146 -0
- data/vendor/brotli/c/include/brotli/types.h +90 -0
- metadata +80 -79
- data/vendor/brotli/common/dictionary.c +0 -9474
- data/vendor/brotli/common/dictionary.h +0 -29
- data/vendor/brotli/common/port.h +0 -107
- data/vendor/brotli/common/types.h +0 -58
- data/vendor/brotli/dec/decode.h +0 -188
- data/vendor/brotli/enc/compressor.cc +0 -139
- data/vendor/brotli/enc/compressor.h +0 -161
- data/vendor/brotli/enc/dictionary_hash.h +0 -4121
- data/vendor/brotli/enc/encode.h +0 -221
- data/vendor/brotli/enc/encode_parallel.cc +0 -289
- data/vendor/brotli/enc/encode_parallel.h +0 -27
- data/vendor/brotli/enc/hash.h +0 -717
- data/vendor/brotli/enc/hash_longest_match_inc.h +0 -241
- data/vendor/brotli/enc/static_dict_lut.h +0 -11241
- data/vendor/brotli/enc/streams.cc +0 -114
- data/vendor/brotli/enc/streams.h +0 -121
@@ -0,0 +1,64 @@
|
|
1
|
+
/* Copyright 2013 Google Inc. All Rights Reserved.
|
2
|
+
|
3
|
+
Distributed under MIT license.
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
5
|
+
*/
|
6
|
+
|
7
|
+
/* Collection of static dictionary words. */
|
8
|
+
|
9
|
+
#ifndef BROTLI_COMMON_DICTIONARY_H_
|
10
|
+
#define BROTLI_COMMON_DICTIONARY_H_
|
11
|
+
|
12
|
+
#include <brotli/port.h>
|
13
|
+
#include <brotli/types.h>
|
14
|
+
|
15
|
+
#if defined(__cplusplus) || defined(c_plusplus)
|
16
|
+
extern "C" {
|
17
|
+
#endif
|
18
|
+
|
19
|
+
typedef struct BrotliDictionary {
|
20
|
+
/**
|
21
|
+
* Number of bits to encode index of dictionary word in a bucket.
|
22
|
+
*
|
23
|
+
* Specification: Appendix A. Static Dictionary Data
|
24
|
+
*
|
25
|
+
* Words in a dictionary are bucketed by length.
|
26
|
+
* @c 0 means that there are no words of a given length.
|
27
|
+
* Dictionary consists of words with length of [4..24] bytes.
|
28
|
+
* Values at [0..3] and [25..31] indices should not be addressed.
|
29
|
+
*/
|
30
|
+
const uint8_t size_bits_by_length[32];
|
31
|
+
|
32
|
+
/* assert(offset[i + 1] == offset[i] + (bits[i] ? (i << bits[i]) : 0)) */
|
33
|
+
const uint32_t offsets_by_length[32];
|
34
|
+
|
35
|
+
/* assert(data_size == offsets_by_length[31]) */
|
36
|
+
const size_t data_size;
|
37
|
+
|
38
|
+
/* Data array is not bound, and should obey to size_bits_by_length values.
|
39
|
+
Specified size matches default (RFC 7932) dictionary. Its size is
|
40
|
+
defined by data_size */
|
41
|
+
const uint8_t* data;
|
42
|
+
} BrotliDictionary;
|
43
|
+
|
44
|
+
BROTLI_COMMON_API extern const BrotliDictionary* BrotliGetDictionary(void);
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Sets dictionary data.
|
48
|
+
*
|
49
|
+
* When dictionary data is already set / present, this method is no-op.
|
50
|
+
*
|
51
|
+
* Dictionary data MUST be provided before BrotliGetDictionary is invoked.
|
52
|
+
* This method is used ONLY in multi-client environment (e.g. C + Java),
|
53
|
+
* to reduce storage by sharing single dictionary between implementations.
|
54
|
+
*/
|
55
|
+
BROTLI_COMMON_API void BrotliSetDictionaryData(const uint8_t* data);
|
56
|
+
|
57
|
+
#define BROTLI_MIN_DICTIONARY_WORD_LENGTH 4
|
58
|
+
#define BROTLI_MAX_DICTIONARY_WORD_LENGTH 24
|
59
|
+
|
60
|
+
#if defined(__cplusplus) || defined(c_plusplus)
|
61
|
+
} /* extern "C" */
|
62
|
+
#endif
|
63
|
+
|
64
|
+
#endif /* BROTLI_COMMON_DICTIONARY_H_ */
|
@@ -0,0 +1,19 @@
|
|
1
|
+
/* Copyright 2016 Google Inc. All Rights Reserved.
|
2
|
+
|
3
|
+
Distributed under MIT license.
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
5
|
+
*/
|
6
|
+
|
7
|
+
/* Version definition. */
|
8
|
+
|
9
|
+
#ifndef BROTLI_COMMON_VERSION_H_
|
10
|
+
#define BROTLI_COMMON_VERSION_H_
|
11
|
+
|
12
|
+
/* This macro should only be used when library is compiled together with client.
|
13
|
+
If library is dynamically linked, use BrotliDecoderVersion and
|
14
|
+
BrotliEncoderVersion methods. */
|
15
|
+
|
16
|
+
/* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
|
17
|
+
#define BROTLI_VERSION 0x1000001
|
18
|
+
|
19
|
+
#endif /* BROTLI_COMMON_VERSION_H_ */
|
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
#include "./bit_reader.h"
|
10
10
|
|
11
|
-
#include
|
11
|
+
#include <brotli/types.h>
|
12
12
|
#include "./port.h"
|
13
13
|
|
14
14
|
#if defined(__cplusplus) || defined(c_plusplus)
|
@@ -24,7 +24,7 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|
24
24
|
size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1;
|
25
25
|
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
|
26
26
|
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
|
27
|
-
enough space in accumulator to fix
|
27
|
+
enough space in accumulator to fix alignment. */
|
28
28
|
if (!BROTLI_ALIGNED_READ) {
|
29
29
|
aligned_read_mask = 0;
|
30
30
|
}
|
@@ -11,20 +11,14 @@
|
|
11
11
|
|
12
12
|
#include <string.h> /* memcpy */
|
13
13
|
|
14
|
-
#include
|
14
|
+
#include <brotli/types.h>
|
15
15
|
#include "./port.h"
|
16
16
|
|
17
17
|
#if defined(__cplusplus) || defined(c_plusplus)
|
18
18
|
extern "C" {
|
19
19
|
#endif
|
20
20
|
|
21
|
-
#
|
22
|
-
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 4
|
23
|
-
typedef uint64_t reg_t;
|
24
|
-
#else
|
25
|
-
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 2
|
26
|
-
typedef uint32_t reg_t;
|
27
|
-
#endif
|
21
|
+
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(reg_t) >> 1)
|
28
22
|
|
29
23
|
static const uint32_t kBitMask[33] = { 0x0000,
|
30
24
|
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
@@ -61,7 +55,7 @@ typedef struct {
|
|
61
55
|
size_t avail_in;
|
62
56
|
} BrotliBitReaderState;
|
63
57
|
|
64
|
-
/* Initializes the
|
58
|
+
/* Initializes the BrotliBitReader fields. */
|
65
59
|
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
|
66
60
|
|
67
61
|
/* Ensures that accumulator is not empty. May consume one byte of input.
|
@@ -97,8 +91,8 @@ static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
|
|
97
91
|
return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
|
98
92
|
}
|
99
93
|
|
100
|
-
/* Checks if there is at least num bytes left in the input
|
101
|
-
the bits remaining in br->val_). */
|
94
|
+
/* Checks if there is at least |num| bytes left in the input ring-buffer
|
95
|
+
(excluding the bits remaining in br->val_). */
|
102
96
|
static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
103
97
|
BrotliBitReader* const br, size_t num) {
|
104
98
|
return TO_BROTLI_BOOL(br->avail_in >= num);
|
@@ -163,7 +157,7 @@ static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) {
|
|
163
157
|
/* Guarantees that there are at least n_bits + 1 bits in accumulator.
|
164
158
|
Precondition: accumulator contains at least 1 bit.
|
165
159
|
n_bits should be in the range [1..24] for regular build. For portable
|
166
|
-
non-64-bit little
|
160
|
+
non-64-bit little-endian build only 16 bits are safe to request. */
|
167
161
|
static BROTLI_INLINE void BrotliFillBitWindow(
|
168
162
|
BrotliBitReader* const br, uint32_t n_bits) {
|
169
163
|
#if (BROTLI_64_BITS)
|
@@ -213,7 +207,7 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
|
213
207
|
#endif
|
214
208
|
}
|
215
209
|
|
216
|
-
/*
|
210
|
+
/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
|
217
211
|
more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */
|
218
212
|
static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
|
219
213
|
BrotliFillBitWindow(br, 17);
|
@@ -237,7 +231,7 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
|
237
231
|
}
|
238
232
|
|
239
233
|
/* Returns currently available bits.
|
240
|
-
The number of valid bits could be
|
234
|
+
The number of valid bits could be calculated by BrotliGetAvailableBits. */
|
241
235
|
static BROTLI_INLINE reg_t BrotliGetBitsUnmasked(BrotliBitReader* const br) {
|
242
236
|
return br->val_ >> br->bit_pos_;
|
243
237
|
}
|
@@ -250,7 +244,7 @@ static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked(
|
|
250
244
|
return (uint32_t)BrotliGetBitsUnmasked(br);
|
251
245
|
}
|
252
246
|
|
253
|
-
/* Returns the specified number of bits from br without advancing bit pos. */
|
247
|
+
/* Returns the specified number of bits from |br| without advancing bit pos. */
|
254
248
|
static BROTLI_INLINE uint32_t BrotliGetBits(
|
255
249
|
BrotliBitReader* const br, uint32_t n_bits) {
|
256
250
|
BrotliFillBitWindow(br, n_bits);
|
@@ -289,7 +283,7 @@ static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
|
289
283
|
br->bit_pos_ += unused_bits;
|
290
284
|
}
|
291
285
|
|
292
|
-
/* Reads the specified number of bits from br and advances the bit pos.
|
286
|
+
/* Reads the specified number of bits from |br| and advances the bit pos.
|
293
287
|
Precondition: accumulator MUST contain at least n_bits. */
|
294
288
|
static BROTLI_INLINE void BrotliTakeBits(
|
295
289
|
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
@@ -299,7 +293,7 @@ static BROTLI_INLINE void BrotliTakeBits(
|
|
299
293
|
BrotliDropBits(br, n_bits);
|
300
294
|
}
|
301
295
|
|
302
|
-
/* Reads the specified number of bits from br and advances the bit pos.
|
296
|
+
/* Reads the specified number of bits from |br| and advances the bit pos.
|
303
297
|
Assumes that there is enough input to perform BrotliFillBitWindow. */
|
304
298
|
static BROTLI_INLINE uint32_t BrotliReadBits(
|
305
299
|
BrotliBitReader* const br, uint32_t n_bits) {
|
@@ -343,23 +337,6 @@ static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
|
343
337
|
return TO_BROTLI_BOOL(pad_bits == 0);
|
344
338
|
}
|
345
339
|
|
346
|
-
/* Peeks a byte at specified offset.
|
347
|
-
Precondition: bit reader is parked to a byte boundary.
|
348
|
-
Returns -1 if operation is not feasible. */
|
349
|
-
static BROTLI_INLINE int BrotliPeekByte(BrotliBitReader* br, size_t offset) {
|
350
|
-
uint32_t available_bits = BrotliGetAvailableBits(br);
|
351
|
-
size_t bytes_left = available_bits >> 3;
|
352
|
-
BROTLI_DCHECK((available_bits & 7) == 0);
|
353
|
-
if (offset < bytes_left) {
|
354
|
-
return (BrotliGetBitsUnmasked(br) >> (unsigned)(offset << 3)) & 0xFF;
|
355
|
-
}
|
356
|
-
offset -= bytes_left;
|
357
|
-
if (offset < br->avail_in) {
|
358
|
-
return br->next_in[offset];
|
359
|
-
}
|
360
|
-
return -1;
|
361
|
-
}
|
362
|
-
|
363
340
|
/* Copies remaining input bytes stored in the bit reader to the output. Value
|
364
341
|
num may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
365
342
|
warmed up again after this. */
|
@@ -4,7 +4,7 @@
|
|
4
4
|
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
5
5
|
*/
|
6
6
|
|
7
|
-
#include
|
7
|
+
#include <brotli/decode.h>
|
8
8
|
|
9
9
|
#ifdef __ARM_NEON__
|
10
10
|
#include <arm_neon.h>
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
#include "../common/constants.h"
|
17
17
|
#include "../common/dictionary.h"
|
18
|
+
#include "../common/version.h"
|
18
19
|
#include "./bit_reader.h"
|
19
20
|
#include "./context.h"
|
20
21
|
#include "./huffman.h"
|
@@ -38,6 +39,11 @@ extern "C" {
|
|
38
39
|
#define HUFFMAN_TABLE_BITS 8U
|
39
40
|
#define HUFFMAN_TABLE_MASK 0xff
|
40
41
|
|
42
|
+
/* We need the slack region for the following reasons:
|
43
|
+
- doing up to two 16-byte copies for fast backward copying
|
44
|
+
- inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */
|
45
|
+
static const uint32_t kRingBufferWriteAheadSlack = 42;
|
46
|
+
|
41
47
|
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
|
42
48
|
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
43
49
|
};
|
@@ -51,6 +57,17 @@ static const uint8_t kCodeLengthPrefixValue[16] = {
|
|
51
57
|
0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,
|
52
58
|
};
|
53
59
|
|
60
|
+
BROTLI_BOOL BrotliDecoderSetParameter(
|
61
|
+
BrotliDecoderState* state, BrotliDecoderParameter p, uint32_t value) {
|
62
|
+
switch (p) {
|
63
|
+
case BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:
|
64
|
+
state->canny_ringbuffer_allocation = !!value ? 0 : 1;
|
65
|
+
return BROTLI_TRUE;
|
66
|
+
|
67
|
+
default: return BROTLI_FALSE;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
54
71
|
BrotliDecoderState* BrotliDecoderCreateInstance(
|
55
72
|
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
|
56
73
|
BrotliDecoderState* state = 0;
|
@@ -65,7 +82,6 @@ BrotliDecoderState* BrotliDecoderCreateInstance(
|
|
65
82
|
}
|
66
83
|
BrotliDecoderStateInitWithCustomAllocators(
|
67
84
|
state, alloc_func, free_func, opaque);
|
68
|
-
state->error_code = BROTLI_DECODER_NO_ERROR;
|
69
85
|
return state;
|
70
86
|
}
|
71
87
|
|
@@ -132,7 +148,7 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
|
132
148
|
uint32_t bits;
|
133
149
|
switch (s->substate_decode_uint8) {
|
134
150
|
case BROTLI_STATE_DECODE_UINT8_NONE:
|
135
|
-
if (
|
151
|
+
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
|
136
152
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
137
153
|
}
|
138
154
|
if (bits == 0) {
|
@@ -142,7 +158,7 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
|
142
158
|
/* No break, transit to the next state. */
|
143
159
|
|
144
160
|
case BROTLI_STATE_DECODE_UINT8_SHORT:
|
145
|
-
if (
|
161
|
+
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) {
|
146
162
|
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT;
|
147
163
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
148
164
|
}
|
@@ -156,7 +172,7 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
|
156
172
|
/* No break, transit to the next state. */
|
157
173
|
|
158
174
|
case BROTLI_STATE_DECODE_UINT8_LONG:
|
159
|
-
if (
|
175
|
+
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) {
|
160
176
|
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG;
|
161
177
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
162
178
|
}
|
@@ -181,7 +197,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
181
197
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
182
198
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
183
199
|
}
|
184
|
-
s->is_last_metablock =
|
200
|
+
s->is_last_metablock = bits ? 1 : 0;
|
185
201
|
s->meta_block_remaining_len = 0;
|
186
202
|
s->is_uncompressed = 0;
|
187
203
|
s->is_metadata = 0;
|
@@ -219,7 +235,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
219
235
|
|
220
236
|
case BROTLI_STATE_METABLOCK_HEADER_SIZE:
|
221
237
|
i = s->loop_counter;
|
222
|
-
for (; i < s->size_nibbles; ++i) {
|
238
|
+
for (; i < (int)s->size_nibbles; ++i) {
|
223
239
|
if (!BrotliSafeReadBits(br, 4, &bits)) {
|
224
240
|
s->loop_counter = i;
|
225
241
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -238,7 +254,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
238
254
|
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
239
255
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
240
256
|
}
|
241
|
-
s->is_uncompressed =
|
257
|
+
s->is_uncompressed = bits ? 1 : 0;
|
242
258
|
}
|
243
259
|
++s->meta_block_remaining_len;
|
244
260
|
s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
|
@@ -268,7 +284,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
268
284
|
|
269
285
|
case BROTLI_STATE_METABLOCK_HEADER_METADATA:
|
270
286
|
i = s->loop_counter;
|
271
|
-
for (; i < s->size_nibbles; ++i) {
|
287
|
+
for (; i < (int)s->size_nibbles; ++i) {
|
272
288
|
if (!BrotliSafeReadBits(br, 8, &bits)) {
|
273
289
|
s->loop_counter = i;
|
274
290
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -359,7 +375,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
359
375
|
static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
360
376
|
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
|
361
377
|
uint32_t val;
|
362
|
-
if (
|
378
|
+
if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
|
363
379
|
*result = DecodeSymbol(val, table, br);
|
364
380
|
return BROTLI_TRUE;
|
365
381
|
}
|
@@ -387,7 +403,7 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
|
|
387
403
|
uint32_t* bits,
|
388
404
|
uint32_t* value) {
|
389
405
|
uint32_t result = *value;
|
390
|
-
if (
|
406
|
+
if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
|
391
407
|
uint32_t val = BrotliGet16BitsUnmasked(br);
|
392
408
|
const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
|
393
409
|
uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
|
@@ -424,7 +440,7 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
|
424
440
|
uint32_t num_symbols = s->symbol;
|
425
441
|
while (i <= num_symbols) {
|
426
442
|
uint32_t v;
|
427
|
-
if (
|
443
|
+
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
|
428
444
|
s->sub_loop_counter = i;
|
429
445
|
s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
|
430
446
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
@@ -453,8 +469,8 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
|
453
469
|
/* Process single decoded symbol code length:
|
454
470
|
A) reset the repeat variable
|
455
471
|
B) remember code length (if it is not 0)
|
456
|
-
C) extend
|
457
|
-
D) reduce the
|
472
|
+
C) extend corresponding index-chain
|
473
|
+
D) reduce the Huffman space
|
458
474
|
E) update the histogram
|
459
475
|
*/
|
460
476
|
static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
@@ -478,7 +494,7 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
|
478
494
|
value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new
|
479
495
|
symbol-skip
|
480
496
|
B) Update repeat variable
|
481
|
-
C) Check if operation is feasible (fits
|
497
|
+
C) Check if operation is feasible (fits alphabet)
|
482
498
|
D) For each symbol do the same operations as in ProcessSingleCodeLength
|
483
499
|
|
484
500
|
PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or
|
@@ -583,16 +599,23 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
583
599
|
static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
584
600
|
uint32_t alphabet_size, BrotliDecoderState* s) {
|
585
601
|
BrotliBitReader* br = &s->br;
|
602
|
+
BROTLI_BOOL get_byte = BROTLI_FALSE;
|
586
603
|
while (s->symbol < alphabet_size && s->space > 0) {
|
587
604
|
const HuffmanCode* p = s->table;
|
588
605
|
uint32_t code_len;
|
606
|
+
uint32_t available_bits;
|
589
607
|
uint32_t bits = 0;
|
590
|
-
|
608
|
+
if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
609
|
+
get_byte = BROTLI_FALSE;
|
610
|
+
available_bits = BrotliGetAvailableBits(br);
|
591
611
|
if (available_bits != 0) {
|
592
612
|
bits = (uint32_t)BrotliGetBitsUnmasked(br);
|
593
613
|
}
|
594
614
|
p += bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
|
595
|
-
if (p->bits > available_bits)
|
615
|
+
if (p->bits > available_bits) {
|
616
|
+
get_byte = BROTLI_TRUE;
|
617
|
+
continue;
|
618
|
+
}
|
596
619
|
code_len = p->value; /* code_len == 0..17 */
|
597
620
|
if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
598
621
|
BrotliDropBits(br, p->bits);
|
@@ -602,19 +625,16 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
602
625
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
603
626
|
uint32_t extra_bits = code_len - 14U;
|
604
627
|
uint32_t repeat_delta = (bits >> p->bits) & BitMask(extra_bits);
|
605
|
-
if (available_bits < p->bits + extra_bits)
|
628
|
+
if (available_bits < p->bits + extra_bits) {
|
629
|
+
get_byte = BROTLI_TRUE;
|
630
|
+
continue;
|
631
|
+
}
|
606
632
|
BrotliDropBits(br, p->bits + extra_bits);
|
607
633
|
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
608
634
|
&s->symbol, &s->repeat, &s->space, &s->prev_code_len,
|
609
635
|
&s->repeat_code_len, s->symbol_lists, s->code_length_histo,
|
610
636
|
s->next_symbol);
|
611
637
|
}
|
612
|
-
continue;
|
613
|
-
|
614
|
-
pullMoreInput:
|
615
|
-
if (!BrotliPullByte(br)) {
|
616
|
-
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
617
|
-
}
|
618
638
|
}
|
619
639
|
return BROTLI_DECODER_SUCCESS;
|
620
640
|
}
|
@@ -630,7 +650,7 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
|
630
650
|
const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
|
631
651
|
uint32_t ix;
|
632
652
|
uint32_t v;
|
633
|
-
if (
|
653
|
+
if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
|
634
654
|
uint32_t available_bits = BrotliGetAvailableBits(br);
|
635
655
|
if (available_bits != 0) {
|
636
656
|
ix = BrotliGetBitsUnmasked(br) & 0xF;
|
@@ -685,113 +705,115 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
|
|
685
705
|
/* Unnecessary masking, but might be good for safety. */
|
686
706
|
alphabet_size &= 0x3ff;
|
687
707
|
/* State machine */
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
s->
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
+
for (;;) {
|
709
|
+
switch (s->substate_huffman) {
|
710
|
+
case BROTLI_STATE_HUFFMAN_NONE:
|
711
|
+
if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {
|
712
|
+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
713
|
+
}
|
714
|
+
BROTLI_LOG_UINT(s->sub_loop_counter);
|
715
|
+
/* The value is used as follows:
|
716
|
+
1 for simple code;
|
717
|
+
0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
|
718
|
+
if (s->sub_loop_counter != 1) {
|
719
|
+
s->space = 32;
|
720
|
+
s->repeat = 0; /* num_codes */
|
721
|
+
memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) *
|
722
|
+
(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));
|
723
|
+
memset(&s->code_length_code_lengths[0], 0,
|
724
|
+
sizeof(s->code_length_code_lengths));
|
725
|
+
s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
|
726
|
+
continue;
|
727
|
+
}
|
728
|
+
/* No break, transit to the next state. */
|
708
729
|
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
714
|
-
}
|
715
|
-
s->sub_loop_counter = 0;
|
716
|
-
/* No break, transit to the next state. */
|
717
|
-
case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
|
718
|
-
BrotliDecoderErrorCode result =
|
719
|
-
ReadSimpleHuffmanSymbols(alphabet_size, s);
|
720
|
-
if (result != BROTLI_DECODER_SUCCESS) {
|
721
|
-
return result;
|
722
|
-
}
|
723
|
-
/* No break, transit to the next state. */
|
724
|
-
}
|
725
|
-
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
|
726
|
-
uint32_t table_size;
|
727
|
-
if (s->symbol == 3) {
|
728
|
-
uint32_t bits;
|
729
|
-
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
730
|
-
s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
|
730
|
+
case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:
|
731
|
+
/* Read symbols, codes & code lengths directly. */
|
732
|
+
if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */
|
733
|
+
s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
|
731
734
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
732
735
|
}
|
733
|
-
s->
|
736
|
+
s->sub_loop_counter = 0;
|
737
|
+
/* No break, transit to the next state. */
|
738
|
+
case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
|
739
|
+
BrotliDecoderErrorCode result =
|
740
|
+
ReadSimpleHuffmanSymbols(alphabet_size, s);
|
741
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
742
|
+
return result;
|
743
|
+
}
|
744
|
+
/* No break, transit to the next state. */
|
734
745
|
}
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
746
|
+
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
|
747
|
+
uint32_t table_size;
|
748
|
+
if (s->symbol == 3) {
|
749
|
+
uint32_t bits;
|
750
|
+
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
751
|
+
s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
|
752
|
+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
753
|
+
}
|
754
|
+
s->symbol += bits;
|
755
|
+
}
|
756
|
+
BROTLI_LOG_UINT(s->symbol);
|
757
|
+
table_size = BrotliBuildSimpleHuffmanTable(
|
758
|
+
table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol);
|
759
|
+
if (opt_table_size) {
|
760
|
+
*opt_table_size = table_size;
|
761
|
+
}
|
762
|
+
s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
763
|
+
return BROTLI_DECODER_SUCCESS;
|
740
764
|
}
|
741
|
-
s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
742
|
-
return BROTLI_DECODER_SUCCESS;
|
743
|
-
}
|
744
765
|
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
766
|
+
/* Decode Huffman-coded code lengths. */
|
767
|
+
case BROTLI_STATE_HUFFMAN_COMPLEX: {
|
768
|
+
uint32_t i;
|
769
|
+
BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);
|
770
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
771
|
+
return result;
|
772
|
+
}
|
773
|
+
BrotliBuildCodeLengthsHuffmanTable(s->table,
|
774
|
+
s->code_length_code_lengths,
|
775
|
+
s->code_length_histo);
|
776
|
+
memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));
|
777
|
+
for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {
|
778
|
+
s->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
|
779
|
+
s->symbol_lists[s->next_symbol[i]] = 0xFFFF;
|
780
|
+
}
|
760
781
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
}
|
769
|
-
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
|
770
|
-
uint32_t table_size;
|
771
|
-
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(alphabet_size, s);
|
772
|
-
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
773
|
-
result = SafeReadSymbolCodeLengths(alphabet_size, s);
|
774
|
-
}
|
775
|
-
if (result != BROTLI_DECODER_SUCCESS) {
|
776
|
-
return result;
|
782
|
+
s->symbol = 0;
|
783
|
+
s->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;
|
784
|
+
s->repeat = 0;
|
785
|
+
s->repeat_code_len = 0;
|
786
|
+
s->space = 32768;
|
787
|
+
s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
|
788
|
+
/* No break, transit to the next state. */
|
777
789
|
}
|
790
|
+
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
|
791
|
+
uint32_t table_size;
|
792
|
+
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(alphabet_size, s);
|
793
|
+
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
794
|
+
result = SafeReadSymbolCodeLengths(alphabet_size, s);
|
795
|
+
}
|
796
|
+
if (result != BROTLI_DECODER_SUCCESS) {
|
797
|
+
return result;
|
798
|
+
}
|
778
799
|
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
800
|
+
if (s->space != 0) {
|
801
|
+
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
|
802
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
|
803
|
+
}
|
804
|
+
table_size = BrotliBuildHuffmanTable(
|
805
|
+
table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
|
806
|
+
if (opt_table_size) {
|
807
|
+
*opt_table_size = table_size;
|
808
|
+
}
|
809
|
+
s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
810
|
+
return BROTLI_DECODER_SUCCESS;
|
787
811
|
}
|
788
|
-
s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
789
|
-
return BROTLI_DECODER_SUCCESS;
|
790
|
-
}
|
791
812
|
|
792
|
-
|
793
|
-
|
794
|
-
|
813
|
+
default:
|
814
|
+
return
|
815
|
+
BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);
|
816
|
+
}
|
795
817
|
}
|
796
818
|
}
|
797
819
|
|
@@ -850,37 +872,38 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
|
850
872
|
static BROTLI_NOINLINE void InverseMoveToFrontTransform(
|
851
873
|
uint8_t* v, uint32_t v_len, BrotliDecoderState* state) {
|
852
874
|
/* Reinitialize elements that could have been changed. */
|
853
|
-
uint32_t i =
|
875
|
+
uint32_t i = 1;
|
854
876
|
uint32_t upper_bound = state->mtf_upper_bound;
|
855
|
-
|
877
|
+
uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */
|
878
|
+
uint8_t* mtf_u8 = (uint8_t*)mtf;
|
856
879
|
/* Load endian-aware constant. */
|
857
880
|
const uint8_t b0123[4] = {0, 1, 2, 3};
|
858
881
|
uint32_t pattern;
|
859
882
|
memcpy(&pattern, &b0123, 4);
|
860
883
|
|
861
884
|
/* Initialize list using 4 consequent values pattern. */
|
862
|
-
|
885
|
+
mtf[0] = pattern;
|
863
886
|
do {
|
864
887
|
pattern += 0x04040404; /* Advance all 4 values by 4. */
|
865
|
-
|
866
|
-
i
|
888
|
+
mtf[i] = pattern;
|
889
|
+
i++;
|
867
890
|
} while (i <= upper_bound);
|
868
891
|
|
869
892
|
/* Transform the input. */
|
870
893
|
upper_bound = 0;
|
871
894
|
for (i = 0; i < v_len; ++i) {
|
872
895
|
int index = v[i];
|
873
|
-
uint8_t value =
|
896
|
+
uint8_t value = mtf_u8[index];
|
874
897
|
upper_bound |= v[i];
|
875
898
|
v[i] = value;
|
876
|
-
|
899
|
+
mtf_u8[-1] = value;
|
877
900
|
do {
|
878
901
|
index--;
|
879
|
-
|
902
|
+
mtf_u8[index + 1] = mtf_u8[index];
|
880
903
|
} while (index >= 0);
|
881
904
|
}
|
882
905
|
/* Remember amount of elements to be reinitialized. */
|
883
|
-
state->mtf_upper_bound = upper_bound;
|
906
|
+
state->mtf_upper_bound = upper_bound >> 2;
|
884
907
|
}
|
885
908
|
|
886
909
|
/* Decodes a series of Huffman table using ReadHuffmanCode function. */
|
@@ -947,7 +970,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
947
970
|
if (!BrotliSafeGetBits(br, 5, &bits)) {
|
948
971
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
949
972
|
}
|
950
|
-
if ((bits & 1) != 0) { /* Use RLE for
|
973
|
+
if ((bits & 1) != 0) { /* Use RLE for zeros. */
|
951
974
|
s->max_run_length_prefix = (bits >> 1) + 1;
|
952
975
|
BrotliDropBits(br, 5);
|
953
976
|
} else {
|
@@ -970,27 +993,29 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
|
970
993
|
uint32_t max_run_length_prefix = s->max_run_length_prefix;
|
971
994
|
uint8_t* context_map = *context_map_arg;
|
972
995
|
uint32_t code = s->code;
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
BROTLI_LOG_UINT(code);
|
996
|
+
BROTLI_BOOL skip_preamble = (code != 0xFFFF);
|
997
|
+
while (context_index < context_map_size || skip_preamble) {
|
998
|
+
if (!skip_preamble) {
|
999
|
+
if (!SafeReadSymbol(s->context_map_table, br, &code)) {
|
1000
|
+
s->code = 0xFFFF;
|
1001
|
+
s->context_index = context_index;
|
1002
|
+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1003
|
+
}
|
1004
|
+
BROTLI_LOG_UINT(code);
|
983
1005
|
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
1006
|
+
if (code == 0) {
|
1007
|
+
context_map[context_index++] = 0;
|
1008
|
+
continue;
|
1009
|
+
}
|
1010
|
+
if (code > max_run_length_prefix) {
|
1011
|
+
context_map[context_index++] =
|
1012
|
+
(uint8_t)(code - max_run_length_prefix);
|
1013
|
+
continue;
|
1014
|
+
}
|
1015
|
+
} else {
|
1016
|
+
skip_preamble = BROTLI_FALSE;
|
992
1017
|
}
|
993
|
-
|
1018
|
+
/* RLE sub-stage. */
|
994
1019
|
{
|
995
1020
|
uint32_t reps;
|
996
1021
|
if (!BrotliSafeReadBits(br, code, &reps)) {
|
@@ -1029,7 +1054,7 @@ rleCode:
|
|
1029
1054
|
}
|
1030
1055
|
}
|
1031
1056
|
|
1032
|
-
/* Decodes a command or literal and updates block type
|
1057
|
+
/* Decodes a command or literal and updates block type ring-buffer.
|
1033
1058
|
Reads 3..54 bits. */
|
1034
1059
|
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
|
1035
1060
|
int safe, BrotliDecoderState* s, int tree_type) {
|
@@ -1172,9 +1197,13 @@ static size_t UnwrittenBytes(const BrotliDecoderState* s, BROTLI_BOOL wrap) {
|
|
1172
1197
|
return partial_pos_rb - s->partial_pos_out;
|
1173
1198
|
}
|
1174
1199
|
|
1200
|
+
/* Dumps output.
|
1201
|
+
Returns BROTLI_DECODER_NEEDS_MORE_OUTPUT only if there is more output to push
|
1202
|
+
and either ring-buffer is as big as window size, or |force| is true.
|
1203
|
+
*/
|
1175
1204
|
static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer(
|
1176
1205
|
BrotliDecoderState* s, size_t* available_out, uint8_t** next_out,
|
1177
|
-
size_t* total_out) {
|
1206
|
+
size_t* total_out, BROTLI_BOOL force) {
|
1178
1207
|
uint8_t* start =
|
1179
1208
|
s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
|
1180
1209
|
size_t to_write = UnwrittenBytes(s, BROTLI_TRUE);
|
@@ -1185,56 +1214,79 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer(
|
|
1185
1214
|
if (s->meta_block_remaining_len < 0) {
|
1186
1215
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1);
|
1187
1216
|
}
|
1188
|
-
|
1189
|
-
|
1217
|
+
if (next_out && !*next_out) {
|
1218
|
+
*next_out = start;
|
1219
|
+
} else {
|
1220
|
+
if (next_out) {
|
1221
|
+
memcpy(*next_out, start, num_written);
|
1222
|
+
*next_out += num_written;
|
1223
|
+
}
|
1224
|
+
}
|
1190
1225
|
*available_out -= num_written;
|
1191
1226
|
BROTLI_LOG_UINT(to_write);
|
1192
1227
|
BROTLI_LOG_UINT(num_written);
|
1193
1228
|
s->partial_pos_out += num_written;
|
1194
|
-
if (total_out)
|
1229
|
+
if (total_out) {
|
1230
|
+
*total_out = s->partial_pos_out;
|
1231
|
+
}
|
1195
1232
|
if (num_written < to_write) {
|
1196
|
-
|
1233
|
+
if (s->ringbuffer_size == (1 << s->window_bits) || force) {
|
1234
|
+
return BROTLI_DECODER_NEEDS_MORE_OUTPUT;
|
1235
|
+
} else {
|
1236
|
+
return BROTLI_DECODER_SUCCESS;
|
1237
|
+
}
|
1197
1238
|
}
|
1198
|
-
|
1199
|
-
if (s->
|
1239
|
+
/* Wrap ring buffer only if it has reached its maximal size. */
|
1240
|
+
if (s->ringbuffer_size == (1 << s->window_bits) &&
|
1241
|
+
s->pos >= s->ringbuffer_size) {
|
1200
1242
|
s->pos -= s->ringbuffer_size;
|
1201
1243
|
s->rb_roundtrips++;
|
1244
|
+
s->should_wrap_ringbuffer = (size_t)s->pos != 0 ? 1 : 0;
|
1202
1245
|
}
|
1203
1246
|
return BROTLI_DECODER_SUCCESS;
|
1204
1247
|
}
|
1205
1248
|
|
1206
|
-
|
1249
|
+
static void BROTLI_NOINLINE WrapRingBuffer(BrotliDecoderState* s) {
|
1250
|
+
if (s->should_wrap_ringbuffer) {
|
1251
|
+
memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
|
1252
|
+
s->should_wrap_ringbuffer = 0;
|
1253
|
+
}
|
1254
|
+
}
|
1255
|
+
|
1256
|
+
/* Allocates ring-buffer.
|
1207
1257
|
|
1208
|
-
|
1209
|
-
|
1258
|
+
s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before
|
1259
|
+
this function is called.
|
1210
1260
|
|
1211
|
-
Last two bytes of
|
1261
|
+
Last two bytes of ring-buffer are initialized to 0, so context calculation
|
1212
1262
|
could be done uniformly for the first two and all other positions.
|
1213
|
-
|
1214
|
-
Custom dictionary, if any, is copied to the end of ringbuffer.
|
1215
1263
|
*/
|
1216
|
-
static BROTLI_BOOL BROTLI_NOINLINE
|
1264
|
+
static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer(
|
1217
1265
|
BrotliDecoderState* s) {
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1266
|
+
uint8_t* old_ringbuffer = s->ringbuffer;
|
1267
|
+
if (s->ringbuffer_size == s->new_ringbuffer_size) {
|
1268
|
+
return BROTLI_TRUE;
|
1269
|
+
}
|
1270
|
+
|
1271
|
+
s->ringbuffer = (uint8_t*)BROTLI_ALLOC(s, (size_t)(s->new_ringbuffer_size) +
|
1272
|
+
kRingBufferWriteAheadSlack);
|
1224
1273
|
if (s->ringbuffer == 0) {
|
1274
|
+
/* Restore previous value. */
|
1275
|
+
s->ringbuffer = old_ringbuffer;
|
1225
1276
|
return BROTLI_FALSE;
|
1226
1277
|
}
|
1278
|
+
s->ringbuffer[s->new_ringbuffer_size - 2] = 0;
|
1279
|
+
s->ringbuffer[s->new_ringbuffer_size - 1] = 0;
|
1227
1280
|
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
s->ringbuffer[s->ringbuffer_size - 1] = 0;
|
1232
|
-
|
1233
|
-
if (s->custom_dict) {
|
1234
|
-
memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
|
1235
|
-
s->custom_dict, (size_t)s->custom_dict_size);
|
1281
|
+
if (!!old_ringbuffer) {
|
1282
|
+
memcpy(s->ringbuffer, old_ringbuffer, (size_t)s->pos);
|
1283
|
+
BROTLI_FREE(s, old_ringbuffer);
|
1236
1284
|
}
|
1237
1285
|
|
1286
|
+
s->ringbuffer_size = s->new_ringbuffer_size;
|
1287
|
+
s->ringbuffer_mask = s->new_ringbuffer_size - 1;
|
1288
|
+
s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;
|
1289
|
+
|
1238
1290
|
return BROTLI_TRUE;
|
1239
1291
|
}
|
1240
1292
|
|
@@ -1242,7 +1294,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|
1242
1294
|
size_t* available_out, uint8_t** next_out, size_t* total_out,
|
1243
1295
|
BrotliDecoderState* s) {
|
1244
1296
|
/* TODO: avoid allocation for single uncompressed block. */
|
1245
|
-
if (!
|
1297
|
+
if (!BrotliEnsureRingBuffer(s)) {
|
1246
1298
|
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1);
|
1247
1299
|
}
|
1248
1300
|
|
@@ -1257,11 +1309,11 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|
1257
1309
|
if (s->pos + nbytes > s->ringbuffer_size) {
|
1258
1310
|
nbytes = s->ringbuffer_size - s->pos;
|
1259
1311
|
}
|
1260
|
-
/* Copy remaining bytes from s->br.buf_ to
|
1312
|
+
/* Copy remaining bytes from s->br.buf_ to ring-buffer. */
|
1261
1313
|
BrotliCopyBytes(&s->ringbuffer[s->pos], &s->br, (size_t)nbytes);
|
1262
1314
|
s->pos += nbytes;
|
1263
1315
|
s->meta_block_remaining_len -= nbytes;
|
1264
|
-
if (s->pos < s->
|
1316
|
+
if (s->pos < 1 << s->window_bits) {
|
1265
1317
|
if (s->meta_block_remaining_len == 0) {
|
1266
1318
|
return BROTLI_DECODER_SUCCESS;
|
1267
1319
|
}
|
@@ -1271,12 +1323,15 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|
1271
1323
|
/* No break, continue to next state */
|
1272
1324
|
}
|
1273
1325
|
case BROTLI_STATE_UNCOMPRESSED_WRITE: {
|
1274
|
-
BrotliDecoderErrorCode result
|
1275
|
-
|
1326
|
+
BrotliDecoderErrorCode result;
|
1327
|
+
result = WriteRingBuffer(
|
1328
|
+
s, available_out, next_out, total_out, BROTLI_FALSE);
|
1276
1329
|
if (result != BROTLI_DECODER_SUCCESS) {
|
1277
1330
|
return result;
|
1278
1331
|
}
|
1279
|
-
s->
|
1332
|
+
if (s->ringbuffer_size == 1 << s->window_bits) {
|
1333
|
+
s->max_distance = s->max_backward_distance;
|
1334
|
+
}
|
1280
1335
|
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
|
1281
1336
|
break;
|
1282
1337
|
}
|
@@ -1285,76 +1340,50 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|
1285
1340
|
BROTLI_DCHECK(0); /* Unreachable */
|
1286
1341
|
}
|
1287
1342
|
|
1288
|
-
BROTLI_BOOL BrotliDecompressedSize(size_t encoded_size,
|
1289
|
-
const uint8_t* encoded_buffer,
|
1290
|
-
size_t* decoded_size) {
|
1291
|
-
size_t total_size = 0;
|
1292
|
-
BrotliDecoderState s;
|
1293
|
-
BrotliBitReader* br;
|
1294
|
-
BrotliDecoderStateInit(&s);
|
1295
|
-
br = &s.br;
|
1296
|
-
*decoded_size = 0;
|
1297
|
-
br->next_in = encoded_buffer;
|
1298
|
-
br->avail_in = encoded_size;
|
1299
|
-
if (!BrotliWarmupBitReader(br)) return BROTLI_FALSE;
|
1300
|
-
DecodeWindowBits(br);
|
1301
|
-
while (1) {
|
1302
|
-
size_t block_size;
|
1303
|
-
if (DecodeMetaBlockLength(&s, br) != BROTLI_DECODER_SUCCESS) {
|
1304
|
-
return BROTLI_FALSE;
|
1305
|
-
}
|
1306
|
-
block_size = (size_t)s.meta_block_remaining_len;
|
1307
|
-
if (!s.is_metadata) {
|
1308
|
-
if ((block_size + total_size) < total_size) return BROTLI_FALSE;
|
1309
|
-
total_size += block_size;
|
1310
|
-
}
|
1311
|
-
if (s.is_last_metablock) {
|
1312
|
-
*decoded_size = total_size;
|
1313
|
-
return BROTLI_TRUE;
|
1314
|
-
}
|
1315
|
-
if (!s.is_uncompressed && !s.is_metadata) return BROTLI_FALSE;
|
1316
|
-
if (!BrotliJumpToByteBoundary(br)) return BROTLI_FALSE;
|
1317
|
-
BrotliBitReaderUnload(br);
|
1318
|
-
if (br->avail_in < block_size) return BROTLI_FALSE;
|
1319
|
-
br->avail_in -= block_size;
|
1320
|
-
br->next_in += block_size;
|
1321
|
-
if (!BrotliWarmupBitReader(br)) return BROTLI_FALSE;
|
1322
|
-
}
|
1323
|
-
}
|
1324
|
-
|
1325
1343
|
/* Calculates the smallest feasible ring buffer.
|
1326
1344
|
|
1327
|
-
If we know the data size is small, do not allocate more
|
1345
|
+
If we know the data size is small, do not allocate more ring buffer
|
1328
1346
|
size than needed to reduce memory usage.
|
1329
1347
|
|
1330
1348
|
When this method is called, metablock size and flags MUST be decoded.
|
1331
1349
|
*/
|
1332
1350
|
static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(
|
1333
|
-
BrotliDecoderState* s
|
1334
|
-
BROTLI_BOOL is_last = TO_BROTLI_BOOL(s->is_last_metablock);
|
1351
|
+
BrotliDecoderState* s) {
|
1335
1352
|
int window_size = 1 << s->window_bits;
|
1336
|
-
|
1337
|
-
|
1338
|
-
if (s->is_uncompressed) {
|
1339
|
-
int next_block_header =
|
1340
|
-
BrotliPeekByte(br, (size_t)s->meta_block_remaining_len);
|
1341
|
-
if (next_block_header != -1) { /* Peek succeeded */
|
1342
|
-
if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */
|
1343
|
-
is_last = BROTLI_TRUE;
|
1344
|
-
}
|
1345
|
-
}
|
1346
|
-
}
|
1347
|
-
|
1353
|
+
int new_ringbuffer_size = window_size;
|
1348
1354
|
/* We need at least 2 bytes of ring buffer size to get the last two
|
1349
1355
|
bytes for context from there */
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1356
|
+
int min_size = s->ringbuffer_size ? s->ringbuffer_size : 1024;
|
1357
|
+
int output_size;
|
1358
|
+
|
1359
|
+
/* If maximum is already reached, no further extension is retired. */
|
1360
|
+
if (s->ringbuffer_size == window_size) {
|
1361
|
+
return;
|
1362
|
+
}
|
1363
|
+
|
1364
|
+
/* Metadata blocks does not touch ring buffer. */
|
1365
|
+
if (s->is_metadata) {
|
1366
|
+
return;
|
1367
|
+
}
|
1368
|
+
|
1369
|
+
if (!s->ringbuffer) {
|
1370
|
+
output_size = 0;
|
1371
|
+
} else {
|
1372
|
+
output_size = s->pos;
|
1373
|
+
}
|
1374
|
+
output_size += s->meta_block_remaining_len;
|
1375
|
+
min_size = min_size < output_size ? output_size : min_size;
|
1376
|
+
|
1377
|
+
if (!!s->canny_ringbuffer_allocation) {
|
1378
|
+
/* Reduce ring buffer size to save memory when server is unscrupulous.
|
1379
|
+
In worst case memory usage might be 1.5x bigger for a short period of
|
1380
|
+
ring buffer reallocation.*/
|
1381
|
+
while ((new_ringbuffer_size >> 1) >= min_size) {
|
1382
|
+
new_ringbuffer_size >>= 1;
|
1354
1383
|
}
|
1355
1384
|
}
|
1356
1385
|
|
1357
|
-
s->
|
1386
|
+
s->new_ringbuffer_size = new_ringbuffer_size;
|
1358
1387
|
}
|
1359
1388
|
|
1360
1389
|
/* Reads 1..256 2-bit context modes. */
|
@@ -1379,6 +1408,8 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
|
|
1379
1408
|
if (s->distance_code == 0) {
|
1380
1409
|
--s->dist_rb_idx;
|
1381
1410
|
s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
|
1411
|
+
/* Compensate double distance-ring-buffer roll for dictionary items. */
|
1412
|
+
s->distance_context = 1;
|
1382
1413
|
} else {
|
1383
1414
|
int distance_code = s->distance_code << 1;
|
1384
1415
|
/* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */
|
@@ -1432,6 +1463,7 @@ static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
|
|
1432
1463
|
}
|
1433
1464
|
/* Convert the distance code to the actual distance by possibly */
|
1434
1465
|
/* looking up past distances from the s->ringbuffer. */
|
1466
|
+
s->distance_context = 0;
|
1435
1467
|
if ((s->distance_code & ~0xf) == 0) {
|
1436
1468
|
TakeDistanceFromRingBuffer(s);
|
1437
1469
|
--s->block_length[2];
|
@@ -1503,7 +1535,7 @@ static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
|
|
1503
1535
|
s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
|
1504
1536
|
*insert_length = v.insert_len_offset;
|
1505
1537
|
if (!safe) {
|
1506
|
-
if (
|
1538
|
+
if (BROTLI_PREDICT_FALSE(v.insert_len_extra_bits != 0)) {
|
1507
1539
|
insert_len_extra = BrotliReadBits(br, v.insert_len_extra_bits);
|
1508
1540
|
}
|
1509
1541
|
copy_length = BrotliReadBits(br, v.copy_len_extra_bits);
|
@@ -1587,7 +1619,7 @@ CommandBegin:
|
|
1587
1619
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1588
1620
|
goto saveStateAndReturn;
|
1589
1621
|
}
|
1590
|
-
if (
|
1622
|
+
if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) {
|
1591
1623
|
BROTLI_SAFE(DecodeCommandBlockSwitch(s));
|
1592
1624
|
goto CommandBegin;
|
1593
1625
|
}
|
@@ -1615,7 +1647,7 @@ CommandInner:
|
|
1615
1647
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1616
1648
|
goto saveStateAndReturn;
|
1617
1649
|
}
|
1618
|
-
if (
|
1650
|
+
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
|
1619
1651
|
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
|
1620
1652
|
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
1621
1653
|
if (!s->trivial_literal_context) goto CommandInner;
|
@@ -1634,7 +1666,7 @@ CommandInner:
|
|
1634
1666
|
--s->block_length[0];
|
1635
1667
|
BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
|
1636
1668
|
++pos;
|
1637
|
-
if (
|
1669
|
+
if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {
|
1638
1670
|
s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
|
1639
1671
|
--i;
|
1640
1672
|
goto saveStateAndReturn;
|
@@ -1651,7 +1683,7 @@ CommandInner:
|
|
1651
1683
|
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
1652
1684
|
goto saveStateAndReturn;
|
1653
1685
|
}
|
1654
|
-
if (
|
1686
|
+
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
|
1655
1687
|
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
|
1656
1688
|
if (s->trivial_literal_context) goto CommandInner;
|
1657
1689
|
}
|
@@ -1674,7 +1706,7 @@ CommandInner:
|
|
1674
1706
|
BROTLI_LOG_UINT(s->context_map_slice[context]);
|
1675
1707
|
BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);
|
1676
1708
|
++pos;
|
1677
|
-
if (
|
1709
|
+
if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {
|
1678
1710
|
s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
|
1679
1711
|
--i;
|
1680
1712
|
goto saveStateAndReturn;
|
@@ -1682,7 +1714,7 @@ CommandInner:
|
|
1682
1714
|
} while (--i != 0);
|
1683
1715
|
}
|
1684
1716
|
BROTLI_LOG_UINT(s->meta_block_remaining_len);
|
1685
|
-
if (
|
1717
|
+
if (BROTLI_PREDICT_FALSE(s->meta_block_remaining_len <= 0)) {
|
1686
1718
|
s->state = BROTLI_STATE_METABLOCK_DONE;
|
1687
1719
|
goto saveStateAndReturn;
|
1688
1720
|
}
|
@@ -1692,46 +1724,54 @@ CommandPostDecodeLiterals:
|
|
1692
1724
|
s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
|
1693
1725
|
}
|
1694
1726
|
if (s->distance_code >= 0) {
|
1727
|
+
/* Implicit distance case. */
|
1728
|
+
s->distance_context = s->distance_code ? 0 : 1;
|
1695
1729
|
--s->dist_rb_idx;
|
1696
1730
|
s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1731
|
+
} else {
|
1732
|
+
/* Read distance code in the command, unless it was implicitly zero. */
|
1733
|
+
if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {
|
1734
|
+
BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
|
1735
|
+
}
|
1736
|
+
BROTLI_SAFE(ReadDistance(s, br));
|
1702
1737
|
}
|
1703
|
-
BROTLI_SAFE(ReadDistance(s, br));
|
1704
|
-
postReadDistance:
|
1705
1738
|
BROTLI_LOG(("[ProcessCommandsInternal] pos = %d distance = %d\n",
|
1706
1739
|
pos, s->distance_code));
|
1707
1740
|
if (s->max_distance != s->max_backward_distance) {
|
1708
|
-
|
1709
|
-
|
1710
|
-
} else {
|
1711
|
-
s->max_distance = s->max_backward_distance;
|
1712
|
-
}
|
1741
|
+
s->max_distance =
|
1742
|
+
(pos < s->max_backward_distance) ? pos : s->max_backward_distance;
|
1713
1743
|
}
|
1714
1744
|
i = s->copy_length;
|
1715
1745
|
/* Apply copy of LZ77 back-reference, or static dictionary reference if
|
1716
1746
|
the distance is larger than the max LZ77 distance */
|
1717
1747
|
if (s->distance_code > s->max_distance) {
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
int
|
1722
|
-
uint32_t shift =
|
1748
|
+
int address = s->distance_code - s->max_distance - 1;
|
1749
|
+
if (i >= BROTLI_MIN_DICTIONARY_WORD_LENGTH &&
|
1750
|
+
i <= BROTLI_MAX_DICTIONARY_WORD_LENGTH) {
|
1751
|
+
int offset = (int)s->dictionary->offsets_by_length[i];
|
1752
|
+
uint32_t shift = s->dictionary->size_bits_by_length[i];
|
1723
1753
|
int mask = (int)BitMask(shift);
|
1724
|
-
int word_idx =
|
1725
|
-
int transform_idx =
|
1754
|
+
int word_idx = address & mask;
|
1755
|
+
int transform_idx = address >> shift;
|
1756
|
+
/* Compensate double distance-ring-buffer roll. */
|
1757
|
+
s->dist_rb_idx += s->distance_context;
|
1726
1758
|
offset += word_idx * i;
|
1759
|
+
if (BROTLI_PREDICT_FALSE(!s->dictionary->data)) {
|
1760
|
+
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET);
|
1761
|
+
}
|
1727
1762
|
if (transform_idx < kNumTransforms) {
|
1728
|
-
const uint8_t* word = &
|
1763
|
+
const uint8_t* word = &s->dictionary->data[offset];
|
1729
1764
|
int len = i;
|
1730
1765
|
if (transform_idx == 0) {
|
1731
1766
|
memcpy(&s->ringbuffer[pos], word, (size_t)len);
|
1767
|
+
BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s]\n",
|
1768
|
+
len, word));
|
1732
1769
|
} else {
|
1733
1770
|
len = TransformDictionaryWord(
|
1734
1771
|
&s->ringbuffer[pos], word, len, transform_idx);
|
1772
|
+
BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s],"
|
1773
|
+
" transform_idx = %d, transformed: [%.*s]\n",
|
1774
|
+
i, word, transform_idx, len, &s->ringbuffer[pos]));
|
1735
1775
|
}
|
1736
1776
|
pos += len;
|
1737
1777
|
s->meta_block_remaining_len -= len;
|
@@ -1762,9 +1802,9 @@ postReadDistance:
|
|
1762
1802
|
s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
|
1763
1803
|
++s->dist_rb_idx;
|
1764
1804
|
s->meta_block_remaining_len -= i;
|
1765
|
-
/* There are 32+ bytes of slack in the
|
1805
|
+
/* There are 32+ bytes of slack in the ring-buffer allocation.
|
1766
1806
|
Also, we have 16 short codes, that make these 16 bytes irrelevant
|
1767
|
-
in the
|
1807
|
+
in the ring-buffer. Let's copy over them as a first guess.
|
1768
1808
|
*/
|
1769
1809
|
memmove16(copy_dst, copy_src);
|
1770
1810
|
if (src_end > pos && dst_end > src_start) {
|
@@ -1801,7 +1841,7 @@ CommandPostWrapCopy:
|
|
1801
1841
|
s->ringbuffer[pos] =
|
1802
1842
|
s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
|
1803
1843
|
++pos;
|
1804
|
-
if (
|
1844
|
+
if (BROTLI_PREDICT_FALSE(--wrap_guard == 0)) {
|
1805
1845
|
s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
|
1806
1846
|
goto saveStateAndReturn;
|
1807
1847
|
}
|
@@ -1857,7 +1897,7 @@ BrotliDecoderResult BrotliDecoderDecompress(
|
|
1857
1897
|
/* Invariant: input stream is never overconsumed:
|
1858
1898
|
* invalid input implies that the whole stream is invalid -> any amount of
|
1859
1899
|
input could be read and discarded
|
1860
|
-
* when result is "needs more input", then at
|
1900
|
+
* when result is "needs more input", then at least one more byte is REQUIRED
|
1861
1901
|
to complete decoding; all input data MUST be consumed by decoder, so
|
1862
1902
|
client could swap the input buffer
|
1863
1903
|
* when result is "needs more output" decoder MUST ensure that it doesn't
|
@@ -1871,6 +1911,15 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
1871
1911
|
size_t* available_out, uint8_t** next_out, size_t* total_out) {
|
1872
1912
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
1873
1913
|
BrotliBitReader* br = &s->br;
|
1914
|
+
/* Do not try to process further in a case of unrecoverable error. */
|
1915
|
+
if ((int)s->error_code < 0) {
|
1916
|
+
return BROTLI_DECODER_RESULT_ERROR;
|
1917
|
+
}
|
1918
|
+
if (*available_out && (!next_out || !*next_out)) {
|
1919
|
+
return SaveErrorCode(
|
1920
|
+
s, BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
|
1921
|
+
}
|
1922
|
+
if (!*available_out) next_out = 0;
|
1874
1923
|
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
|
1875
1924
|
br->avail_in = *available_in;
|
1876
1925
|
br->next_in = *next_in;
|
@@ -1885,12 +1934,18 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
1885
1934
|
for (;;) {
|
1886
1935
|
if (result != BROTLI_DECODER_SUCCESS) { /* Error, needs more input/output */
|
1887
1936
|
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
1888
|
-
if (s->ringbuffer != 0) { /*
|
1889
|
-
WriteRingBuffer(s,
|
1937
|
+
if (s->ringbuffer != 0) { /* Pro-actively push output. */
|
1938
|
+
BrotliDecoderErrorCode intermediate_result = WriteRingBuffer(s,
|
1939
|
+
available_out, next_out, total_out, BROTLI_TRUE);
|
1940
|
+
/* WriteRingBuffer checks s->meta_block_remaining_len validity. */
|
1941
|
+
if ((int)intermediate_result < 0) {
|
1942
|
+
result = intermediate_result;
|
1943
|
+
break;
|
1944
|
+
}
|
1890
1945
|
}
|
1891
1946
|
if (s->buffer_length != 0) { /* Used with internal buffer. */
|
1892
1947
|
if (br->avail_in == 0) { /* Successfully finished read transaction. */
|
1893
|
-
/*
|
1948
|
+
/* Accumulator contains less than 8 bits, because internal buffer
|
1894
1949
|
is expanded byte-by-byte until it is enough to complete read. */
|
1895
1950
|
s->buffer_length = 0;
|
1896
1951
|
/* Switch to input stream and restart. */
|
@@ -1935,8 +1990,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
1935
1990
|
s->buffer_length = 0;
|
1936
1991
|
} else {
|
1937
1992
|
/* Using input stream in last iteration. When decoder switches to input
|
1938
|
-
stream it has less than 8 bits in
|
1939
|
-
return unused
|
1993
|
+
stream it has less than 8 bits in accumulator, so it is safe to
|
1994
|
+
return unused accumulator bits there. */
|
1940
1995
|
BrotliBitReaderUnload(br);
|
1941
1996
|
*available_in = br->avail_in;
|
1942
1997
|
*next_in = br->next_in;
|
@@ -1959,14 +2014,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
1959
2014
|
break;
|
1960
2015
|
}
|
1961
2016
|
/* Maximum distance, see section 9.1. of the spec. */
|
1962
|
-
s->max_backward_distance = (1 << s->window_bits) -
|
1963
|
-
/* Limit custom dictionary size. */
|
1964
|
-
if (s->custom_dict_size >= s->max_backward_distance) {
|
1965
|
-
s->custom_dict += s->custom_dict_size - s->max_backward_distance;
|
1966
|
-
s->custom_dict_size = s->max_backward_distance;
|
1967
|
-
}
|
1968
|
-
s->max_backward_distance_minus_custom_dict_size =
|
1969
|
-
s->max_backward_distance - s->custom_dict_size;
|
2017
|
+
s->max_backward_distance = (1 << s->window_bits) - BROTLI_WINDOW_GAP;
|
1970
2018
|
|
1971
2019
|
/* Allocate memory for both block_type_trees and block_len_trees. */
|
1972
2020
|
s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s,
|
@@ -2009,9 +2057,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2009
2057
|
s->state = BROTLI_STATE_METABLOCK_DONE;
|
2010
2058
|
break;
|
2011
2059
|
}
|
2012
|
-
|
2013
|
-
BrotliCalculateRingBufferSize(s, br);
|
2014
|
-
}
|
2060
|
+
BrotliCalculateRingBufferSize(s);
|
2015
2061
|
if (s->is_uncompressed) {
|
2016
2062
|
s->state = BROTLI_STATE_UNCOMPRESSED;
|
2017
2063
|
break;
|
@@ -2020,10 +2066,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2020
2066
|
s->state = BROTLI_STATE_HUFFMAN_CODE_0;
|
2021
2067
|
break;
|
2022
2068
|
case BROTLI_STATE_UNCOMPRESSED: {
|
2023
|
-
int bytes_copied = s->meta_block_remaining_len;
|
2024
2069
|
result = CopyUncompressedBlockToOutput(
|
2025
2070
|
available_out, next_out, total_out, s);
|
2026
|
-
bytes_copied -= s->meta_block_remaining_len;
|
2027
2071
|
if (result != BROTLI_DECODER_SUCCESS) {
|
2028
2072
|
break;
|
2029
2073
|
}
|
@@ -2131,26 +2175,25 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2131
2175
|
/* No break, continue to next state */
|
2132
2176
|
case BROTLI_STATE_CONTEXT_MAP_2:
|
2133
2177
|
{
|
2134
|
-
uint32_t num_distance_codes =
|
2135
|
-
|
2178
|
+
uint32_t num_distance_codes = s->num_direct_distance_codes +
|
2179
|
+
((2 * BROTLI_MAX_DISTANCE_BITS) << s->distance_postfix_bits);
|
2180
|
+
BROTLI_BOOL allocation_success = BROTLI_TRUE;
|
2136
2181
|
result = DecodeContextMap(
|
2137
2182
|
s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS,
|
2138
2183
|
&s->num_dist_htrees, &s->dist_context_map, s);
|
2139
2184
|
if (result != BROTLI_DECODER_SUCCESS) {
|
2140
2185
|
break;
|
2141
2186
|
}
|
2142
|
-
BrotliDecoderHuffmanTreeGroupInit(
|
2187
|
+
allocation_success &= BrotliDecoderHuffmanTreeGroupInit(
|
2143
2188
|
s, &s->literal_hgroup, BROTLI_NUM_LITERAL_SYMBOLS,
|
2144
2189
|
s->num_literal_htrees);
|
2145
|
-
BrotliDecoderHuffmanTreeGroupInit(
|
2190
|
+
allocation_success &= BrotliDecoderHuffmanTreeGroupInit(
|
2146
2191
|
s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS,
|
2147
2192
|
s->num_block_types[1]);
|
2148
|
-
BrotliDecoderHuffmanTreeGroupInit(
|
2193
|
+
allocation_success &= BrotliDecoderHuffmanTreeGroupInit(
|
2149
2194
|
s, &s->distance_hgroup, num_distance_codes,
|
2150
2195
|
s->num_dist_htrees);
|
2151
|
-
if (
|
2152
|
-
s->insert_copy_hgroup.codes == 0 ||
|
2153
|
-
s->distance_hgroup.codes == 0) {
|
2196
|
+
if (!allocation_success) {
|
2154
2197
|
return SaveErrorCode(s,
|
2155
2198
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
|
2156
2199
|
}
|
@@ -2183,7 +2226,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2183
2226
|
PrepareLiteralDecoding(s);
|
2184
2227
|
s->dist_context_map_slice = s->dist_context_map;
|
2185
2228
|
s->htree_command = s->insert_copy_hgroup.htrees[0];
|
2186
|
-
if (!
|
2229
|
+
if (!BrotliEnsureRingBuffer(s)) {
|
2187
2230
|
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
|
2188
2231
|
break;
|
2189
2232
|
}
|
@@ -2202,13 +2245,16 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2202
2245
|
case BROTLI_STATE_COMMAND_INNER_WRITE:
|
2203
2246
|
case BROTLI_STATE_COMMAND_POST_WRITE_1:
|
2204
2247
|
case BROTLI_STATE_COMMAND_POST_WRITE_2:
|
2205
|
-
result = WriteRingBuffer(
|
2248
|
+
result = WriteRingBuffer(
|
2249
|
+
s, available_out, next_out, total_out, BROTLI_FALSE);
|
2206
2250
|
if (result != BROTLI_DECODER_SUCCESS) {
|
2207
2251
|
break;
|
2208
2252
|
}
|
2209
|
-
s
|
2253
|
+
WrapRingBuffer(s);
|
2254
|
+
if (s->ringbuffer_size == 1 << s->window_bits) {
|
2255
|
+
s->max_distance = s->max_backward_distance;
|
2256
|
+
}
|
2210
2257
|
if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
|
2211
|
-
memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
|
2212
2258
|
if (s->meta_block_remaining_len == 0) {
|
2213
2259
|
/* Next metablock, if any */
|
2214
2260
|
s->state = BROTLI_STATE_METABLOCK_DONE;
|
@@ -2253,7 +2299,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2253
2299
|
/* No break, continue to next state */
|
2254
2300
|
case BROTLI_STATE_DONE:
|
2255
2301
|
if (s->ringbuffer != 0) {
|
2256
|
-
result = WriteRingBuffer(
|
2302
|
+
result = WriteRingBuffer(
|
2303
|
+
s, available_out, next_out, total_out, BROTLI_TRUE);
|
2257
2304
|
if (result != BROTLI_DECODER_SUCCESS) {
|
2258
2305
|
break;
|
2259
2306
|
}
|
@@ -2264,27 +2311,48 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
|
2264
2311
|
return SaveErrorCode(s, result);
|
2265
2312
|
}
|
2266
2313
|
|
2267
|
-
void BrotliDecoderSetCustomDictionary(
|
2268
|
-
BrotliDecoderState* s, size_t size, const uint8_t* dict) {
|
2269
|
-
if (size > (1u << 24)) {
|
2270
|
-
return;
|
2271
|
-
}
|
2272
|
-
s->custom_dict = dict;
|
2273
|
-
s->custom_dict_size = (int)size;
|
2274
|
-
}
|
2275
|
-
|
2276
2314
|
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {
|
2315
|
+
/* After unrecoverable error remaining output is considered nonsensical. */
|
2316
|
+
if ((int)s->error_code < 0) {
|
2317
|
+
return BROTLI_FALSE;
|
2318
|
+
}
|
2277
2319
|
return TO_BROTLI_BOOL(
|
2278
2320
|
s->ringbuffer != 0 && UnwrittenBytes(s, BROTLI_FALSE) != 0);
|
2279
2321
|
}
|
2280
2322
|
|
2323
|
+
const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) {
|
2324
|
+
uint8_t* result = 0;
|
2325
|
+
size_t available_out = *size ? *size : 1u << 24;
|
2326
|
+
size_t requested_out = available_out;
|
2327
|
+
BrotliDecoderErrorCode status;
|
2328
|
+
if ((s->ringbuffer == 0) || ((int)s->error_code < 0)) {
|
2329
|
+
*size = 0;
|
2330
|
+
return 0;
|
2331
|
+
}
|
2332
|
+
WrapRingBuffer(s);
|
2333
|
+
status = WriteRingBuffer(s, &available_out, &result, 0, BROTLI_TRUE);
|
2334
|
+
/* Either WriteRingBuffer returns those "success" codes... */
|
2335
|
+
if (status == BROTLI_DECODER_SUCCESS ||
|
2336
|
+
status == BROTLI_DECODER_NEEDS_MORE_OUTPUT) {
|
2337
|
+
*size = requested_out - available_out;
|
2338
|
+
} else {
|
2339
|
+
/* ... or stream is broken. Normally this should be caught by
|
2340
|
+
BrotliDecoderDecompressStream, this is just a safeguard. */
|
2341
|
+
if ((int)status < 0) SaveErrorCode(s, status);
|
2342
|
+
*size = 0;
|
2343
|
+
result = 0;
|
2344
|
+
}
|
2345
|
+
return result;
|
2346
|
+
}
|
2347
|
+
|
2281
2348
|
BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s) {
|
2282
2349
|
return TO_BROTLI_BOOL(s->state != BROTLI_STATE_UNINITED ||
|
2283
2350
|
BrotliGetAvailableBits(&s->br) != 0);
|
2284
2351
|
}
|
2285
2352
|
|
2286
2353
|
BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s) {
|
2287
|
-
return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE)
|
2354
|
+
return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE) &&
|
2355
|
+
!BrotliDecoderHasMoreOutput(s);
|
2288
2356
|
}
|
2289
2357
|
|
2290
2358
|
BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
|
@@ -2293,54 +2361,19 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
|
|
2293
2361
|
|
2294
2362
|
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
2295
2363
|
switch (c) {
|
2296
|
-
#define
|
2364
|
+
#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \
|
2297
2365
|
case BROTLI_DECODER ## PREFIX ## NAME: return #NAME;
|
2298
|
-
#define
|
2299
|
-
BROTLI_DECODER_ERROR_CODES_LIST(
|
2300
|
-
#undef
|
2301
|
-
#undef
|
2366
|
+
#define BROTLI_NOTHING_
|
2367
|
+
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_)
|
2368
|
+
#undef BROTLI_ERROR_CODE_CASE_
|
2369
|
+
#undef BROTLI_NOTHING_
|
2302
2370
|
default: return "INVALID";
|
2303
2371
|
}
|
2304
2372
|
}
|
2305
2373
|
|
2306
|
-
|
2307
|
-
|
2308
|
-
brotli_alloc_func alloc, brotli_free_func free, void* opaque) {
|
2309
|
-
return (BrotliState*)BrotliDecoderCreateInstance(alloc, free, opaque);
|
2310
|
-
}
|
2311
|
-
void BrotliDestroyState(BrotliState* state) {
|
2312
|
-
BrotliDecoderDestroyInstance((BrotliDecoderState*)state);
|
2313
|
-
}
|
2314
|
-
BrotliResult BrotliDecompressBuffer(
|
2315
|
-
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
|
2316
|
-
uint8_t* decoded_buffer) {
|
2317
|
-
return (BrotliResult)BrotliDecoderDecompress(
|
2318
|
-
encoded_size, encoded_buffer, decoded_size, decoded_buffer);
|
2319
|
-
}
|
2320
|
-
BrotliResult BrotliDecompressStream(
|
2321
|
-
size_t* available_in, const uint8_t** next_in, size_t* available_out,
|
2322
|
-
uint8_t** next_out, size_t* total_out, BrotliState* s) {
|
2323
|
-
return (BrotliResult)BrotliDecoderDecompressStream((BrotliDecoderState*)s,
|
2324
|
-
available_in, next_in, available_out, next_out, total_out);
|
2325
|
-
}
|
2326
|
-
void BrotliSetCustomDictionary(
|
2327
|
-
size_t size, const uint8_t* dict, BrotliState* s) {
|
2328
|
-
BrotliDecoderSetCustomDictionary((BrotliDecoderState*)s, size, dict);
|
2329
|
-
}
|
2330
|
-
BROTLI_BOOL BrotliStateIsStreamStart(const BrotliState* s) {
|
2331
|
-
return !BrotliDecoderIsUsed((const BrotliDecoderState*)s);
|
2332
|
-
}
|
2333
|
-
BROTLI_BOOL BrotliStateIsStreamEnd(const BrotliState* s) {
|
2334
|
-
return BrotliDecoderIsFinished((const BrotliDecoderState*)s);
|
2335
|
-
}
|
2336
|
-
BrotliErrorCode BrotliGetErrorCode(const BrotliState* s) {
|
2337
|
-
return (BrotliErrorCode)BrotliDecoderGetErrorCode(
|
2338
|
-
(const BrotliDecoderState*)s);
|
2339
|
-
}
|
2340
|
-
const char* BrotliErrorString(BrotliErrorCode c) {
|
2341
|
-
return BrotliDecoderErrorString((BrotliDecoderErrorCode)c);
|
2374
|
+
uint32_t BrotliDecoderVersion() {
|
2375
|
+
return BROTLI_VERSION;
|
2342
2376
|
}
|
2343
|
-
/* <<< DEPRECATED */
|
2344
2377
|
|
2345
2378
|
#if defined(__cplusplus) || defined(c_plusplus)
|
2346
2379
|
} /* extern "C" */
|