brotli 0.2.3 → 0.4.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/.github/workflows/main.yml +34 -0
- data/.github/workflows/publish.yml +34 -0
- data/Gemfile +6 -3
- data/Rakefile +16 -9
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +209 -31
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +20 -18
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +104 -0
- data/test/brotli_writer_test.rb +36 -0
- data/test/test_helper.rb +8 -0
- data/vendor/brotli/c/common/constants.c +15 -0
- data/vendor/brotli/c/common/constants.h +136 -0
- data/vendor/brotli/c/common/context.c +156 -0
- data/vendor/brotli/c/common/context.h +4 -152
- data/vendor/brotli/c/common/dictionary.bin.br +0 -0
- data/vendor/brotli/c/common/dictionary.c +10 -1
- data/vendor/brotli/c/common/platform.c +22 -0
- data/vendor/brotli/c/common/platform.h +43 -17
- data/vendor/brotli/c/common/transform.c +59 -3
- data/vendor/brotli/c/common/transform.h +5 -0
- data/vendor/brotli/c/common/version.h +2 -2
- data/vendor/brotli/c/dec/bit_reader.c +28 -0
- data/vendor/brotli/c/dec/bit_reader.h +58 -16
- data/vendor/brotli/c/dec/decode.c +353 -251
- data/vendor/brotli/c/dec/huffman.h +6 -12
- data/vendor/brotli/c/dec/prefix.h +0 -18
- data/vendor/brotli/c/dec/state.c +9 -14
- data/vendor/brotli/c/dec/state.h +144 -37
- data/vendor/brotli/c/enc/backward_references.c +8 -7
- data/vendor/brotli/c/enc/backward_references.h +5 -4
- data/vendor/brotli/c/enc/backward_references_hq.c +51 -33
- data/vendor/brotli/c/enc/backward_references_hq.h +11 -8
- data/vendor/brotli/c/enc/backward_references_inc.h +24 -14
- data/vendor/brotli/c/enc/block_splitter.c +3 -3
- data/vendor/brotli/c/enc/block_splitter_inc.h +15 -6
- data/vendor/brotli/c/enc/brotli_bit_stream.c +13 -30
- data/vendor/brotli/c/enc/cluster_inc.h +6 -3
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +12 -12
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +1 -1
- data/vendor/brotli/c/enc/dictionary_hash.c +1826 -1100
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +104 -39
- data/vendor/brotli/c/enc/encoder_dict.c +3 -2
- data/vendor/brotli/c/enc/encoder_dict.h +3 -1
- data/vendor/brotli/c/enc/entropy_encode.c +2 -0
- data/vendor/brotli/c/enc/entropy_encode.h +2 -2
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +19 -100
- data/vendor/brotli/c/enc/find_match_length.h +2 -3
- data/vendor/brotli/c/enc/hash.h +80 -90
- data/vendor/brotli/c/enc/hash_composite_inc.h +52 -63
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +88 -49
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +50 -50
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -50
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +91 -60
- data/vendor/brotli/c/enc/hash_rolling_inc.h +23 -27
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +39 -38
- data/vendor/brotli/c/enc/memory.h +24 -12
- data/vendor/brotli/c/enc/metablock.c +23 -27
- data/vendor/brotli/c/enc/metablock_inc.h +1 -1
- data/vendor/brotli/c/enc/params.h +3 -1
- data/vendor/brotli/c/enc/ringbuffer.h +4 -1
- data/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/vendor/brotli/c/enc/write_bits.h +27 -25
- data/vendor/brotli/c/include/brotli/encode.h +22 -1
- data/vendor/brotli/c/include/brotli/port.h +14 -0
- metadata +17 -97
- data/.travis.yml +0 -31
- data/docs/Brotli.html +0 -485
- data/docs/Brotli/Error.html +0 -124
- data/docs/_index.html +0 -122
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -496
- data/docs/file.README.html +0 -127
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -127
- data/docs/js/app.js +0 -292
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -67
- data/docs/top-level-namespace.html +0 -110
- data/spec/brotli_spec.rb +0 -88
- data/spec/inflate_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -4
@@ -18,12 +18,6 @@ extern "C" {
|
|
18
18
|
|
19
19
|
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
|
20
20
|
|
21
|
-
/* Maximum possible Huffman table size for an alphabet size of (index * 32),
|
22
|
-
max code length 15 and root table bits 8. */
|
23
|
-
static const uint16_t kMaxHuffmanTableSize[] = {
|
24
|
-
256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,
|
25
|
-
854, 886, 920, 952, 984, 1016, 1048, 1080, 1112, 1144, 1176, 1208, 1240, 1272,
|
26
|
-
1304, 1336, 1368, 1400, 1432, 1464, 1496, 1528};
|
27
21
|
/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */
|
28
22
|
#define BROTLI_HUFFMAN_MAX_SIZE_26 396
|
29
23
|
/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
|
@@ -82,7 +76,7 @@ typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
|
|
82
76
|
|
83
77
|
static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
|
84
78
|
const uint16_t value) {
|
85
|
-
return ((value & 0xFFFF) << 16) | (bits & 0xFF);
|
79
|
+
return (HuffmanCode) ((value & 0xFFFF) << 16) | (bits & 0xFF);
|
86
80
|
}
|
87
81
|
|
88
82
|
#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
|
@@ -100,7 +94,7 @@ BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
|
|
100
94
|
/* Builds Huffman lookup table assuming code lengths are in symbol order.
|
101
95
|
Returns size of resulting table. */
|
102
96
|
BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
103
|
-
int root_bits, const uint16_t* const symbol_lists, uint16_t*
|
97
|
+
int root_bits, const uint16_t* const symbol_lists, uint16_t* count);
|
104
98
|
|
105
99
|
/* Builds a simple Huffman table. The |num_symbols| parameter is to be
|
106
100
|
interpreted as follows: 0 means 1 symbol, 1 means 2 symbols,
|
@@ -110,13 +104,13 @@ BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
|
110
104
|
int root_bits, uint16_t* symbols, uint32_t num_symbols);
|
111
105
|
|
112
106
|
/* Contains a collection of Huffman trees with the same alphabet size. */
|
113
|
-
/*
|
114
|
-
greater than log2(
|
107
|
+
/* alphabet_size_limit is needed due to simple codes, since
|
108
|
+
log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */
|
115
109
|
typedef struct {
|
116
110
|
HuffmanCode** htrees;
|
117
111
|
HuffmanCode* codes;
|
118
|
-
uint16_t
|
119
|
-
uint16_t
|
112
|
+
uint16_t alphabet_size_max;
|
113
|
+
uint16_t alphabet_size_limit;
|
120
114
|
uint16_t num_htrees;
|
121
115
|
} HuffmanTreeGroup;
|
122
116
|
|
@@ -13,24 +13,6 @@
|
|
13
13
|
#include "../common/constants.h"
|
14
14
|
#include <brotli/types.h>
|
15
15
|
|
16
|
-
/* Represents the range of values belonging to a prefix code:
|
17
|
-
[offset, offset + 2^nbits) */
|
18
|
-
struct PrefixCodeRange {
|
19
|
-
uint16_t offset;
|
20
|
-
uint8_t nbits;
|
21
|
-
};
|
22
|
-
|
23
|
-
static const struct PrefixCodeRange
|
24
|
-
kBlockLengthPrefixCode[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = {
|
25
|
-
{ 1, 2}, { 5, 2}, { 9, 2}, { 13, 2},
|
26
|
-
{ 17, 3}, { 25, 3}, { 33, 3}, { 41, 3},
|
27
|
-
{ 49, 4}, { 65, 4}, { 81, 4}, { 97, 4},
|
28
|
-
{ 113, 5}, { 145, 5}, { 177, 5}, { 209, 5},
|
29
|
-
{ 241, 6}, { 305, 6}, { 369, 7}, { 497, 8},
|
30
|
-
{ 753, 9}, { 1265, 10}, {2289, 11}, {4337, 12},
|
31
|
-
{8433, 13}, {16625, 24}
|
32
|
-
};
|
33
|
-
|
34
16
|
typedef struct CmdLutElement {
|
35
17
|
uint8_t insert_len_extra_bits;
|
36
18
|
uint8_t copy_len_extra_bits;
|
data/vendor/brotli/c/dec/state.c
CHANGED
@@ -33,10 +33,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
33
33
|
s->state = BROTLI_STATE_UNINITED;
|
34
34
|
s->large_window = 0;
|
35
35
|
s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
|
36
|
-
s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
|
37
|
-
s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
|
38
36
|
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
|
39
|
-
s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
40
37
|
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
|
41
38
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
|
42
39
|
|
@@ -59,8 +56,6 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
59
56
|
s->context_map_slice = NULL;
|
60
57
|
s->dist_context_map_slice = NULL;
|
61
58
|
|
62
|
-
s->sub_loop_counter = 0;
|
63
|
-
|
64
59
|
s->literal_hgroup.codes = NULL;
|
65
60
|
s->literal_hgroup.htrees = NULL;
|
66
61
|
s->insert_copy_hgroup.codes = NULL;
|
@@ -84,9 +79,6 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
84
79
|
s->block_type_trees = NULL;
|
85
80
|
s->block_len_trees = NULL;
|
86
81
|
|
87
|
-
/* Make small negative indexes addressable. */
|
88
|
-
s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
|
89
|
-
|
90
82
|
s->mtf_upper_bound = 63;
|
91
83
|
|
92
84
|
s->dictionary = BrotliGetDictionary();
|
@@ -142,17 +134,20 @@ void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
|
|
142
134
|
}
|
143
135
|
|
144
136
|
BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
|
145
|
-
HuffmanTreeGroup* group, uint32_t
|
146
|
-
uint32_t ntrees) {
|
147
|
-
/*
|
148
|
-
|
137
|
+
HuffmanTreeGroup* group, uint32_t alphabet_size_max,
|
138
|
+
uint32_t alphabet_size_limit, uint32_t ntrees) {
|
139
|
+
/* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
|
140
|
+
This number is discovered "unlimited" "enough" calculator; it is actually
|
141
|
+
a wee bigger than required in several cases (especially for alphabets with
|
142
|
+
less than 16 symbols). */
|
143
|
+
const size_t max_table_size = alphabet_size_limit + 376;
|
149
144
|
const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
|
150
145
|
const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
|
151
146
|
/* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
|
152
147
|
HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
|
153
148
|
code_size + htree_size);
|
154
|
-
group->
|
155
|
-
group->
|
149
|
+
group->alphabet_size_max = (uint16_t)alphabet_size_max;
|
150
|
+
group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
|
156
151
|
group->num_htrees = (uint16_t)ntrees;
|
157
152
|
group->htrees = p;
|
158
153
|
group->codes = (HuffmanCode*)(&p[ntrees]);
|
data/vendor/brotli/c/dec/state.h
CHANGED
@@ -21,6 +21,95 @@
|
|
21
21
|
extern "C" {
|
22
22
|
#endif
|
23
23
|
|
24
|
+
/* Graphviz diagram that describes state transitions:
|
25
|
+
|
26
|
+
digraph States {
|
27
|
+
graph [compound=true]
|
28
|
+
concentrate=true
|
29
|
+
node [shape="box"]
|
30
|
+
|
31
|
+
UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
|
32
|
+
subgraph cluster_metablock_workflow {
|
33
|
+
style="rounded"
|
34
|
+
label=< <B>METABLOCK CYCLE</B> >
|
35
|
+
METABLOCK_BEGIN -> METABLOCK_HEADER
|
36
|
+
METABLOCK_HEADER:sw -> METADATA
|
37
|
+
METABLOCK_HEADER:s -> UNCOMPRESSED
|
38
|
+
METABLOCK_HEADER:se -> METABLOCK_DONE:ne
|
39
|
+
METADATA:s -> METABLOCK_DONE:w
|
40
|
+
UNCOMPRESSED:s -> METABLOCK_DONE:n
|
41
|
+
METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
|
42
|
+
}
|
43
|
+
INITIALIZE -> METABLOCK_BEGIN
|
44
|
+
METABLOCK_DONE -> DONE
|
45
|
+
|
46
|
+
subgraph cluster_compressed_metablock {
|
47
|
+
style="rounded"
|
48
|
+
label=< <B>COMPRESSED METABLOCK</B> >
|
49
|
+
|
50
|
+
subgraph cluster_command {
|
51
|
+
style="rounded"
|
52
|
+
label=< <B>HOT LOOP</B> >
|
53
|
+
|
54
|
+
_METABLOCK_DONE_PORT_ [shape=point style=invis]
|
55
|
+
|
56
|
+
{
|
57
|
+
// Set different shape for nodes returning from "compressed metablock".
|
58
|
+
node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
|
59
|
+
CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
|
60
|
+
}
|
61
|
+
|
62
|
+
CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
|
63
|
+
|
64
|
+
// IO ("write") nodes are not in the hot loop!
|
65
|
+
CMD_INNER_WRITE [style=dashed]
|
66
|
+
CMD_INNER -> CMD_INNER_WRITE
|
67
|
+
CMD_POST_WRITE_1 [style=dashed]
|
68
|
+
CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
|
69
|
+
CMD_POST_WRITE_2 [style=dashed]
|
70
|
+
CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
|
71
|
+
|
72
|
+
CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
|
73
|
+
CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
|
74
|
+
[constraint="false"]
|
75
|
+
CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
|
76
|
+
CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
|
77
|
+
CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
|
78
|
+
CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
|
79
|
+
{rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
|
80
|
+
CMD_POST_WRAP_COPY}
|
81
|
+
{rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
|
82
|
+
|
83
|
+
{CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
|
84
|
+
_METABLOCK_DONE_PORT_ [style=invis]
|
85
|
+
{CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
|
86
|
+
[constraint="false" style=invis]
|
87
|
+
}
|
88
|
+
|
89
|
+
BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
|
90
|
+
HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
|
91
|
+
HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
|
92
|
+
CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
|
93
|
+
TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
|
94
|
+
BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
|
95
|
+
|
96
|
+
HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
|
97
|
+
{rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
|
98
|
+
{rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
|
99
|
+
TREE_GROUP}
|
100
|
+
}
|
101
|
+
METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
|
102
|
+
|
103
|
+
_METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
|
104
|
+
[constraint="false" ltail=cluster_command]
|
105
|
+
|
106
|
+
UNINITED [shape=Mdiamond];
|
107
|
+
DONE [shape=Msquare];
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
*/
|
112
|
+
|
24
113
|
typedef enum {
|
25
114
|
BROTLI_STATE_UNINITED,
|
26
115
|
BROTLI_STATE_LARGE_WINDOW_BITS,
|
@@ -39,6 +128,7 @@ typedef enum {
|
|
39
128
|
BROTLI_STATE_METABLOCK_DONE,
|
40
129
|
BROTLI_STATE_COMMAND_POST_WRITE_1,
|
41
130
|
BROTLI_STATE_COMMAND_POST_WRITE_2,
|
131
|
+
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
|
42
132
|
BROTLI_STATE_HUFFMAN_CODE_0,
|
43
133
|
BROTLI_STATE_HUFFMAN_CODE_1,
|
44
134
|
BROTLI_STATE_HUFFMAN_CODE_2,
|
@@ -46,6 +136,7 @@ typedef enum {
|
|
46
136
|
BROTLI_STATE_CONTEXT_MAP_1,
|
47
137
|
BROTLI_STATE_CONTEXT_MAP_2,
|
48
138
|
BROTLI_STATE_TREE_GROUP,
|
139
|
+
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
|
49
140
|
BROTLI_STATE_DONE
|
50
141
|
} BrotliRunningState;
|
51
142
|
|
@@ -98,6 +189,50 @@ typedef enum {
|
|
98
189
|
BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
|
99
190
|
} BrotliRunningReadBlockLengthState;
|
100
191
|
|
192
|
+
typedef struct BrotliMetablockHeaderArena {
|
193
|
+
BrotliRunningTreeGroupState substate_tree_group;
|
194
|
+
BrotliRunningContextMapState substate_context_map;
|
195
|
+
BrotliRunningHuffmanState substate_huffman;
|
196
|
+
|
197
|
+
uint32_t sub_loop_counter;
|
198
|
+
|
199
|
+
uint32_t repeat_code_len;
|
200
|
+
uint32_t prev_code_len;
|
201
|
+
|
202
|
+
/* For ReadHuffmanCode. */
|
203
|
+
uint32_t symbol;
|
204
|
+
uint32_t repeat;
|
205
|
+
uint32_t space;
|
206
|
+
|
207
|
+
/* Huffman table for "histograms". */
|
208
|
+
HuffmanCode table[32];
|
209
|
+
/* List of heads of symbol chains. */
|
210
|
+
uint16_t* symbol_lists;
|
211
|
+
/* Storage from symbol_lists. */
|
212
|
+
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
|
213
|
+
BROTLI_NUM_COMMAND_SYMBOLS];
|
214
|
+
/* Tails of symbol chains. */
|
215
|
+
int next_symbol[32];
|
216
|
+
uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
|
217
|
+
/* Population counts for the code lengths. */
|
218
|
+
uint16_t code_length_histo[16];
|
219
|
+
|
220
|
+
/* For HuffmanTreeGroupDecode. */
|
221
|
+
int htree_index;
|
222
|
+
HuffmanCode* next;
|
223
|
+
|
224
|
+
/* For DecodeContextMap. */
|
225
|
+
uint32_t context_index;
|
226
|
+
uint32_t max_run_length_prefix;
|
227
|
+
uint32_t code;
|
228
|
+
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
|
229
|
+
} BrotliMetablockHeaderArena;
|
230
|
+
|
231
|
+
typedef struct BrotliMetablockBodyArena {
|
232
|
+
uint8_t dist_extra_bits[544];
|
233
|
+
uint32_t dist_offset[544];
|
234
|
+
} BrotliMetablockBodyArena;
|
235
|
+
|
101
236
|
struct BrotliDecoderStateStruct {
|
102
237
|
BrotliRunningState state;
|
103
238
|
|
@@ -110,7 +245,8 @@ struct BrotliDecoderStateStruct {
|
|
110
245
|
brotli_free_func free_func;
|
111
246
|
void* memory_manager_opaque;
|
112
247
|
|
113
|
-
/* Temporary storage for remaining input.
|
248
|
+
/* Temporary storage for remaining input. Brotli stream format is designed in
|
249
|
+
a way, that 64 bits are enough to make progress in decoding. */
|
114
250
|
union {
|
115
251
|
uint64_t u64;
|
116
252
|
uint8_t u8[8];
|
@@ -125,7 +261,6 @@ struct BrotliDecoderStateStruct {
|
|
125
261
|
int dist_rb_idx;
|
126
262
|
int dist_rb[4];
|
127
263
|
int error_code;
|
128
|
-
uint32_t sub_loop_counter;
|
129
264
|
uint8_t* ringbuffer;
|
130
265
|
uint8_t* ringbuffer_end;
|
131
266
|
HuffmanCode* htree_command;
|
@@ -153,13 +288,10 @@ struct BrotliDecoderStateStruct {
|
|
153
288
|
uint32_t block_type_rb[6];
|
154
289
|
uint32_t distance_postfix_bits;
|
155
290
|
uint32_t num_direct_distance_codes;
|
156
|
-
int distance_postfix_mask;
|
157
291
|
uint32_t num_dist_htrees;
|
158
292
|
uint8_t* dist_context_map;
|
159
293
|
HuffmanCode* literal_htree;
|
160
294
|
uint8_t dist_htree_index;
|
161
|
-
uint32_t repeat_code_len;
|
162
|
-
uint32_t prev_code_len;
|
163
295
|
|
164
296
|
int copy_length;
|
165
297
|
int distance_code;
|
@@ -168,33 +300,6 @@ struct BrotliDecoderStateStruct {
|
|
168
300
|
size_t rb_roundtrips; /* how many times we went around the ring-buffer */
|
169
301
|
size_t partial_pos_out; /* how much output to the user in total */
|
170
302
|
|
171
|
-
/* For ReadHuffmanCode. */
|
172
|
-
uint32_t symbol;
|
173
|
-
uint32_t repeat;
|
174
|
-
uint32_t space;
|
175
|
-
|
176
|
-
HuffmanCode table[32];
|
177
|
-
/* List of heads of symbol chains. */
|
178
|
-
uint16_t* symbol_lists;
|
179
|
-
/* Storage from symbol_lists. */
|
180
|
-
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
|
181
|
-
BROTLI_NUM_COMMAND_SYMBOLS];
|
182
|
-
/* Tails of symbol chains. */
|
183
|
-
int next_symbol[32];
|
184
|
-
uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
|
185
|
-
/* Population counts for the code lengths. */
|
186
|
-
uint16_t code_length_histo[16];
|
187
|
-
|
188
|
-
/* For HuffmanTreeGroupDecode. */
|
189
|
-
int htree_index;
|
190
|
-
HuffmanCode* next;
|
191
|
-
|
192
|
-
/* For DecodeContextMap. */
|
193
|
-
uint32_t context_index;
|
194
|
-
uint32_t max_run_length_prefix;
|
195
|
-
uint32_t code;
|
196
|
-
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
|
197
|
-
|
198
303
|
/* For InverseMoveToFrontTransform. */
|
199
304
|
uint32_t mtf_upper_bound;
|
200
305
|
uint32_t mtf[64 + 1];
|
@@ -203,10 +308,7 @@ struct BrotliDecoderStateStruct {
|
|
203
308
|
|
204
309
|
/* States inside function calls. */
|
205
310
|
BrotliRunningMetablockHeaderState substate_metablock_header;
|
206
|
-
BrotliRunningTreeGroupState substate_tree_group;
|
207
|
-
BrotliRunningContextMapState substate_context_map;
|
208
311
|
BrotliRunningUncompressedState substate_uncompressed;
|
209
|
-
BrotliRunningHuffmanState substate_huffman;
|
210
312
|
BrotliRunningDecodeUint8State substate_decode_uint8;
|
211
313
|
BrotliRunningReadBlockLengthState substate_read_block_length;
|
212
314
|
|
@@ -229,6 +331,11 @@ struct BrotliDecoderStateStruct {
|
|
229
331
|
const BrotliTransforms* transforms;
|
230
332
|
|
231
333
|
uint32_t trivial_literal_contexts[8]; /* 256 bits */
|
334
|
+
|
335
|
+
union {
|
336
|
+
BrotliMetablockHeaderArena header;
|
337
|
+
BrotliMetablockBodyArena body;
|
338
|
+
} arena;
|
232
339
|
};
|
233
340
|
|
234
341
|
typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
|
@@ -241,8 +348,8 @@ BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
|
|
241
348
|
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
|
242
349
|
BrotliDecoderState* s);
|
243
350
|
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
|
244
|
-
BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t
|
245
|
-
uint32_t
|
351
|
+
BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max,
|
352
|
+
uint32_t alphabet_size_limit, uint32_t ntrees);
|
246
353
|
|
247
354
|
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
248
355
|
|
@@ -9,6 +9,7 @@
|
|
9
9
|
#include "./backward_references.h"
|
10
10
|
|
11
11
|
#include "../common/constants.h"
|
12
|
+
#include "../common/context.h"
|
12
13
|
#include "../common/dictionary.h"
|
13
14
|
#include "../common/platform.h"
|
14
15
|
#include <brotli/types.h>
|
@@ -119,17 +120,17 @@ static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance,
|
|
119
120
|
#undef CAT
|
120
121
|
#undef EXPAND_CAT
|
121
122
|
|
122
|
-
void BrotliCreateBackwardReferences(
|
123
|
-
size_t
|
124
|
-
|
125
|
-
|
123
|
+
void BrotliCreateBackwardReferences(size_t num_bytes,
|
124
|
+
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
125
|
+
ContextLut literal_context_lut, const BrotliEncoderParams* params,
|
126
|
+
Hasher* hasher, int* dist_cache, size_t* last_insert_len,
|
126
127
|
Command* commands, size_t* num_commands, size_t* num_literals) {
|
127
128
|
switch (params->hasher.type) {
|
128
129
|
#define CASE_(N) \
|
129
130
|
case N: \
|
130
|
-
CreateBackwardReferencesNH ## N(
|
131
|
-
|
132
|
-
|
131
|
+
CreateBackwardReferencesNH ## N(num_bytes, \
|
132
|
+
position, ringbuffer, ringbuffer_mask, \
|
133
|
+
literal_context_lut, params, hasher, dist_cache, \
|
133
134
|
last_insert_len, commands, num_commands, num_literals); \
|
134
135
|
return;
|
135
136
|
FOR_GENERIC_HASHERS(CASE_)
|
@@ -10,6 +10,7 @@
|
|
10
10
|
#define BROTLI_ENC_BACKWARD_REFERENCES_H_
|
11
11
|
|
12
12
|
#include "../common/constants.h"
|
13
|
+
#include "../common/context.h"
|
13
14
|
#include "../common/dictionary.h"
|
14
15
|
#include "../common/platform.h"
|
15
16
|
#include <brotli/types.h>
|
@@ -25,10 +26,10 @@ extern "C" {
|
|
25
26
|
initially the total amount of commands output by previous
|
26
27
|
CreateBackwardReferences calls, and must be incremented by the amount written
|
27
28
|
by this call. */
|
28
|
-
BROTLI_INTERNAL void BrotliCreateBackwardReferences(
|
29
|
-
size_t
|
30
|
-
|
31
|
-
|
29
|
+
BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes,
|
30
|
+
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
31
|
+
ContextLut literal_context_lut, const BrotliEncoderParams* params,
|
32
|
+
Hasher* hasher, int* dist_cache, size_t* last_insert_len,
|
32
33
|
Command* commands, size_t* num_commands, size_t* num_literals);
|
33
34
|
|
34
35
|
#if defined(__cplusplus) || defined(c_plusplus)
|
@@ -11,6 +11,7 @@
|
|
11
11
|
#include <string.h> /* memcpy, memset */
|
12
12
|
|
13
13
|
#include "../common/constants.h"
|
14
|
+
#include "../common/context.h"
|
14
15
|
#include "../common/platform.h"
|
15
16
|
#include <brotli/types.h>
|
16
17
|
#include "./command.h"
|
@@ -26,6 +27,7 @@
|
|
26
27
|
extern "C" {
|
27
28
|
#endif
|
28
29
|
|
30
|
+
/* BrotliCalculateDistanceCodeLimit(BROTLI_MAX_ALLOWED_DISTANCE, 3, 120). */
|
29
31
|
#define BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE 544
|
30
32
|
|
31
33
|
static const float kInfinity = 1.7e38f; /* ~= 2 ^ 127 */
|
@@ -86,14 +88,10 @@ typedef struct ZopfliCostModel {
|
|
86
88
|
static void InitZopfliCostModel(
|
87
89
|
MemoryManager* m, ZopfliCostModel* self, const BrotliDistanceParams* dist,
|
88
90
|
size_t num_bytes) {
|
89
|
-
uint32_t distance_histogram_size = dist->alphabet_size;
|
90
|
-
if (distance_histogram_size > BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE) {
|
91
|
-
distance_histogram_size = BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE;
|
92
|
-
}
|
93
91
|
self->num_bytes_ = num_bytes;
|
94
92
|
self->literal_costs_ = BROTLI_ALLOC(m, float, num_bytes + 2);
|
95
|
-
self->cost_dist_ = BROTLI_ALLOC(m, float, dist->
|
96
|
-
self->distance_histogram_size =
|
93
|
+
self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size_limit);
|
94
|
+
self->distance_histogram_size = dist->alphabet_size_limit;
|
97
95
|
if (BROTLI_IS_OOM(m)) return;
|
98
96
|
}
|
99
97
|
|
@@ -408,9 +406,12 @@ static size_t UpdateNodes(
|
|
408
406
|
const int* starting_dist_cache, const size_t num_matches,
|
409
407
|
const BackwardMatch* matches, const ZopfliCostModel* model,
|
410
408
|
StartPosQueue* queue, ZopfliNode* nodes) {
|
409
|
+
const size_t stream_offset = params->stream_offset;
|
411
410
|
const size_t cur_ix = block_start + pos;
|
412
411
|
const size_t cur_ix_masked = cur_ix & ringbuffer_mask;
|
413
412
|
const size_t max_distance = BROTLI_MIN(size_t, cur_ix, max_backward_limit);
|
413
|
+
const size_t dictionary_start = BROTLI_MIN(size_t,
|
414
|
+
cur_ix + stream_offset, max_backward_limit);
|
414
415
|
const size_t max_len = num_bytes - pos;
|
415
416
|
const size_t max_zopfli_len = MaxZopfliLen(params);
|
416
417
|
const size_t max_iters = MaxZopfliCandidates(params);
|
@@ -419,8 +420,8 @@ static size_t UpdateNodes(
|
|
419
420
|
size_t k;
|
420
421
|
size_t gap = 0;
|
421
422
|
|
422
|
-
EvaluateNode(block_start, pos, max_backward_limit, gap,
|
423
|
-
model, queue, nodes);
|
423
|
+
EvaluateNode(block_start + stream_offset, pos, max_backward_limit, gap,
|
424
|
+
starting_dist_cache, model, queue, nodes);
|
424
425
|
|
425
426
|
{
|
426
427
|
const PosData* posdata = StartPosQueueAt(queue, 0);
|
@@ -453,7 +454,7 @@ static size_t UpdateNodes(
|
|
453
454
|
if (cur_ix_masked + best_len > ringbuffer_mask) {
|
454
455
|
break;
|
455
456
|
}
|
456
|
-
if (BROTLI_PREDICT_FALSE(backward >
|
457
|
+
if (BROTLI_PREDICT_FALSE(backward > dictionary_start + gap)) {
|
457
458
|
/* Word dictionary -> ignore. */
|
458
459
|
continue;
|
459
460
|
}
|
@@ -472,6 +473,8 @@ static size_t UpdateNodes(
|
|
472
473
|
&ringbuffer[cur_ix_masked],
|
473
474
|
max_len);
|
474
475
|
} else {
|
476
|
+
/* "Gray" area. It is addressable by decoder, but this encoder
|
477
|
+
instance does not have that data -> should not touch it. */
|
475
478
|
continue;
|
476
479
|
}
|
477
480
|
{
|
@@ -506,7 +509,7 @@ static size_t UpdateNodes(
|
|
506
509
|
BackwardMatch match = matches[j];
|
507
510
|
size_t dist = match.distance;
|
508
511
|
BROTLI_BOOL is_dictionary_match =
|
509
|
-
TO_BROTLI_BOOL(dist >
|
512
|
+
TO_BROTLI_BOOL(dist > dictionary_start + gap);
|
510
513
|
/* We already tried all possible last distance matches, so we can use
|
511
514
|
normal distance code here. */
|
512
515
|
size_t dist_code = dist + BROTLI_NUM_DISTANCE_SHORT_CODES - 1;
|
@@ -569,6 +572,7 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
|
|
569
572
|
const size_t block_start, const ZopfliNode* nodes, int* dist_cache,
|
570
573
|
size_t* last_insert_len, const BrotliEncoderParams* params,
|
571
574
|
Command* commands, size_t* num_literals) {
|
575
|
+
const size_t stream_offset = params->stream_offset;
|
572
576
|
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
573
577
|
size_t pos = 0;
|
574
578
|
uint32_t offset = nodes[0].u.next;
|
@@ -587,9 +591,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
|
|
587
591
|
{
|
588
592
|
size_t distance = ZopfliNodeCopyDistance(next);
|
589
593
|
size_t len_code = ZopfliNodeLengthCode(next);
|
590
|
-
size_t
|
591
|
-
|
592
|
-
BROTLI_BOOL is_dictionary =
|
594
|
+
size_t dictionary_start = BROTLI_MIN(size_t,
|
595
|
+
block_start + pos + stream_offset, max_backward_limit);
|
596
|
+
BROTLI_BOOL is_dictionary =
|
597
|
+
TO_BROTLI_BOOL(distance > dictionary_start + gap);
|
593
598
|
size_t dist_code = ZopfliNodeDistanceCode(next);
|
594
599
|
InitCommand(&commands[i], ¶ms->dist, insert_length,
|
595
600
|
copy_length, (int)len_code - (int)copy_length, dist_code);
|
@@ -613,6 +618,7 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position,
|
|
613
618
|
const BrotliEncoderParams* params, const size_t gap, const int* dist_cache,
|
614
619
|
const ZopfliCostModel* model, const uint32_t* num_matches,
|
615
620
|
const BackwardMatch* matches, ZopfliNode* nodes) {
|
621
|
+
const size_t stream_offset = params->stream_offset;
|
616
622
|
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
617
623
|
const size_t max_zopfli_len = MaxZopfliLen(params);
|
618
624
|
StartPosQueue queue;
|
@@ -637,7 +643,7 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position,
|
|
637
643
|
while (skip) {
|
638
644
|
i++;
|
639
645
|
if (i + 3 >= num_bytes) break;
|
640
|
-
EvaluateNode(position, i, max_backward_limit, gap,
|
646
|
+
EvaluateNode(position + stream_offset, i, max_backward_limit, gap,
|
641
647
|
dist_cache, model, &queue, nodes);
|
642
648
|
cur_match_pos += num_matches[i];
|
643
649
|
skip--;
|
@@ -650,8 +656,9 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position,
|
|
650
656
|
/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
|
651
657
|
size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
|
652
658
|
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
653
|
-
const BrotliEncoderParams* params,
|
654
|
-
const int* dist_cache,
|
659
|
+
ContextLut literal_context_lut, const BrotliEncoderParams* params,
|
660
|
+
const int* dist_cache, Hasher* hasher, ZopfliNode* nodes) {
|
661
|
+
const size_t stream_offset = params->stream_offset;
|
655
662
|
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
656
663
|
const size_t max_zopfli_len = MaxZopfliLen(params);
|
657
664
|
ZopfliCostModel model;
|
@@ -662,6 +669,7 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
|
|
662
669
|
size_t i;
|
663
670
|
size_t gap = 0;
|
664
671
|
size_t lz_matches_offset = 0;
|
672
|
+
BROTLI_UNUSED(literal_context_lut);
|
665
673
|
nodes[0].length = 0;
|
666
674
|
nodes[0].u.cost = 0;
|
667
675
|
InitZopfliCostModel(m, &model, ¶ms->dist, num_bytes);
|
@@ -672,12 +680,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
|
|
672
680
|
for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) {
|
673
681
|
const size_t pos = position + i;
|
674
682
|
const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
|
683
|
+
const size_t dictionary_start = BROTLI_MIN(size_t,
|
684
|
+
pos + stream_offset, max_backward_limit);
|
675
685
|
size_t skip;
|
676
686
|
size_t num_matches;
|
677
|
-
num_matches = FindAllMatchesH10(hasher,
|
687
|
+
num_matches = FindAllMatchesH10(&hasher->privat._H10,
|
678
688
|
¶ms->dictionary,
|
679
689
|
ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance,
|
680
|
-
gap, params, &matches[lz_matches_offset]);
|
690
|
+
dictionary_start + gap, params, &matches[lz_matches_offset]);
|
681
691
|
if (num_matches > 0 &&
|
682
692
|
BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) {
|
683
693
|
matches[0] = matches[num_matches - 1];
|
@@ -692,13 +702,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
|
|
692
702
|
}
|
693
703
|
if (skip > 1) {
|
694
704
|
/* Add the tail of the copy to the hasher. */
|
695
|
-
StoreRangeH10(hasher,
|
705
|
+
StoreRangeH10(&hasher->privat._H10,
|
706
|
+
ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN(
|
696
707
|
size_t, pos + skip, store_end));
|
697
708
|
skip--;
|
698
709
|
while (skip) {
|
699
710
|
i++;
|
700
711
|
if (i + HashTypeLengthH10() - 1 >= num_bytes) break;
|
701
|
-
EvaluateNode(position, i, max_backward_limit, gap,
|
712
|
+
EvaluateNode(position + stream_offset, i, max_backward_limit, gap,
|
702
713
|
dist_cache, &model, &queue, nodes);
|
703
714
|
skip--;
|
704
715
|
}
|
@@ -710,15 +721,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
|
|
710
721
|
|
711
722
|
void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
712
723
|
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
713
|
-
const BrotliEncoderParams* params,
|
714
|
-
|
724
|
+
ContextLut literal_context_lut, const BrotliEncoderParams* params,
|
725
|
+
Hasher* hasher, int* dist_cache, size_t* last_insert_len,
|
715
726
|
Command* commands, size_t* num_commands, size_t* num_literals) {
|
716
|
-
ZopfliNode* nodes;
|
717
|
-
|
718
|
-
if (BROTLI_IS_OOM(m)) return;
|
727
|
+
ZopfliNode* nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
|
728
|
+
if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) return;
|
719
729
|
BrotliInitZopfliNodes(nodes, num_bytes + 1);
|
720
730
|
*num_commands += BrotliZopfliComputeShortestPath(m, num_bytes,
|
721
|
-
position, ringbuffer, ringbuffer_mask, params,
|
731
|
+
position, ringbuffer, ringbuffer_mask, literal_context_lut, params,
|
722
732
|
dist_cache, hasher, nodes);
|
723
733
|
if (BROTLI_IS_OOM(m)) return;
|
724
734
|
BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache,
|
@@ -728,9 +738,10 @@ void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
|
728
738
|
|
729
739
|
void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
730
740
|
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
731
|
-
const BrotliEncoderParams* params,
|
732
|
-
|
741
|
+
ContextLut literal_context_lut, const BrotliEncoderParams* params,
|
742
|
+
Hasher* hasher, int* dist_cache, size_t* last_insert_len,
|
733
743
|
Command* commands, size_t* num_commands, size_t* num_literals) {
|
744
|
+
const size_t stream_offset = params->stream_offset;
|
734
745
|
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
735
746
|
uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes);
|
736
747
|
size_t matches_size = 4 * num_bytes;
|
@@ -747,10 +758,16 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
|
747
758
|
BackwardMatch* matches = BROTLI_ALLOC(m, BackwardMatch, matches_size);
|
748
759
|
size_t gap = 0;
|
749
760
|
size_t shadow_matches = 0;
|
750
|
-
|
761
|
+
BROTLI_UNUSED(literal_context_lut);
|
762
|
+
if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(num_matches) ||
|
763
|
+
BROTLI_IS_NULL(matches)) {
|
764
|
+
return;
|
765
|
+
}
|
751
766
|
for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; ++i) {
|
752
767
|
const size_t pos = position + i;
|
753
768
|
size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
|
769
|
+
size_t dictionary_start = BROTLI_MIN(size_t,
|
770
|
+
pos + stream_offset, max_backward_limit);
|
754
771
|
size_t max_length = num_bytes - i;
|
755
772
|
size_t num_found_matches;
|
756
773
|
size_t cur_match_end;
|
@@ -759,10 +776,10 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
|
759
776
|
BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size,
|
760
777
|
cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches);
|
761
778
|
if (BROTLI_IS_OOM(m)) return;
|
762
|
-
num_found_matches = FindAllMatchesH10(hasher,
|
779
|
+
num_found_matches = FindAllMatchesH10(&hasher->privat._H10,
|
763
780
|
¶ms->dictionary,
|
764
781
|
ringbuffer, ringbuffer_mask, pos, max_length,
|
765
|
-
max_distance, gap, params,
|
782
|
+
max_distance, dictionary_start + gap, params,
|
766
783
|
&matches[cur_match_pos + shadow_matches]);
|
767
784
|
cur_match_end = cur_match_pos + num_found_matches;
|
768
785
|
for (j = cur_match_pos; j + 1 < cur_match_end; ++j) {
|
@@ -777,7 +794,8 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
|
777
794
|
matches[cur_match_pos++] = matches[cur_match_end - 1];
|
778
795
|
num_matches[i] = 1;
|
779
796
|
/* Add the tail of the copy to the hasher. */
|
780
|
-
StoreRangeH10(hasher,
|
797
|
+
StoreRangeH10(&hasher->privat._H10,
|
798
|
+
ringbuffer, ringbuffer_mask, pos + 1,
|
781
799
|
BROTLI_MIN(size_t, pos + match_len, store_end));
|
782
800
|
memset(&num_matches[i + 1], 0, skip * sizeof(num_matches[0]));
|
783
801
|
i += skip;
|
@@ -791,7 +809,7 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
|
791
809
|
memcpy(orig_dist_cache, dist_cache, 4 * sizeof(dist_cache[0]));
|
792
810
|
orig_num_commands = *num_commands;
|
793
811
|
nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
|
794
|
-
if (BROTLI_IS_OOM(m)) return;
|
812
|
+
if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) return;
|
795
813
|
InitZopfliCostModel(m, &model, ¶ms->dist, num_bytes);
|
796
814
|
if (BROTLI_IS_OOM(m)) return;
|
797
815
|
for (i = 0; i < 2; i++) {
|