brotli/dec/state.h

251 lines
7.2 KiB
C
Raw Normal View History

2015-03-20 15:13:15 +00:00
/* Copyright 2015 Google Inc. All Rights Reserved.
2015-12-11 10:11:51 +00:00
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
2015-03-20 15:13:15 +00:00
*/
/* 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
2015-03-20 15:13:15 +00:00
} 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 {
2015-03-20 15:13:15 +00:00
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;
2015-03-20 15:13:15 +00:00
int pos;
int max_backward_distance;
int max_backward_distance_minus_custom_dict_size;
2015-03-20 15:13:15 +00:00
int max_distance;
int ringbuffer_size;
int ringbuffer_mask;
int dist_rb_idx;
int dist_rb[4];
2015-03-20 15:13:15 +00:00
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;
2015-03-20 15:13:15 +00:00
/* 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;
2015-03-20 15:13:15 +00:00
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;
2015-03-20 15:13:15 +00:00
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;
2015-03-20 15:13:15 +00:00
int distance_postfix_mask;
uint32_t num_dist_htrees;
2015-03-20 15:13:15 +00:00
uint8_t* dist_context_map;
HuffmanCode *literal_htree;
uint8_t literal_htree_index;
2015-03-20 15:13:15 +00:00
uint8_t dist_htree_index;
uint32_t repeat_code_len;
uint32_t prev_code_len;
2015-03-20 15:13:15 +00:00
2015-03-20 15:13:15 +00:00
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;
2015-03-20 15:13:15 +00:00
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];
2015-03-20 15:13:15 +00:00
uint8_t code_length_code_lengths[18];
/* Population counts for the code lengths */
uint16_t code_length_histo[16];
2015-03-20 15:13:15 +00:00
/* 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;
2015-03-20 15:13:15 +00:00
void BrotliStateInit(BrotliState* s);
void BrotliStateInitWithCustomAllocators(BrotliState* s,
brotli_alloc_func alloc_func,
brotli_free_func free_func,
void* opaque);
2015-03-20 15:13:15 +00:00
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);
2015-03-20 15:13:15 +00:00
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_DEC_STATE_H_ */