Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/brotli/dec/state.h
21758 views
1
/* Copyright 2015 Google Inc. All Rights Reserved.
2
3
Distributed under MIT license.
4
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
*/
6
7
/* Brotli state for partial streaming decoding. */
8
9
#ifndef BROTLI_DEC_STATE_H_
10
#define BROTLI_DEC_STATE_H_
11
12
#include "../common/constants.h"
13
#include "../common/platform.h"
14
#include <brotli/shared_dictionary.h>
15
#include <brotli/decode.h>
16
#include "bit_reader.h"
17
#include "huffman.h"
18
19
#if defined(__cplusplus) || defined(c_plusplus)
20
extern "C" {
21
#endif
22
23
/* Graphviz diagram that describes state transitions:
24
25
digraph States {
26
graph [compound=true]
27
concentrate=true
28
node [shape="box"]
29
30
UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
31
subgraph cluster_metablock_workflow {
32
style="rounded"
33
label=< <B>METABLOCK CYCLE</B> >
34
METABLOCK_BEGIN -> METABLOCK_HEADER
35
METABLOCK_HEADER:sw -> METADATA
36
METABLOCK_HEADER:s -> UNCOMPRESSED
37
METABLOCK_HEADER:se -> METABLOCK_DONE:ne
38
METADATA:s -> METABLOCK_DONE:w
39
UNCOMPRESSED:s -> METABLOCK_DONE:n
40
METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
41
}
42
INITIALIZE -> METABLOCK_BEGIN
43
METABLOCK_DONE -> DONE
44
45
subgraph cluster_compressed_metablock {
46
style="rounded"
47
label=< <B>COMPRESSED METABLOCK</B> >
48
49
subgraph cluster_command {
50
style="rounded"
51
label=< <B>HOT LOOP</B> >
52
53
_METABLOCK_DONE_PORT_ [shape=point style=invis]
54
55
{
56
// Set different shape for nodes returning from "compressed metablock".
57
node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
58
CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
59
}
60
61
CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
62
63
// IO ("write") nodes are not in the hot loop!
64
CMD_INNER_WRITE [style=dashed]
65
CMD_INNER -> CMD_INNER_WRITE
66
CMD_POST_WRITE_1 [style=dashed]
67
CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
68
CMD_POST_WRITE_2 [style=dashed]
69
CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
70
71
CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
72
CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
73
[constraint="false"]
74
CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
75
CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
76
CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
77
CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
78
{rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
79
CMD_POST_WRAP_COPY}
80
{rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
81
82
{CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
83
_METABLOCK_DONE_PORT_ [style=invis]
84
{CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
85
[constraint="false" style=invis]
86
}
87
88
BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
89
HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
90
HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
91
CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
92
TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
93
BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
94
95
HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
96
{rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
97
{rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
98
TREE_GROUP}
99
}
100
METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
101
102
_METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
103
[constraint="false" ltail=cluster_command]
104
105
UNINITED [shape=Mdiamond];
106
DONE [shape=Msquare];
107
}
108
109
110
*/
111
112
typedef enum {
113
BROTLI_STATE_UNINITED,
114
BROTLI_STATE_LARGE_WINDOW_BITS,
115
BROTLI_STATE_INITIALIZE,
116
BROTLI_STATE_METABLOCK_BEGIN,
117
BROTLI_STATE_METABLOCK_HEADER,
118
BROTLI_STATE_METABLOCK_HEADER_2,
119
BROTLI_STATE_CONTEXT_MODES,
120
BROTLI_STATE_COMMAND_BEGIN,
121
BROTLI_STATE_COMMAND_INNER,
122
BROTLI_STATE_COMMAND_POST_DECODE_LITERALS,
123
BROTLI_STATE_COMMAND_POST_WRAP_COPY,
124
BROTLI_STATE_UNCOMPRESSED,
125
BROTLI_STATE_METADATA,
126
BROTLI_STATE_COMMAND_INNER_WRITE,
127
BROTLI_STATE_METABLOCK_DONE,
128
BROTLI_STATE_COMMAND_POST_WRITE_1,
129
BROTLI_STATE_COMMAND_POST_WRITE_2,
130
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
131
BROTLI_STATE_HUFFMAN_CODE_0,
132
BROTLI_STATE_HUFFMAN_CODE_1,
133
BROTLI_STATE_HUFFMAN_CODE_2,
134
BROTLI_STATE_HUFFMAN_CODE_3,
135
BROTLI_STATE_CONTEXT_MAP_1,
136
BROTLI_STATE_CONTEXT_MAP_2,
137
BROTLI_STATE_TREE_GROUP,
138
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
139
BROTLI_STATE_DONE
140
} BrotliRunningState;
141
142
typedef enum {
143
BROTLI_STATE_METABLOCK_HEADER_NONE,
144
BROTLI_STATE_METABLOCK_HEADER_EMPTY,
145
BROTLI_STATE_METABLOCK_HEADER_NIBBLES,
146
BROTLI_STATE_METABLOCK_HEADER_SIZE,
147
BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED,
148
BROTLI_STATE_METABLOCK_HEADER_RESERVED,
149
BROTLI_STATE_METABLOCK_HEADER_BYTES,
150
BROTLI_STATE_METABLOCK_HEADER_METADATA
151
} BrotliRunningMetablockHeaderState;
152
153
typedef enum {
154
BROTLI_STATE_UNCOMPRESSED_NONE,
155
BROTLI_STATE_UNCOMPRESSED_WRITE
156
} BrotliRunningUncompressedState;
157
158
typedef enum {
159
BROTLI_STATE_TREE_GROUP_NONE,
160
BROTLI_STATE_TREE_GROUP_LOOP
161
} BrotliRunningTreeGroupState;
162
163
typedef enum {
164
BROTLI_STATE_CONTEXT_MAP_NONE,
165
BROTLI_STATE_CONTEXT_MAP_READ_PREFIX,
166
BROTLI_STATE_CONTEXT_MAP_HUFFMAN,
167
BROTLI_STATE_CONTEXT_MAP_DECODE,
168
BROTLI_STATE_CONTEXT_MAP_TRANSFORM
169
} BrotliRunningContextMapState;
170
171
typedef enum {
172
BROTLI_STATE_HUFFMAN_NONE,
173
BROTLI_STATE_HUFFMAN_SIMPLE_SIZE,
174
BROTLI_STATE_HUFFMAN_SIMPLE_READ,
175
BROTLI_STATE_HUFFMAN_SIMPLE_BUILD,
176
BROTLI_STATE_HUFFMAN_COMPLEX,
177
BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS
178
} BrotliRunningHuffmanState;
179
180
typedef enum {
181
BROTLI_STATE_DECODE_UINT8_NONE,
182
BROTLI_STATE_DECODE_UINT8_SHORT,
183
BROTLI_STATE_DECODE_UINT8_LONG
184
} BrotliRunningDecodeUint8State;
185
186
typedef enum {
187
BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
188
BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
189
} BrotliRunningReadBlockLengthState;
190
191
/* BrotliDecoderState addon, used for Compound Dictionary functionality. */
192
typedef struct BrotliDecoderCompoundDictionary {
193
int num_chunks;
194
int total_size;
195
int br_index;
196
int br_offset;
197
int br_length;
198
int br_copied;
199
const uint8_t* chunks[16];
200
int chunk_offsets[16];
201
int block_bits;
202
uint8_t block_map[256];
203
} BrotliDecoderCompoundDictionary;
204
205
typedef struct BrotliMetablockHeaderArena {
206
BrotliRunningTreeGroupState substate_tree_group;
207
BrotliRunningContextMapState substate_context_map;
208
BrotliRunningHuffmanState substate_huffman;
209
210
brotli_reg_t sub_loop_counter;
211
212
brotli_reg_t repeat_code_len;
213
brotli_reg_t prev_code_len;
214
215
/* For ReadHuffmanCode. */
216
brotli_reg_t symbol;
217
brotli_reg_t repeat;
218
brotli_reg_t space;
219
220
/* Huffman table for "histograms". */
221
HuffmanCode table[32];
222
/* List of heads of symbol chains. */
223
uint16_t* symbol_lists;
224
/* Storage from symbol_lists. */
225
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
226
BROTLI_NUM_COMMAND_SYMBOLS];
227
/* Tails of symbol chains. */
228
int next_symbol[32];
229
uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
230
/* Population counts for the code lengths. */
231
uint16_t code_length_histo[16];
232
/* TODO(eustas): +2 bytes padding */
233
234
/* For HuffmanTreeGroupDecode. */
235
int htree_index;
236
HuffmanCode* next;
237
238
/* For DecodeContextMap. */
239
brotli_reg_t context_index;
240
brotli_reg_t max_run_length_prefix;
241
brotli_reg_t code;
242
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
243
} BrotliMetablockHeaderArena;
244
245
typedef struct BrotliMetablockBodyArena {
246
uint8_t dist_extra_bits[544];
247
brotli_reg_t dist_offset[544];
248
} BrotliMetablockBodyArena;
249
250
struct BrotliDecoderStateStruct {
251
BrotliRunningState state;
252
253
/* This counter is reused for several disjoint loops. */
254
int loop_counter;
255
256
BrotliBitReader br;
257
258
brotli_alloc_func alloc_func;
259
brotli_free_func free_func;
260
void* memory_manager_opaque;
261
262
/* Temporary storage for remaining input. Brotli stream format is designed in
263
a way, that 64 bits are enough to make progress in decoding. */
264
union {
265
uint64_t u64;
266
uint8_t u8[8];
267
} buffer;
268
brotli_reg_t buffer_length;
269
270
int pos;
271
int max_backward_distance;
272
int max_distance;
273
int ringbuffer_size;
274
int ringbuffer_mask;
275
int dist_rb_idx;
276
int dist_rb[4];
277
int error_code;
278
int meta_block_remaining_len;
279
280
uint8_t* ringbuffer;
281
uint8_t* ringbuffer_end;
282
HuffmanCode* htree_command;
283
const uint8_t* context_lookup;
284
uint8_t* context_map_slice;
285
uint8_t* dist_context_map_slice;
286
287
/* This ring buffer holds a few past copy distances that will be used by
288
some special distance codes. */
289
HuffmanTreeGroup literal_hgroup;
290
HuffmanTreeGroup insert_copy_hgroup;
291
HuffmanTreeGroup distance_hgroup;
292
HuffmanCode* block_type_trees;
293
HuffmanCode* block_len_trees;
294
/* This is true if the literal context map histogram type always matches the
295
block type. It is then not needed to keep the context (faster decoding). */
296
int trivial_literal_context;
297
/* Distance context is actual after command is decoded and before distance is
298
computed. After distance computation it is used as a temporary variable. */
299
int distance_context;
300
brotli_reg_t block_length[3];
301
brotli_reg_t block_length_index;
302
brotli_reg_t num_block_types[3];
303
brotli_reg_t block_type_rb[6];
304
brotli_reg_t distance_postfix_bits;
305
brotli_reg_t num_direct_distance_codes;
306
brotli_reg_t num_dist_htrees;
307
uint8_t* dist_context_map;
308
HuffmanCode* literal_htree;
309
310
/* For partial write operations. */
311
size_t rb_roundtrips; /* how many times we went around the ring-buffer */
312
size_t partial_pos_out; /* how much output to the user in total */
313
314
/* For InverseMoveToFrontTransform. */
315
brotli_reg_t mtf_upper_bound;
316
uint32_t mtf[64 + 1];
317
318
int copy_length;
319
int distance_code;
320
321
uint8_t dist_htree_index;
322
/* TODO(eustas): +3 bytes padding */
323
324
/* Less used attributes are at the end of this struct. */
325
326
brotli_decoder_metadata_start_func metadata_start_func;
327
brotli_decoder_metadata_chunk_func metadata_chunk_func;
328
void* metadata_callback_opaque;
329
330
/* For reporting. */
331
uint64_t used_input; /* how many bytes of input are consumed */
332
333
/* States inside function calls. */
334
BrotliRunningMetablockHeaderState substate_metablock_header;
335
BrotliRunningUncompressedState substate_uncompressed;
336
BrotliRunningDecodeUint8State substate_decode_uint8;
337
BrotliRunningReadBlockLengthState substate_read_block_length;
338
339
int new_ringbuffer_size;
340
/* TODO(eustas): +4 bytes padding */
341
342
unsigned int is_last_metablock : 1;
343
unsigned int is_uncompressed : 1;
344
unsigned int is_metadata : 1;
345
unsigned int should_wrap_ringbuffer : 1;
346
unsigned int canny_ringbuffer_allocation : 1;
347
unsigned int large_window : 1;
348
unsigned int window_bits : 6;
349
unsigned int size_nibbles : 8;
350
/* TODO(eustas): +12 bits padding */
351
352
brotli_reg_t num_literal_htrees;
353
uint8_t* context_map;
354
uint8_t* context_modes;
355
356
BrotliSharedDictionary* dictionary;
357
BrotliDecoderCompoundDictionary* compound_dictionary;
358
359
uint32_t trivial_literal_contexts[8]; /* 256 bits */
360
361
union {
362
BrotliMetablockHeaderArena header;
363
BrotliMetablockBodyArena body;
364
} arena;
365
};
366
367
typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
368
#define BrotliDecoderState BrotliDecoderStateInternal
369
370
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
371
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
372
BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s);
373
BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
374
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
375
BrotliDecoderState* s);
376
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
377
BrotliDecoderState* s, HuffmanTreeGroup* group,
378
brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
379
brotli_reg_t ntrees);
380
381
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
382
383
#define BROTLI_DECODER_FREE(S, X) { \
384
S->free_func(S->memory_manager_opaque, X); \
385
X = NULL; \
386
}
387
388
/* Literal/Command/Distance block size maximum; same as maximum metablock size;
389
used as block size when there is no block switching. */
390
#define BROTLI_BLOCK_SIZE_CAP (1U << 24)
391
392
#if defined(__cplusplus) || defined(c_plusplus)
393
} /* extern "C" */
394
#endif
395
396
#endif /* BROTLI_DEC_STATE_H_ */
397
398