diff options
Diffstat (limited to 'modules/brotli/dec/state.h')
-rw-r--r-- | modules/brotli/dec/state.h | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/modules/brotli/dec/state.h b/modules/brotli/dec/state.h new file mode 100644 index 000000000..63647ef2b --- /dev/null +++ b/modules/brotli/dec/state.h @@ -0,0 +1,242 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Brotli state for partial streaming decoding. */ + +#ifndef BROTLI_DEC_STATE_H_ +#define BROTLI_DEC_STATE_H_ + +#include "./bit_reader.h" +#include "./huffman.h" +#include "./types.h" +#include "./port.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef enum { + BROTLI_STATE_UNINITED, + BROTLI_STATE_METABLOCK_BEGIN, + BROTLI_STATE_METABLOCK_HEADER, + BROTLI_STATE_METABLOCK_HEADER_2, + BROTLI_STATE_CONTEXT_MODES, + BROTLI_STATE_COMMAND_BEGIN, + BROTLI_STATE_COMMAND_INNER, + BROTLI_STATE_COMMAND_POST_DECODE_LITERALS, + BROTLI_STATE_COMMAND_POST_WRAP_COPY, + BROTLI_STATE_UNCOMPRESSED, + BROTLI_STATE_METADATA, + BROTLI_STATE_COMMAND_INNER_WRITE, + BROTLI_STATE_METABLOCK_DONE, + BROTLI_STATE_COMMAND_POST_WRITE_1, + BROTLI_STATE_COMMAND_POST_WRITE_2, + BROTLI_STATE_HUFFMAN_CODE_0, + BROTLI_STATE_HUFFMAN_CODE_1, + BROTLI_STATE_HUFFMAN_CODE_2, + BROTLI_STATE_HUFFMAN_CODE_3, + BROTLI_STATE_CONTEXT_MAP_1, + BROTLI_STATE_CONTEXT_MAP_2, + BROTLI_STATE_TREE_GROUP, + BROTLI_STATE_DONE +} BrotliRunningState; + +typedef enum { + BROTLI_STATE_METABLOCK_HEADER_NONE, + BROTLI_STATE_METABLOCK_HEADER_EMPTY, + BROTLI_STATE_METABLOCK_HEADER_NIBBLES, + BROTLI_STATE_METABLOCK_HEADER_SIZE, + BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED, + BROTLI_STATE_METABLOCK_HEADER_RESERVED, + BROTLI_STATE_METABLOCK_HEADER_BYTES, + BROTLI_STATE_METABLOCK_HEADER_METADATA +} BrotliRunningMetablockHeaderState; + +typedef enum { + BROTLI_STATE_UNCOMPRESSED_NONE, + BROTLI_STATE_UNCOMPRESSED_WRITE +} BrotliRunningUncompressedState; + +typedef enum { + BROTLI_STATE_TREE_GROUP_NONE, + BROTLI_STATE_TREE_GROUP_LOOP +} BrotliRunningTreeGroupState; + +typedef enum { + BROTLI_STATE_CONTEXT_MAP_NONE, + BROTLI_STATE_CONTEXT_MAP_READ_PREFIX, + BROTLI_STATE_CONTEXT_MAP_HUFFMAN, + BROTLI_STATE_CONTEXT_MAP_DECODE, + BROTLI_STATE_CONTEXT_MAP_TRANSFORM +} BrotliRunningContextMapState; + +typedef enum { + BROTLI_STATE_HUFFMAN_NONE, + BROTLI_STATE_HUFFMAN_SIMPLE_SIZE, + BROTLI_STATE_HUFFMAN_SIMPLE_READ, + BROTLI_STATE_HUFFMAN_SIMPLE_BUILD, + BROTLI_STATE_HUFFMAN_COMPLEX, + BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS +} BrotliRunningHuffmanState; + +typedef enum { + BROTLI_STATE_DECODE_UINT8_NONE, + BROTLI_STATE_DECODE_UINT8_SHORT, + BROTLI_STATE_DECODE_UINT8_LONG +} BrotliRunningDecodeUint8State; + +typedef enum { + BROTLI_STATE_READ_BLOCK_LENGTH_NONE, + BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX +} BrotliRunningReadBlockLengthState; + +struct BrotliStateStruct { + BrotliRunningState state; + + /* This counter is reused for several disjoint loops. */ + int loop_counter; + + BrotliBitReader br; + + brotli_alloc_func alloc_func; + brotli_free_func free_func; + void* memory_manager_opaque; + + /* Temporary storage for remaining input. */ + union { + uint64_t u64; + uint8_t u8[8]; + } buffer; + uint32_t buffer_length; + + int pos; + int max_backward_distance; + int max_backward_distance_minus_custom_dict_size; + int max_distance; + int ringbuffer_size; + int ringbuffer_mask; + int dist_rb_idx; + int dist_rb[4]; + int error_code; + uint32_t sub_loop_counter; + uint8_t* ringbuffer; + uint8_t* ringbuffer_end; + HuffmanCode* htree_command; + const uint8_t* context_lookup1; + const uint8_t* context_lookup2; + uint8_t* context_map_slice; + uint8_t* dist_context_map_slice; + + /* This ring buffer holds a few past copy distances that will be used by */ + /* some special distance codes. */ + HuffmanTreeGroup literal_hgroup; + HuffmanTreeGroup insert_copy_hgroup; + HuffmanTreeGroup distance_hgroup; + HuffmanCode* block_type_trees; + HuffmanCode* block_len_trees; + /* This is true if the literal context map histogram type always matches the + block type. It is then not needed to keep the context (faster decoding). */ + int trivial_literal_context; + int distance_context; + int meta_block_remaining_len; + uint32_t block_length_index; + uint32_t block_length[3]; + uint32_t num_block_types[3]; + uint32_t block_type_rb[6]; + uint32_t distance_postfix_bits; + uint32_t num_direct_distance_codes; + int distance_postfix_mask; + uint32_t num_dist_htrees; + uint8_t* dist_context_map; + HuffmanCode* literal_htree; + uint8_t dist_htree_index; + uint32_t repeat_code_len; + uint32_t prev_code_len; + + int copy_length; + int distance_code; + + /* For partial write operations */ + size_t rb_roundtrips; /* How many times we went around the ringbuffer */ + size_t partial_pos_out; /* How much output to the user in total (<= rb) */ + + /* For ReadHuffmanCode */ + uint32_t symbol; + uint32_t repeat; + uint32_t space; + + HuffmanCode table[32]; + /* List of of symbol chains. */ + uint16_t* symbol_lists; + /* Storage from symbol_lists. */ + uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 + + BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE]; + /* Tails of symbol chains. */ + int next_symbol[32]; + uint8_t code_length_code_lengths[18]; + /* Population counts for the code lengths */ + uint16_t code_length_histo[16]; + + /* For HuffmanTreeGroupDecode */ + int htree_index; + HuffmanCode* next; + + /* For DecodeContextMap */ + uint32_t context_index; + uint32_t max_run_length_prefix; + uint32_t code; + HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272]; + + /* For InverseMoveToFrontTransform */ + uint32_t mtf_upper_bound; + uint8_t mtf[256 + 4]; + + /* For custom dictionaries */ + const uint8_t* custom_dict; + int custom_dict_size; + + /* less used attributes are in the end of this struct */ + /* States inside function calls */ + BrotliRunningMetablockHeaderState substate_metablock_header; + BrotliRunningTreeGroupState substate_tree_group; + BrotliRunningContextMapState substate_context_map; + BrotliRunningUncompressedState substate_uncompressed; + BrotliRunningHuffmanState substate_huffman; + BrotliRunningDecodeUint8State substate_decode_uint8; + BrotliRunningReadBlockLengthState substate_read_block_length; + + uint8_t is_last_metablock; + uint8_t is_uncompressed; + uint8_t is_metadata; + uint8_t size_nibbles; + uint32_t window_bits; + + uint32_t num_literal_htrees; + uint8_t* context_map; + uint8_t* context_modes; + + uint32_t trivial_literal_contexts[8]; /* 256 bits */ +}; + +typedef struct BrotliStateStruct BrotliStateInternal; +#define BrotliState BrotliStateInternal + +BROTLI_INTERNAL void BrotliStateInit(BrotliState* s); +BROTLI_INTERNAL void BrotliStateInitWithCustomAllocators(BrotliState* s, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); +BROTLI_INTERNAL void BrotliStateCleanup(BrotliState* s); +BROTLI_INTERNAL void BrotliStateMetablockBegin(BrotliState* s); +BROTLI_INTERNAL void BrotliStateCleanupAfterMetablock(BrotliState* s); +BROTLI_INTERNAL void BrotliHuffmanTreeGroupInit(BrotliState* s, + HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t ntrees); +BROTLI_INTERNAL void BrotliHuffmanTreeGroupRelease(BrotliState* s, + HuffmanTreeGroup* group); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_STATE_H_ */ |