brotli/dec/state.h
Zoltan Szabadka 4b2fd00e24 Use a single lookup table for insert/copy offsets and extra bits.
Remove safe_malloc.c since all the bounds checking is done inside
decode.c now.
2015-08-10 16:39:50 +02:00

190 lines
5.1 KiB
C

/* Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/* Brotli state for partial streaming decoding. */
#ifndef BROTLI_DEC_STATE_H_
#define BROTLI_DEC_STATE_H_
#include <stdio.h>
#include "./bit_reader.h"
#include "./huffman.h"
#include "./streams.h"
#include "./types.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
typedef enum {
BROTLI_STATE_UNINITED,
BROTLI_STATE_BITREADER_WARMUP,
BROTLI_STATE_METABLOCK_BEGIN,
BROTLI_STATE_METABLOCK_HEADER_1,
BROTLI_STATE_METABLOCK_HEADER_2,
BROTLI_STATE_BLOCK_BEGIN,
BROTLI_STATE_BLOCK_INNER,
BROTLI_STATE_BLOCK_DISTANCE,
BROTLI_STATE_BLOCK_POST,
BROTLI_STATE_UNCOMPRESSED,
BROTLI_STATE_METADATA,
BROTLI_STATE_BLOCK_INNER_WRITE,
BROTLI_STATE_METABLOCK_DONE,
BROTLI_STATE_BLOCK_POST_WRITE_1,
BROTLI_STATE_BLOCK_POST_WRITE_2,
BROTLI_STATE_BLOCK_POST_WRAP_COPY,
BROTLI_STATE_HUFFMAN_CODE_0,
BROTLI_STATE_HUFFMAN_CODE_1,
BROTLI_STATE_HUFFMAN_CODE_2,
BROTLI_STATE_CONTEXT_MAP_1,
BROTLI_STATE_CONTEXT_MAP_2,
BROTLI_STATE_TREE_GROUP,
BROTLI_STATE_DONE
} BrotliRunningState;
typedef enum {
BROTLI_STATE_SUB0_NONE,
BROTLI_STATE_SUB0_UNCOMPRESSED_SHORT,
BROTLI_STATE_SUB0_UNCOMPRESSED_FILL,
BROTLI_STATE_SUB0_UNCOMPRESSED_COPY,
BROTLI_STATE_SUB0_UNCOMPRESSED_WARMUP,
BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_1,
BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_2,
BROTLI_STATE_SUB0_UNCOMPRESSED_WRITE_3,
BROTLI_STATE_SUB0_TREE_GROUP,
BROTLI_STATE_SUB0_CONTEXT_MAP_HUFFMAN,
BROTLI_STATE_SUB0_CONTEXT_MAPS
} BrotliRunningSub0State;
typedef enum {
BROTLI_STATE_SUB1_NONE,
BROTLI_STATE_SUB1_HUFFMAN_LENGTH_BEGIN,
BROTLI_STATE_SUB1_HUFFMAN_LENGTH_SYMBOLS,
BROTLI_STATE_SUB1_HUFFMAN_DONE
} BrotliRunningSub1State;
typedef struct {
BrotliRunningState state;
BrotliRunningSub0State sub0_state; /* State inside function call */
BrotliRunningSub1State sub1_state; /* State inside function call */
int pos;
int input_end;
uint32_t window_bits;
int max_backward_distance;
int max_distance;
int ringbuffer_size;
int ringbuffer_mask;
uint8_t* ringbuffer;
uint8_t* ringbuffer_end;
/* This ring buffer holds a few past copy distances that will be used by */
/* some special distance codes. */
int dist_rb[4];
int dist_rb_idx;
HuffmanTreeGroup literal_hgroup;
HuffmanTreeGroup insert_copy_hgroup;
HuffmanTreeGroup distance_hgroup;
HuffmanCode* block_type_trees;
HuffmanCode* block_len_trees;
BrotliBitReader br;
/* This counter is reused for several disjoint loops. */
int loop_counter;
/* 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 meta_block_remaining_len;
int is_metadata;
int is_uncompressed;
int block_length[3];
int num_block_types[3];
int block_type_rb[6];
int distance_postfix_bits;
int num_direct_distance_codes;
int distance_postfix_mask;
uint8_t* context_map;
uint8_t* context_modes;
int num_literal_htrees;
uint8_t* dist_context_map;
int num_dist_htrees;
uint8_t* context_map_slice;
uint8_t* dist_context_map_slice;
uint8_t literal_htree_index;
uint8_t dist_htree_index;
uint8_t prev_code_len;
uint8_t repeat_code_len;
const uint8_t* context_lookup1;
const uint8_t* context_lookup2;
HuffmanCode* htree_command;
int copy_length;
int distance_code;
int distance;
/* For CopyUncompressedBlockToOutput */
int nbytes;
/* For partial write operations */
int to_write;
int partially_written;
/* For HuffmanTreeGroupDecode */
int htrees_decoded;
/* For ReadHuffmanCodeLengths */
int symbol;
int repeat;
int space;
HuffmanCode table[32];
uint8_t code_length_code_lengths[18];
/* For ReadHuffmanCode */
uint8_t* code_lengths;
/* The maximum non-zero code length index in code lengths */
uint32_t huffman_max_nonzero;
/* Population counts for the code lengths */
uint16_t code_length_histo[16];
/* For HuffmanTreeGroupDecode */
int htree_index;
HuffmanCode* next;
/* For DecodeContextMap */
int context_index;
int max_run_length_prefix;
HuffmanCode* context_map_table;
/* For InverseMoveToFrontTransform */
int mtf_upper_bound;
uint8_t mtf[256];
/* For custom dictionaries */
const uint8_t* custom_dict;
int custom_dict_size;
} BrotliState;
void BrotliStateInit(BrotliState* s);
void BrotliStateCleanup(BrotliState* s);
void BrotliStateMetablockBegin(BrotliState* s);
void BrotliStateCleanupAfterMetablock(BrotliState* s);
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_DEC_STATE_H_ */