brotli 0.2.3 → 0.5.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 +37 -0
- data/.github/workflows/publish.yml +24 -0
- data/.gitmodules +1 -1
- data/Gemfile +6 -3
- data/README.md +2 -2
- data/Rakefile +16 -9
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +210 -31
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +25 -17
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +107 -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 +137 -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 +14 -3
- data/vendor/brotli/c/common/platform.c +23 -0
- data/vendor/brotli/c/common/platform.h +95 -122
- data/vendor/brotli/c/common/shared_dictionary.c +521 -0
- data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
- data/vendor/brotli/c/common/transform.c +60 -4
- data/vendor/brotli/c/common/transform.h +5 -0
- data/vendor/brotli/c/common/version.h +31 -6
- data/vendor/brotli/c/dec/bit_reader.c +34 -4
- data/vendor/brotli/c/dec/bit_reader.h +221 -107
- data/vendor/brotli/c/dec/decode.c +772 -403
- data/vendor/brotli/c/dec/huffman.c +7 -4
- data/vendor/brotli/c/dec/huffman.h +8 -13
- data/vendor/brotli/c/dec/prefix.h +1 -18
- data/vendor/brotli/c/dec/state.c +40 -21
- data/vendor/brotli/c/dec/state.h +201 -59
- data/vendor/brotli/c/enc/backward_references.c +88 -25
- data/vendor/brotli/c/enc/backward_references.h +10 -8
- data/vendor/brotli/c/enc/backward_references_hq.c +194 -80
- data/vendor/brotli/c/enc/backward_references_hq.h +17 -13
- data/vendor/brotli/c/enc/backward_references_inc.h +52 -16
- data/vendor/brotli/c/enc/bit_cost.c +8 -7
- data/vendor/brotli/c/enc/bit_cost.h +5 -4
- data/vendor/brotli/c/enc/block_splitter.c +40 -17
- data/vendor/brotli/c/enc/block_splitter.h +5 -4
- data/vendor/brotli/c/enc/block_splitter_inc.h +99 -49
- data/vendor/brotli/c/enc/brotli_bit_stream.c +142 -137
- data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
- data/vendor/brotli/c/enc/cluster.c +10 -9
- data/vendor/brotli/c/enc/cluster.h +7 -6
- data/vendor/brotli/c/enc/cluster_inc.h +30 -22
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +17 -16
- data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
- data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
- data/vendor/brotli/c/enc/compress_fragment.c +93 -83
- data/vendor/brotli/c/enc/compress_fragment.h +32 -7
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +100 -88
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +1829 -1101
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +550 -416
- data/vendor/brotli/c/enc/encoder_dict.c +613 -5
- data/vendor/brotli/c/enc/encoder_dict.h +120 -4
- data/vendor/brotli/c/enc/entropy_encode.c +5 -2
- data/vendor/brotli/c/enc/entropy_encode.h +4 -3
- data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +21 -101
- data/vendor/brotli/c/enc/find_match_length.h +17 -25
- data/vendor/brotli/c/enc/hash.h +350 -120
- data/vendor/brotli/c/enc/hash_composite_inc.h +71 -67
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +92 -51
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +79 -84
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -54
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +93 -62
- data/vendor/brotli/c/enc/hash_rolling_inc.h +25 -29
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +42 -40
- data/vendor/brotli/c/enc/histogram.c +4 -4
- data/vendor/brotli/c/enc/histogram.h +7 -6
- data/vendor/brotli/c/enc/literal_cost.c +20 -15
- data/vendor/brotli/c/enc/literal_cost.h +4 -2
- data/vendor/brotli/c/enc/memory.c +29 -5
- data/vendor/brotli/c/enc/memory.h +43 -14
- data/vendor/brotli/c/enc/metablock.c +95 -85
- data/vendor/brotli/c/enc/metablock.h +9 -8
- data/vendor/brotli/c/enc/metablock_inc.h +9 -7
- data/vendor/brotli/c/enc/params.h +7 -4
- data/vendor/brotli/c/enc/prefix.h +3 -2
- data/vendor/brotli/c/enc/quality.h +40 -3
- data/vendor/brotli/c/enc/ringbuffer.h +8 -4
- data/vendor/brotli/c/enc/state.h +104 -0
- data/vendor/brotli/c/enc/static_dict.c +60 -4
- data/vendor/brotli/c/enc/static_dict.h +3 -2
- data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
- data/vendor/brotli/c/enc/utf8_util.c +2 -2
- data/vendor/brotli/c/enc/utf8_util.h +2 -1
- data/vendor/brotli/c/enc/write_bits.h +29 -26
- data/vendor/brotli/c/include/brotli/decode.h +67 -2
- data/vendor/brotli/c/include/brotli/encode.h +77 -3
- data/vendor/brotli/c/include/brotli/port.h +34 -3
- data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
- metadata +23 -97
- data/.travis.yml +0 -31
- data/docs/Brotli/Error.html +0 -124
- data/docs/Brotli.html +0 -485
- 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
@@ -6,13 +6,14 @@
|
|
6
6
|
|
7
7
|
/* Utilities for building Huffman decoding tables. */
|
8
8
|
|
9
|
-
#include "
|
9
|
+
#include "huffman.h"
|
10
10
|
|
11
11
|
#include <string.h> /* memcpy, memset */
|
12
12
|
|
13
|
+
#include <brotli/types.h>
|
14
|
+
|
13
15
|
#include "../common/constants.h"
|
14
16
|
#include "../common/platform.h"
|
15
|
-
#include <brotli/types.h>
|
16
17
|
|
17
18
|
#if defined(__cplusplus) || defined(c_plusplus)
|
18
19
|
extern "C" {
|
@@ -117,11 +118,13 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
|
117
118
|
int bits_count;
|
118
119
|
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
|
119
120
|
BROTLI_REVERSE_BITS_MAX);
|
121
|
+
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5);
|
120
122
|
|
121
123
|
/* Generate offsets into sorted symbol table by code length. */
|
122
124
|
symbol = -1;
|
123
125
|
bits = 1;
|
124
|
-
|
126
|
+
/* BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5 */
|
127
|
+
BROTLI_REPEAT_5({
|
125
128
|
symbol += count[bits];
|
126
129
|
offset[bits] = symbol;
|
127
130
|
bits++;
|
@@ -132,7 +135,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
|
132
135
|
/* Sort symbols by length, by symbol order within each length. */
|
133
136
|
symbol = BROTLI_CODE_LENGTH_CODES;
|
134
137
|
do {
|
135
|
-
|
138
|
+
BROTLI_REPEAT_6({
|
136
139
|
symbol--;
|
137
140
|
sorted[offset[code_lengths[symbol]]--] = symbol;
|
138
141
|
});
|
@@ -9,21 +9,16 @@
|
|
9
9
|
#ifndef BROTLI_DEC_HUFFMAN_H_
|
10
10
|
#define BROTLI_DEC_HUFFMAN_H_
|
11
11
|
|
12
|
-
#include "../common/platform.h"
|
13
12
|
#include <brotli/types.h>
|
14
13
|
|
14
|
+
#include "../common/platform.h"
|
15
|
+
|
15
16
|
#if defined(__cplusplus) || defined(c_plusplus)
|
16
17
|
extern "C" {
|
17
18
|
#endif
|
18
19
|
|
19
20
|
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
|
20
21
|
|
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
22
|
/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */
|
28
23
|
#define BROTLI_HUFFMAN_MAX_SIZE_26 396
|
29
24
|
/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
|
@@ -82,7 +77,7 @@ typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
|
|
82
77
|
|
83
78
|
static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
|
84
79
|
const uint16_t value) {
|
85
|
-
return ((value & 0xFFFF) << 16) | (bits & 0xFF);
|
80
|
+
return (HuffmanCode) ((value & 0xFFFF) << 16) | (bits & 0xFF);
|
86
81
|
}
|
87
82
|
|
88
83
|
#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
|
@@ -100,7 +95,7 @@ BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
|
|
100
95
|
/* Builds Huffman lookup table assuming code lengths are in symbol order.
|
101
96
|
Returns size of resulting table. */
|
102
97
|
BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
103
|
-
int root_bits, const uint16_t* const symbol_lists, uint16_t*
|
98
|
+
int root_bits, const uint16_t* const symbol_lists, uint16_t* count);
|
104
99
|
|
105
100
|
/* Builds a simple Huffman table. The |num_symbols| parameter is to be
|
106
101
|
interpreted as follows: 0 means 1 symbol, 1 means 2 symbols,
|
@@ -110,13 +105,13 @@ BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
|
110
105
|
int root_bits, uint16_t* symbols, uint32_t num_symbols);
|
111
106
|
|
112
107
|
/* Contains a collection of Huffman trees with the same alphabet size. */
|
113
|
-
/*
|
114
|
-
greater than log2(
|
108
|
+
/* alphabet_size_limit is needed due to simple codes, since
|
109
|
+
log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */
|
115
110
|
typedef struct {
|
116
111
|
HuffmanCode** htrees;
|
117
112
|
HuffmanCode* codes;
|
118
|
-
uint16_t
|
119
|
-
uint16_t
|
113
|
+
uint16_t alphabet_size_max;
|
114
|
+
uint16_t alphabet_size_limit;
|
120
115
|
uint16_t num_htrees;
|
121
116
|
} HuffmanTreeGroup;
|
122
117
|
|
@@ -10,26 +10,9 @@
|
|
10
10
|
#ifndef BROTLI_DEC_PREFIX_H_
|
11
11
|
#define BROTLI_DEC_PREFIX_H_
|
12
12
|
|
13
|
-
#include "../common/constants.h"
|
14
13
|
#include <brotli/types.h>
|
15
14
|
|
16
|
-
|
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
|
-
};
|
15
|
+
#include "../common/constants.h"
|
33
16
|
|
34
17
|
typedef struct CmdLutElement {
|
35
18
|
uint8_t insert_len_extra_bits;
|
data/vendor/brotli/c/dec/state.c
CHANGED
@@ -4,12 +4,14 @@
|
|
4
4
|
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
5
5
|
*/
|
6
6
|
|
7
|
-
#include "
|
7
|
+
#include "state.h"
|
8
8
|
|
9
9
|
#include <stdlib.h> /* free, malloc */
|
10
10
|
|
11
11
|
#include <brotli/types.h>
|
12
|
-
|
12
|
+
|
13
|
+
#include "../common/dictionary.h"
|
14
|
+
#include "huffman.h"
|
13
15
|
|
14
16
|
#if defined(__cplusplus) || defined(c_plusplus)
|
15
17
|
extern "C" {
|
@@ -33,10 +35,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
33
35
|
s->state = BROTLI_STATE_UNINITED;
|
34
36
|
s->large_window = 0;
|
35
37
|
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
38
|
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
|
39
|
-
s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
|
40
39
|
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
|
41
40
|
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
|
42
41
|
|
@@ -45,6 +44,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
45
44
|
s->pos = 0;
|
46
45
|
s->rb_roundtrips = 0;
|
47
46
|
s->partial_pos_out = 0;
|
47
|
+
s->used_input = 0;
|
48
48
|
|
49
49
|
s->block_type_trees = NULL;
|
50
50
|
s->block_len_trees = NULL;
|
@@ -59,8 +59,6 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
59
59
|
s->context_map_slice = NULL;
|
60
60
|
s->dist_context_map_slice = NULL;
|
61
61
|
|
62
|
-
s->sub_loop_counter = 0;
|
63
|
-
|
64
62
|
s->literal_hgroup.codes = NULL;
|
65
63
|
s->literal_hgroup.htrees = NULL;
|
66
64
|
s->insert_copy_hgroup.codes = NULL;
|
@@ -84,22 +82,25 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
|
84
82
|
s->block_type_trees = NULL;
|
85
83
|
s->block_len_trees = NULL;
|
86
84
|
|
87
|
-
/* Make small negative indexes addressable. */
|
88
|
-
s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
|
89
|
-
|
90
85
|
s->mtf_upper_bound = 63;
|
91
86
|
|
92
|
-
s->
|
93
|
-
s->
|
87
|
+
s->compound_dictionary = NULL;
|
88
|
+
s->dictionary =
|
89
|
+
BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
|
90
|
+
if (!s->dictionary) return BROTLI_FALSE;
|
91
|
+
|
92
|
+
s->metadata_start_func = NULL;
|
93
|
+
s->metadata_chunk_func = NULL;
|
94
|
+
s->metadata_callback_opaque = 0;
|
94
95
|
|
95
96
|
return BROTLI_TRUE;
|
96
97
|
}
|
97
98
|
|
98
99
|
void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
|
99
100
|
s->meta_block_remaining_len = 0;
|
100
|
-
s->block_length[0] =
|
101
|
-
s->block_length[1] =
|
102
|
-
s->block_length[2] =
|
101
|
+
s->block_length[0] = BROTLI_BLOCK_SIZE_CAP;
|
102
|
+
s->block_length[1] = BROTLI_BLOCK_SIZE_CAP;
|
103
|
+
s->block_length[2] = BROTLI_BLOCK_SIZE_CAP;
|
103
104
|
s->num_block_types[0] = 1;
|
104
105
|
s->num_block_types[1] = 1;
|
105
106
|
s->num_block_types[2] = 1;
|
@@ -134,25 +135,43 @@ void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
|
|
134
135
|
BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
|
135
136
|
}
|
136
137
|
|
138
|
+
#ifdef BROTLI_REPORTING
|
139
|
+
/* When BROTLI_REPORTING is defined extra reporting module have to be linked. */
|
140
|
+
void BrotliDecoderOnFinish(const BrotliDecoderState* s);
|
141
|
+
#define BROTLI_DECODER_ON_FINISH(s) BrotliDecoderOnFinish(s);
|
142
|
+
#else
|
143
|
+
#if !defined(BROTLI_DECODER_ON_FINISH)
|
144
|
+
#define BROTLI_DECODER_ON_FINISH(s) (void)(s);
|
145
|
+
#endif
|
146
|
+
#endif
|
147
|
+
|
137
148
|
void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
|
138
149
|
BrotliDecoderStateCleanupAfterMetablock(s);
|
139
150
|
|
151
|
+
BROTLI_DECODER_ON_FINISH(s);
|
152
|
+
|
153
|
+
BROTLI_DECODER_FREE(s, s->compound_dictionary);
|
154
|
+
BrotliSharedDictionaryDestroyInstance(s->dictionary);
|
155
|
+
s->dictionary = NULL;
|
140
156
|
BROTLI_DECODER_FREE(s, s->ringbuffer);
|
141
157
|
BROTLI_DECODER_FREE(s, s->block_type_trees);
|
142
158
|
}
|
143
159
|
|
144
160
|
BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
|
145
|
-
HuffmanTreeGroup* group,
|
146
|
-
|
147
|
-
/*
|
148
|
-
|
161
|
+
HuffmanTreeGroup* group, brotli_reg_t alphabet_size_max,
|
162
|
+
brotli_reg_t alphabet_size_limit, brotli_reg_t ntrees) {
|
163
|
+
/* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
|
164
|
+
This number is discovered "unlimited" "enough" calculator; it is actually
|
165
|
+
a wee bigger than required in several cases (especially for alphabets with
|
166
|
+
less than 16 symbols). */
|
167
|
+
const size_t max_table_size = alphabet_size_limit + 376;
|
149
168
|
const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
|
150
169
|
const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
|
151
170
|
/* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
|
152
171
|
HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
|
153
172
|
code_size + htree_size);
|
154
|
-
group->
|
155
|
-
group->
|
173
|
+
group->alphabet_size_max = (uint16_t)alphabet_size_max;
|
174
|
+
group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
|
156
175
|
group->num_htrees = (uint16_t)ntrees;
|
157
176
|
group->htrees = p;
|
158
177
|
group->codes = (HuffmanCode*)(&p[ntrees]);
|
data/vendor/brotli/c/dec/state.h
CHANGED
@@ -9,18 +9,110 @@
|
|
9
9
|
#ifndef BROTLI_DEC_STATE_H_
|
10
10
|
#define BROTLI_DEC_STATE_H_
|
11
11
|
|
12
|
+
#include <brotli/decode.h>
|
13
|
+
#include <brotli/shared_dictionary.h>
|
14
|
+
#include <brotli/types.h>
|
15
|
+
|
12
16
|
#include "../common/constants.h"
|
13
17
|
#include "../common/dictionary.h"
|
14
18
|
#include "../common/platform.h"
|
15
19
|
#include "../common/transform.h"
|
16
|
-
#include
|
17
|
-
#include "
|
18
|
-
#include "./huffman.h"
|
20
|
+
#include "bit_reader.h"
|
21
|
+
#include "huffman.h"
|
19
22
|
|
20
23
|
#if defined(__cplusplus) || defined(c_plusplus)
|
21
24
|
extern "C" {
|
22
25
|
#endif
|
23
26
|
|
27
|
+
/* Graphviz diagram that describes state transitions:
|
28
|
+
|
29
|
+
digraph States {
|
30
|
+
graph [compound=true]
|
31
|
+
concentrate=true
|
32
|
+
node [shape="box"]
|
33
|
+
|
34
|
+
UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
|
35
|
+
subgraph cluster_metablock_workflow {
|
36
|
+
style="rounded"
|
37
|
+
label=< <B>METABLOCK CYCLE</B> >
|
38
|
+
METABLOCK_BEGIN -> METABLOCK_HEADER
|
39
|
+
METABLOCK_HEADER:sw -> METADATA
|
40
|
+
METABLOCK_HEADER:s -> UNCOMPRESSED
|
41
|
+
METABLOCK_HEADER:se -> METABLOCK_DONE:ne
|
42
|
+
METADATA:s -> METABLOCK_DONE:w
|
43
|
+
UNCOMPRESSED:s -> METABLOCK_DONE:n
|
44
|
+
METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
|
45
|
+
}
|
46
|
+
INITIALIZE -> METABLOCK_BEGIN
|
47
|
+
METABLOCK_DONE -> DONE
|
48
|
+
|
49
|
+
subgraph cluster_compressed_metablock {
|
50
|
+
style="rounded"
|
51
|
+
label=< <B>COMPRESSED METABLOCK</B> >
|
52
|
+
|
53
|
+
subgraph cluster_command {
|
54
|
+
style="rounded"
|
55
|
+
label=< <B>HOT LOOP</B> >
|
56
|
+
|
57
|
+
_METABLOCK_DONE_PORT_ [shape=point style=invis]
|
58
|
+
|
59
|
+
{
|
60
|
+
// Set different shape for nodes returning from "compressed metablock".
|
61
|
+
node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
|
62
|
+
CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
|
63
|
+
}
|
64
|
+
|
65
|
+
CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
|
66
|
+
|
67
|
+
// IO ("write") nodes are not in the hot loop!
|
68
|
+
CMD_INNER_WRITE [style=dashed]
|
69
|
+
CMD_INNER -> CMD_INNER_WRITE
|
70
|
+
CMD_POST_WRITE_1 [style=dashed]
|
71
|
+
CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
|
72
|
+
CMD_POST_WRITE_2 [style=dashed]
|
73
|
+
CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
|
74
|
+
|
75
|
+
CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
|
76
|
+
CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
|
77
|
+
[constraint="false"]
|
78
|
+
CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
|
79
|
+
CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
|
80
|
+
CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
|
81
|
+
CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
|
82
|
+
{rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
|
83
|
+
CMD_POST_WRAP_COPY}
|
84
|
+
{rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
|
85
|
+
|
86
|
+
{CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
|
87
|
+
_METABLOCK_DONE_PORT_ [style=invis]
|
88
|
+
{CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
|
89
|
+
[constraint="false" style=invis]
|
90
|
+
}
|
91
|
+
|
92
|
+
BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
|
93
|
+
HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
|
94
|
+
HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
|
95
|
+
CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
|
96
|
+
TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
|
97
|
+
BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
|
98
|
+
|
99
|
+
HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
|
100
|
+
{rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
|
101
|
+
{rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
|
102
|
+
TREE_GROUP}
|
103
|
+
}
|
104
|
+
METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
|
105
|
+
|
106
|
+
_METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
|
107
|
+
[constraint="false" ltail=cluster_command]
|
108
|
+
|
109
|
+
UNINITED [shape=Mdiamond];
|
110
|
+
DONE [shape=Msquare];
|
111
|
+
}
|
112
|
+
|
113
|
+
|
114
|
+
*/
|
115
|
+
|
24
116
|
typedef enum {
|
25
117
|
BROTLI_STATE_UNINITED,
|
26
118
|
BROTLI_STATE_LARGE_WINDOW_BITS,
|
@@ -39,6 +131,7 @@ typedef enum {
|
|
39
131
|
BROTLI_STATE_METABLOCK_DONE,
|
40
132
|
BROTLI_STATE_COMMAND_POST_WRITE_1,
|
41
133
|
BROTLI_STATE_COMMAND_POST_WRITE_2,
|
134
|
+
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
|
42
135
|
BROTLI_STATE_HUFFMAN_CODE_0,
|
43
136
|
BROTLI_STATE_HUFFMAN_CODE_1,
|
44
137
|
BROTLI_STATE_HUFFMAN_CODE_2,
|
@@ -46,6 +139,7 @@ typedef enum {
|
|
46
139
|
BROTLI_STATE_CONTEXT_MAP_1,
|
47
140
|
BROTLI_STATE_CONTEXT_MAP_2,
|
48
141
|
BROTLI_STATE_TREE_GROUP,
|
142
|
+
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
|
49
143
|
BROTLI_STATE_DONE
|
50
144
|
} BrotliRunningState;
|
51
145
|
|
@@ -98,6 +192,65 @@ typedef enum {
|
|
98
192
|
BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
|
99
193
|
} BrotliRunningReadBlockLengthState;
|
100
194
|
|
195
|
+
/* BrotliDecoderState addon, used for Compound Dictionary functionality. */
|
196
|
+
typedef struct BrotliDecoderCompoundDictionary {
|
197
|
+
int num_chunks;
|
198
|
+
int total_size;
|
199
|
+
int br_index;
|
200
|
+
int br_offset;
|
201
|
+
int br_length;
|
202
|
+
int br_copied;
|
203
|
+
const uint8_t* chunks[16];
|
204
|
+
int chunk_offsets[16];
|
205
|
+
int block_bits;
|
206
|
+
uint8_t block_map[256];
|
207
|
+
} BrotliDecoderCompoundDictionary;
|
208
|
+
|
209
|
+
typedef struct BrotliMetablockHeaderArena {
|
210
|
+
BrotliRunningTreeGroupState substate_tree_group;
|
211
|
+
BrotliRunningContextMapState substate_context_map;
|
212
|
+
BrotliRunningHuffmanState substate_huffman;
|
213
|
+
|
214
|
+
brotli_reg_t sub_loop_counter;
|
215
|
+
|
216
|
+
brotli_reg_t repeat_code_len;
|
217
|
+
brotli_reg_t prev_code_len;
|
218
|
+
|
219
|
+
/* For ReadHuffmanCode. */
|
220
|
+
brotli_reg_t symbol;
|
221
|
+
brotli_reg_t repeat;
|
222
|
+
brotli_reg_t space;
|
223
|
+
|
224
|
+
/* Huffman table for "histograms". */
|
225
|
+
HuffmanCode table[32];
|
226
|
+
/* List of heads of symbol chains. */
|
227
|
+
uint16_t* symbol_lists;
|
228
|
+
/* Storage from symbol_lists. */
|
229
|
+
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
|
230
|
+
BROTLI_NUM_COMMAND_SYMBOLS];
|
231
|
+
/* Tails of symbol chains. */
|
232
|
+
int next_symbol[32];
|
233
|
+
uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
|
234
|
+
/* Population counts for the code lengths. */
|
235
|
+
uint16_t code_length_histo[16];
|
236
|
+
/* TODO(eustas): +2 bytes padding */
|
237
|
+
|
238
|
+
/* For HuffmanTreeGroupDecode. */
|
239
|
+
int htree_index;
|
240
|
+
HuffmanCode* next;
|
241
|
+
|
242
|
+
/* For DecodeContextMap. */
|
243
|
+
brotli_reg_t context_index;
|
244
|
+
brotli_reg_t max_run_length_prefix;
|
245
|
+
brotli_reg_t code;
|
246
|
+
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
|
247
|
+
} BrotliMetablockHeaderArena;
|
248
|
+
|
249
|
+
typedef struct BrotliMetablockBodyArena {
|
250
|
+
uint8_t dist_extra_bits[544];
|
251
|
+
brotli_reg_t dist_offset[544];
|
252
|
+
} BrotliMetablockBodyArena;
|
253
|
+
|
101
254
|
struct BrotliDecoderStateStruct {
|
102
255
|
BrotliRunningState state;
|
103
256
|
|
@@ -110,12 +263,13 @@ struct BrotliDecoderStateStruct {
|
|
110
263
|
brotli_free_func free_func;
|
111
264
|
void* memory_manager_opaque;
|
112
265
|
|
113
|
-
/* Temporary storage for remaining input.
|
266
|
+
/* Temporary storage for remaining input. Brotli stream format is designed in
|
267
|
+
a way, that 64 bits are enough to make progress in decoding. */
|
114
268
|
union {
|
115
269
|
uint64_t u64;
|
116
270
|
uint8_t u8[8];
|
117
271
|
} buffer;
|
118
|
-
|
272
|
+
brotli_reg_t buffer_length;
|
119
273
|
|
120
274
|
int pos;
|
121
275
|
int max_backward_distance;
|
@@ -125,7 +279,8 @@ struct BrotliDecoderStateStruct {
|
|
125
279
|
int dist_rb_idx;
|
126
280
|
int dist_rb[4];
|
127
281
|
int error_code;
|
128
|
-
|
282
|
+
int meta_block_remaining_len;
|
283
|
+
|
129
284
|
uint8_t* ringbuffer;
|
130
285
|
uint8_t* ringbuffer_end;
|
131
286
|
HuffmanCode* htree_command;
|
@@ -146,89 +301,71 @@ struct BrotliDecoderStateStruct {
|
|
146
301
|
/* Distance context is actual after command is decoded and before distance is
|
147
302
|
computed. After distance computation it is used as a temporary variable. */
|
148
303
|
int distance_context;
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
int distance_postfix_mask;
|
157
|
-
uint32_t num_dist_htrees;
|
304
|
+
brotli_reg_t block_length[3];
|
305
|
+
brotli_reg_t block_length_index;
|
306
|
+
brotli_reg_t num_block_types[3];
|
307
|
+
brotli_reg_t block_type_rb[6];
|
308
|
+
brotli_reg_t distance_postfix_bits;
|
309
|
+
brotli_reg_t num_direct_distance_codes;
|
310
|
+
brotli_reg_t num_dist_htrees;
|
158
311
|
uint8_t* dist_context_map;
|
159
312
|
HuffmanCode* literal_htree;
|
160
|
-
uint8_t dist_htree_index;
|
161
|
-
uint32_t repeat_code_len;
|
162
|
-
uint32_t prev_code_len;
|
163
|
-
|
164
|
-
int copy_length;
|
165
|
-
int distance_code;
|
166
313
|
|
167
314
|
/* For partial write operations. */
|
168
315
|
size_t rb_roundtrips; /* how many times we went around the ring-buffer */
|
169
316
|
size_t partial_pos_out; /* how much output to the user in total */
|
170
317
|
|
171
|
-
/* For
|
172
|
-
|
173
|
-
uint32_t
|
174
|
-
uint32_t space;
|
318
|
+
/* For InverseMoveToFrontTransform. */
|
319
|
+
brotli_reg_t mtf_upper_bound;
|
320
|
+
uint32_t mtf[64 + 1];
|
175
321
|
|
176
|
-
|
177
|
-
|
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];
|
322
|
+
int copy_length;
|
323
|
+
int distance_code;
|
187
324
|
|
188
|
-
|
189
|
-
|
190
|
-
HuffmanCode* next;
|
325
|
+
uint8_t dist_htree_index;
|
326
|
+
/* TODO(eustas): +3 bytes padding */
|
191
327
|
|
192
|
-
/*
|
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];
|
328
|
+
/* Less used attributes are at the end of this struct. */
|
197
329
|
|
198
|
-
|
199
|
-
|
200
|
-
|
330
|
+
brotli_decoder_metadata_start_func metadata_start_func;
|
331
|
+
brotli_decoder_metadata_chunk_func metadata_chunk_func;
|
332
|
+
void* metadata_callback_opaque;
|
201
333
|
|
202
|
-
/*
|
334
|
+
/* For reporting. */
|
335
|
+
uint64_t used_input; /* how many bytes of input are consumed */
|
203
336
|
|
204
337
|
/* States inside function calls. */
|
205
338
|
BrotliRunningMetablockHeaderState substate_metablock_header;
|
206
|
-
BrotliRunningTreeGroupState substate_tree_group;
|
207
|
-
BrotliRunningContextMapState substate_context_map;
|
208
339
|
BrotliRunningUncompressedState substate_uncompressed;
|
209
|
-
BrotliRunningHuffmanState substate_huffman;
|
210
340
|
BrotliRunningDecodeUint8State substate_decode_uint8;
|
211
341
|
BrotliRunningReadBlockLengthState substate_read_block_length;
|
212
342
|
|
343
|
+
int new_ringbuffer_size;
|
344
|
+
/* TODO(eustas): +4 bytes padding */
|
345
|
+
|
213
346
|
unsigned int is_last_metablock : 1;
|
214
347
|
unsigned int is_uncompressed : 1;
|
215
348
|
unsigned int is_metadata : 1;
|
216
349
|
unsigned int should_wrap_ringbuffer : 1;
|
217
350
|
unsigned int canny_ringbuffer_allocation : 1;
|
218
351
|
unsigned int large_window : 1;
|
352
|
+
unsigned int window_bits : 6;
|
219
353
|
unsigned int size_nibbles : 8;
|
220
|
-
|
354
|
+
/* TODO(eustas): +12 bits padding */
|
221
355
|
|
222
|
-
|
223
|
-
|
224
|
-
uint32_t num_literal_htrees;
|
356
|
+
brotli_reg_t num_literal_htrees;
|
225
357
|
uint8_t* context_map;
|
226
358
|
uint8_t* context_modes;
|
227
359
|
|
228
|
-
|
229
|
-
|
360
|
+
BrotliSharedDictionary* dictionary;
|
361
|
+
BrotliDecoderCompoundDictionary* compound_dictionary;
|
230
362
|
|
231
363
|
uint32_t trivial_literal_contexts[8]; /* 256 bits */
|
364
|
+
|
365
|
+
union {
|
366
|
+
BrotliMetablockHeaderArena header;
|
367
|
+
BrotliMetablockBodyArena body;
|
368
|
+
} arena;
|
232
369
|
};
|
233
370
|
|
234
371
|
typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
|
@@ -241,8 +378,9 @@ BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
|
|
241
378
|
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
|
242
379
|
BrotliDecoderState* s);
|
243
380
|
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
|
244
|
-
BrotliDecoderState* s, HuffmanTreeGroup* group,
|
245
|
-
|
381
|
+
BrotliDecoderState* s, HuffmanTreeGroup* group,
|
382
|
+
brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
|
383
|
+
brotli_reg_t ntrees);
|
246
384
|
|
247
385
|
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
248
386
|
|
@@ -251,6 +389,10 @@ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
|
|
251
389
|
X = NULL; \
|
252
390
|
}
|
253
391
|
|
392
|
+
/* Literal/Command/Distance block size maximum; same as maximum metablock size;
|
393
|
+
used as block size when there is no block switching. */
|
394
|
+
#define BROTLI_BLOCK_SIZE_CAP (1U << 24)
|
395
|
+
|
254
396
|
#if defined(__cplusplus) || defined(c_plusplus)
|
255
397
|
} /* extern "C" */
|
256
398
|
#endif
|