brotli 0.1.8 → 0.2.0
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/.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" */
|