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 <brotli/decode.h>
13#include <brotli/shared_dictionary.h>
14#include <brotli/types.h>
15
16#include "../common/constants.h"
17#include "../common/dictionary.h"
18#include "../common/platform.h"
19#include "../common/transform.h"
20#include "bit_reader.h"
21#include "huffman.h"
22
23#if defined(__cplusplus) || defined(c_plusplus)
24extern "C" {
25#endif
26
27/* Graphviz diagram that describes state transitions:
28
29digraph 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
116typedef enum {
117 BROTLI_STATE_UNINITED,
118 BROTLI_STATE_LARGE_WINDOW_BITS,
119 BROTLI_STATE_INITIALIZE,
120 BROTLI_STATE_METABLOCK_BEGIN,
121 BROTLI_STATE_METABLOCK_HEADER,
122 BROTLI_STATE_METABLOCK_HEADER_2,
123 BROTLI_STATE_CONTEXT_MODES,
124 BROTLI_STATE_COMMAND_BEGIN,
125 BROTLI_STATE_COMMAND_INNER,
126 BROTLI_STATE_COMMAND_POST_DECODE_LITERALS,
127 BROTLI_STATE_COMMAND_POST_WRAP_COPY,
128 BROTLI_STATE_UNCOMPRESSED,
129 BROTLI_STATE_METADATA,
130 BROTLI_STATE_COMMAND_INNER_WRITE,
131 BROTLI_STATE_METABLOCK_DONE,
132 BROTLI_STATE_COMMAND_POST_WRITE_1,
133 BROTLI_STATE_COMMAND_POST_WRITE_2,
134 BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
135 BROTLI_STATE_HUFFMAN_CODE_0,
136 BROTLI_STATE_HUFFMAN_CODE_1,
137 BROTLI_STATE_HUFFMAN_CODE_2,
138 BROTLI_STATE_HUFFMAN_CODE_3,
139 BROTLI_STATE_CONTEXT_MAP_1,
140 BROTLI_STATE_CONTEXT_MAP_2,
141 BROTLI_STATE_TREE_GROUP,
142 BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
143 BROTLI_STATE_DONE
144} BrotliRunningState;
145
146typedef enum {
147 BROTLI_STATE_METABLOCK_HEADER_NONE,
148 BROTLI_STATE_METABLOCK_HEADER_EMPTY,
149 BROTLI_STATE_METABLOCK_HEADER_NIBBLES,
150 BROTLI_STATE_METABLOCK_HEADER_SIZE,
151 BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED,
152 BROTLI_STATE_METABLOCK_HEADER_RESERVED,
153 BROTLI_STATE_METABLOCK_HEADER_BYTES,
154 BROTLI_STATE_METABLOCK_HEADER_METADATA
155} BrotliRunningMetablockHeaderState;
156
157typedef enum {
158 BROTLI_STATE_UNCOMPRESSED_NONE,
159 BROTLI_STATE_UNCOMPRESSED_WRITE
160} BrotliRunningUncompressedState;
161
162typedef enum {
163 BROTLI_STATE_TREE_GROUP_NONE,
164 BROTLI_STATE_TREE_GROUP_LOOP
165} BrotliRunningTreeGroupState;
166
167typedef enum {
168 BROTLI_STATE_CONTEXT_MAP_NONE,
169 BROTLI_STATE_CONTEXT_MAP_READ_PREFIX,
170 BROTLI_STATE_CONTEXT_MAP_HUFFMAN,
171 BROTLI_STATE_CONTEXT_MAP_DECODE,
172 BROTLI_STATE_CONTEXT_MAP_TRANSFORM
173} BrotliRunningContextMapState;
174
175typedef enum {
176 BROTLI_STATE_HUFFMAN_NONE,
177 BROTLI_STATE_HUFFMAN_SIMPLE_SIZE,
178 BROTLI_STATE_HUFFMAN_SIMPLE_READ,
179 BROTLI_STATE_HUFFMAN_SIMPLE_BUILD,
180 BROTLI_STATE_HUFFMAN_COMPLEX,
181 BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS
182} BrotliRunningHuffmanState;
183
184typedef enum {
185 BROTLI_STATE_DECODE_UINT8_NONE,
186 BROTLI_STATE_DECODE_UINT8_SHORT,
187 BROTLI_STATE_DECODE_UINT8_LONG
188} BrotliRunningDecodeUint8State;
189
190typedef enum {
191 BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
192 BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
193} BrotliRunningReadBlockLengthState;
194
195/* BrotliDecoderState addon, used for Compound Dictionary functionality. */
196typedef 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
209typedef struct BrotliMetablockHeaderArena {
210 BrotliRunningTreeGroupState substate_tree_group;
211 BrotliRunningContextMapState substate_context_map;
212 BrotliRunningHuffmanState substate_huffman;
213
214 uint32_t sub_loop_counter;
215
216 uint32_t repeat_code_len;
217 uint32_t prev_code_len;
218
219 /* For ReadHuffmanCode. */
220 uint32_t symbol;
221 uint32_t repeat;
222 uint32_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
237 /* For HuffmanTreeGroupDecode. */
238 int htree_index;
239 HuffmanCode* next;
240
241 /* For DecodeContextMap. */
242 uint32_t context_index;
243 uint32_t max_run_length_prefix;
244 uint32_t code;
245 HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
246} BrotliMetablockHeaderArena;
247
248typedef struct BrotliMetablockBodyArena {
249 uint8_t dist_extra_bits[544];
250 uint32_t dist_offset[544];
251} BrotliMetablockBodyArena;
252
253struct BrotliDecoderStateStruct {
254 BrotliRunningState state;
255
256 /* This counter is reused for several disjoint loops. */
257 int loop_counter;
258
259 BrotliBitReader br;
260
261 brotli_alloc_func alloc_func;
262 brotli_free_func free_func;
263 void* memory_manager_opaque;
264
265 /* Temporary storage for remaining input. Brotli stream format is designed in
266 a way, that 64 bits are enough to make progress in decoding. */
267 union {
268 uint64_t u64;
269 uint8_t u8[8];
270 } buffer;
271 uint32_t buffer_length;
272
273 int pos;
274 int max_backward_distance;
275 int max_distance;
276 int ringbuffer_size;
277 int ringbuffer_mask;
278 int dist_rb_idx;
279 int dist_rb[4];
280 int error_code;
281 uint8_t* ringbuffer;
282 uint8_t* ringbuffer_end;
283 HuffmanCode* htree_command;
284 const uint8_t* context_lookup;
285 uint8_t* context_map_slice;
286 uint8_t* dist_context_map_slice;
287
288 /* This ring buffer holds a few past copy distances that will be used by
289 some special distance codes. */
290 HuffmanTreeGroup literal_hgroup;
291 HuffmanTreeGroup insert_copy_hgroup;
292 HuffmanTreeGroup distance_hgroup;
293 HuffmanCode* block_type_trees;
294 HuffmanCode* block_len_trees;
295 /* This is true if the literal context map histogram type always matches the
296 block type. It is then not needed to keep the context (faster decoding). */
297 int trivial_literal_context;
298 /* Distance context is actual after command is decoded and before distance is
299 computed. After distance computation it is used as a temporary variable. */
300 int distance_context;
301 int meta_block_remaining_len;
302 uint32_t block_length_index;
303 uint32_t block_length[3];
304 uint32_t num_block_types[3];
305 uint32_t block_type_rb[6];
306 uint32_t distance_postfix_bits;
307 uint32_t num_direct_distance_codes;
308 uint32_t num_dist_htrees;
309 uint8_t* dist_context_map;
310 HuffmanCode* literal_htree;
311 uint8_t dist_htree_index;
312
313 int copy_length;
314 int distance_code;
315
316 /* For partial write operations. */
317 size_t rb_roundtrips; /* how many times we went around the ring-buffer */
318 size_t partial_pos_out; /* how much output to the user in total */
319
320 /* For InverseMoveToFrontTransform. */
321 uint32_t mtf_upper_bound;
322 uint32_t mtf[64 + 1];
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 unsigned int is_last_metablock : 1;
340 unsigned int is_uncompressed : 1;
341 unsigned int is_metadata : 1;
342 unsigned int should_wrap_ringbuffer : 1;
343 unsigned int canny_ringbuffer_allocation : 1;
344 unsigned int large_window : 1;
345 unsigned int size_nibbles : 8;
346 uint32_t window_bits;
347
348 int new_ringbuffer_size;
349
350 uint32_t num_literal_htrees;
351 uint8_t* context_map;
352 uint8_t* context_modes;
353
354 BrotliSharedDictionary* dictionary;
355 BrotliDecoderCompoundDictionary* compound_dictionary;
356
357 uint32_t trivial_literal_contexts[8]; /* 256 bits */
358
359 union {
360 BrotliMetablockHeaderArena header;
361 BrotliMetablockBodyArena body;
362 } arena;
363};
364
365typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
366#define BrotliDecoderState BrotliDecoderStateInternal
367
368BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
369 brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
370BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s);
371BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
372BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
373 BrotliDecoderState* s);
374BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
375 BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max,
376 uint32_t alphabet_size_limit, uint32_t ntrees);
377
378#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
379
380#define BROTLI_DECODER_FREE(S, X) { \
381 S->free_func(S->memory_manager_opaque, X); \
382 X = NULL; \
383}
384
385#if defined(__cplusplus) || defined(c_plusplus)
386} /* extern "C" */
387#endif
388
389#endif /* BROTLI_DEC_STATE_H_ */
390