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