brotli 0.2.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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++) {
|