/* 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" #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]; 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; uint32_t sub_loop_counter; /* 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 literal_htree_index; 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]; /* 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; }; typedef struct BrotliStateStruct BrotliState; void BrotliStateInit(BrotliState* s); void BrotliStateInitWithCustomAllocators(BrotliState* s, brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); void BrotliStateCleanup(BrotliState* s); void BrotliStateMetablockBegin(BrotliState* s); void BrotliStateCleanupAfterMetablock(BrotliState* s); void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t ntrees); void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group); /* Returns 1, if s is in a state where we have not read any input bytes yet, and 0 otherwise */ int BrotliStateIsStreamStart(const BrotliState* s); /* Returns 1, if s is in a state where we reached the end of the input and produced all of the output, and 0 otherwise. */ int BrotliStateIsStreamEnd(const BrotliState* s); #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ #endif #endif /* BROTLI_DEC_STATE_H_ */