1*6777b538SAndroid Build Coastguard Worker /* Copyright 2015 Google Inc. All Rights Reserved. 2*6777b538SAndroid Build Coastguard Worker 3*6777b538SAndroid Build Coastguard Worker Distributed under MIT license. 4*6777b538SAndroid Build Coastguard Worker See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5*6777b538SAndroid Build Coastguard Worker */ 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker /* Brotli state for partial streaming decoding. */ 8*6777b538SAndroid Build Coastguard Worker 9*6777b538SAndroid Build Coastguard Worker #ifndef BROTLI_DEC_STATE_H_ 10*6777b538SAndroid Build Coastguard Worker #define BROTLI_DEC_STATE_H_ 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "../common/constants.h" 13*6777b538SAndroid Build Coastguard Worker #include "../common/dictionary.h" 14*6777b538SAndroid Build Coastguard Worker #include "../common/platform.h" 15*6777b538SAndroid Build Coastguard Worker #include <brotli/shared_dictionary.h> 16*6777b538SAndroid Build Coastguard Worker #include "../common/transform.h" 17*6777b538SAndroid Build Coastguard Worker #include <brotli/types.h> 18*6777b538SAndroid Build Coastguard Worker #include "bit_reader.h" 19*6777b538SAndroid Build Coastguard Worker #include "huffman.h" 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus) 22*6777b538SAndroid Build Coastguard Worker extern "C" { 23*6777b538SAndroid Build Coastguard Worker #endif 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker /* Graphviz diagram that describes state transitions: 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker digraph States { 28*6777b538SAndroid Build Coastguard Worker graph [compound=true] 29*6777b538SAndroid Build Coastguard Worker concentrate=true 30*6777b538SAndroid Build Coastguard Worker node [shape="box"] 31*6777b538SAndroid Build Coastguard Worker 32*6777b538SAndroid Build Coastguard Worker UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE} 33*6777b538SAndroid Build Coastguard Worker subgraph cluster_metablock_workflow { 34*6777b538SAndroid Build Coastguard Worker style="rounded" 35*6777b538SAndroid Build Coastguard Worker label=< <B>METABLOCK CYCLE</B> > 36*6777b538SAndroid Build Coastguard Worker METABLOCK_BEGIN -> METABLOCK_HEADER 37*6777b538SAndroid Build Coastguard Worker METABLOCK_HEADER:sw -> METADATA 38*6777b538SAndroid Build Coastguard Worker METABLOCK_HEADER:s -> UNCOMPRESSED 39*6777b538SAndroid Build Coastguard Worker METABLOCK_HEADER:se -> METABLOCK_DONE:ne 40*6777b538SAndroid Build Coastguard Worker METADATA:s -> METABLOCK_DONE:w 41*6777b538SAndroid Build Coastguard Worker UNCOMPRESSED:s -> METABLOCK_DONE:n 42*6777b538SAndroid Build Coastguard Worker METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"] 43*6777b538SAndroid Build Coastguard Worker } 44*6777b538SAndroid Build Coastguard Worker INITIALIZE -> METABLOCK_BEGIN 45*6777b538SAndroid Build Coastguard Worker METABLOCK_DONE -> DONE 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard Worker subgraph cluster_compressed_metablock { 48*6777b538SAndroid Build Coastguard Worker style="rounded" 49*6777b538SAndroid Build Coastguard Worker label=< <B>COMPRESSED METABLOCK</B> > 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker subgraph cluster_command { 52*6777b538SAndroid Build Coastguard Worker style="rounded" 53*6777b538SAndroid Build Coastguard Worker label=< <B>HOT LOOP</B> > 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker _METABLOCK_DONE_PORT_ [shape=point style=invis] 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker { 58*6777b538SAndroid Build Coastguard Worker // Set different shape for nodes returning from "compressed metablock". 59*6777b538SAndroid Build Coastguard Worker node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS; 60*6777b538SAndroid Build Coastguard Worker CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1; 61*6777b538SAndroid Build Coastguard Worker } 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // IO ("write") nodes are not in the hot loop! 66*6777b538SAndroid Build Coastguard Worker CMD_INNER_WRITE [style=dashed] 67*6777b538SAndroid Build Coastguard Worker CMD_INNER -> CMD_INNER_WRITE 68*6777b538SAndroid Build Coastguard Worker CMD_POST_WRITE_1 [style=dashed] 69*6777b538SAndroid Build Coastguard Worker CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1 70*6777b538SAndroid Build Coastguard Worker CMD_POST_WRITE_2 [style=dashed] 71*6777b538SAndroid Build Coastguard Worker CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"] 74*6777b538SAndroid Build Coastguard Worker CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS} 75*6777b538SAndroid Build Coastguard Worker [constraint="false"] 76*6777b538SAndroid Build Coastguard Worker CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"] 77*6777b538SAndroid Build Coastguard Worker CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"] 78*6777b538SAndroid Build Coastguard Worker CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"] 79*6777b538SAndroid Build Coastguard Worker CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"] 80*6777b538SAndroid Build Coastguard Worker {rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS; 81*6777b538SAndroid Build Coastguard Worker CMD_POST_WRAP_COPY} 82*6777b538SAndroid Build Coastguard Worker {rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2} 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker {CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} -> 85*6777b538SAndroid Build Coastguard Worker _METABLOCK_DONE_PORT_ [style=invis] 86*6777b538SAndroid Build Coastguard Worker {CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_ 87*6777b538SAndroid Build Coastguard Worker [constraint="false" style=invis] 88*6777b538SAndroid Build Coastguard Worker } 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n 91*6777b538SAndroid Build Coastguard Worker HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3 92*6777b538SAndroid Build Coastguard Worker HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1 93*6777b538SAndroid Build Coastguard Worker CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP 94*6777b538SAndroid Build Coastguard Worker TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e 95*6777b538SAndroid Build Coastguard Worker BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n 96*6777b538SAndroid Build Coastguard Worker 97*6777b538SAndroid Build Coastguard Worker HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"] 98*6777b538SAndroid Build Coastguard Worker {rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3} 99*6777b538SAndroid Build Coastguard Worker {rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2; 100*6777b538SAndroid Build Coastguard Worker TREE_GROUP} 101*6777b538SAndroid Build Coastguard Worker } 102*6777b538SAndroid Build Coastguard Worker METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n 103*6777b538SAndroid Build Coastguard Worker 104*6777b538SAndroid Build Coastguard Worker _METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se 105*6777b538SAndroid Build Coastguard Worker [constraint="false" ltail=cluster_command] 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker UNINITED [shape=Mdiamond]; 108*6777b538SAndroid Build Coastguard Worker DONE [shape=Msquare]; 109*6777b538SAndroid Build Coastguard Worker } 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard Worker */ 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker typedef enum { 115*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_UNINITED, 116*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_LARGE_WINDOW_BITS, 117*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_INITIALIZE, 118*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_BEGIN, 119*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER, 120*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_2, 121*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MODES, 122*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_BEGIN, 123*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_INNER, 124*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_POST_DECODE_LITERALS, 125*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_POST_WRAP_COPY, 126*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_UNCOMPRESSED, 127*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METADATA, 128*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_INNER_WRITE, 129*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_DONE, 130*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_POST_WRITE_1, 131*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_COMMAND_POST_WRITE_2, 132*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER, 133*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_CODE_0, 134*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_CODE_1, 135*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_CODE_2, 136*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_CODE_3, 137*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_1, 138*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_2, 139*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_TREE_GROUP, 140*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY, 141*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_DONE 142*6777b538SAndroid Build Coastguard Worker } BrotliRunningState; 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker typedef enum { 145*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_NONE, 146*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_EMPTY, 147*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_NIBBLES, 148*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_SIZE, 149*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED, 150*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_RESERVED, 151*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_BYTES, 152*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_METABLOCK_HEADER_METADATA 153*6777b538SAndroid Build Coastguard Worker } BrotliRunningMetablockHeaderState; 154*6777b538SAndroid Build Coastguard Worker 155*6777b538SAndroid Build Coastguard Worker typedef enum { 156*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_UNCOMPRESSED_NONE, 157*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_UNCOMPRESSED_WRITE 158*6777b538SAndroid Build Coastguard Worker } BrotliRunningUncompressedState; 159*6777b538SAndroid Build Coastguard Worker 160*6777b538SAndroid Build Coastguard Worker typedef enum { 161*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_TREE_GROUP_NONE, 162*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_TREE_GROUP_LOOP 163*6777b538SAndroid Build Coastguard Worker } BrotliRunningTreeGroupState; 164*6777b538SAndroid Build Coastguard Worker 165*6777b538SAndroid Build Coastguard Worker typedef enum { 166*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_NONE, 167*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_READ_PREFIX, 168*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_HUFFMAN, 169*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_DECODE, 170*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_CONTEXT_MAP_TRANSFORM 171*6777b538SAndroid Build Coastguard Worker } BrotliRunningContextMapState; 172*6777b538SAndroid Build Coastguard Worker 173*6777b538SAndroid Build Coastguard Worker typedef enum { 174*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_NONE, 175*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_SIMPLE_SIZE, 176*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_SIMPLE_READ, 177*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_SIMPLE_BUILD, 178*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_COMPLEX, 179*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS 180*6777b538SAndroid Build Coastguard Worker } BrotliRunningHuffmanState; 181*6777b538SAndroid Build Coastguard Worker 182*6777b538SAndroid Build Coastguard Worker typedef enum { 183*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_DECODE_UINT8_NONE, 184*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_DECODE_UINT8_SHORT, 185*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_DECODE_UINT8_LONG 186*6777b538SAndroid Build Coastguard Worker } BrotliRunningDecodeUint8State; 187*6777b538SAndroid Build Coastguard Worker 188*6777b538SAndroid Build Coastguard Worker typedef enum { 189*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_READ_BLOCK_LENGTH_NONE, 190*6777b538SAndroid Build Coastguard Worker BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX 191*6777b538SAndroid Build Coastguard Worker } BrotliRunningReadBlockLengthState; 192*6777b538SAndroid Build Coastguard Worker 193*6777b538SAndroid Build Coastguard Worker /* BrotliDecoderState addon, used for Compound Dictionary functionality. */ 194*6777b538SAndroid Build Coastguard Worker typedef struct BrotliDecoderCompoundDictionary { 195*6777b538SAndroid Build Coastguard Worker int num_chunks; 196*6777b538SAndroid Build Coastguard Worker int total_size; 197*6777b538SAndroid Build Coastguard Worker int br_index; 198*6777b538SAndroid Build Coastguard Worker int br_offset; 199*6777b538SAndroid Build Coastguard Worker int br_length; 200*6777b538SAndroid Build Coastguard Worker int br_copied; 201*6777b538SAndroid Build Coastguard Worker const uint8_t* chunks[16]; 202*6777b538SAndroid Build Coastguard Worker int chunk_offsets[16]; 203*6777b538SAndroid Build Coastguard Worker int block_bits; 204*6777b538SAndroid Build Coastguard Worker uint8_t block_map[256]; 205*6777b538SAndroid Build Coastguard Worker } BrotliDecoderCompoundDictionary; 206*6777b538SAndroid Build Coastguard Worker 207*6777b538SAndroid Build Coastguard Worker typedef struct BrotliMetablockHeaderArena { 208*6777b538SAndroid Build Coastguard Worker BrotliRunningTreeGroupState substate_tree_group; 209*6777b538SAndroid Build Coastguard Worker BrotliRunningContextMapState substate_context_map; 210*6777b538SAndroid Build Coastguard Worker BrotliRunningHuffmanState substate_huffman; 211*6777b538SAndroid Build Coastguard Worker 212*6777b538SAndroid Build Coastguard Worker uint32_t sub_loop_counter; 213*6777b538SAndroid Build Coastguard Worker 214*6777b538SAndroid Build Coastguard Worker uint32_t repeat_code_len; 215*6777b538SAndroid Build Coastguard Worker uint32_t prev_code_len; 216*6777b538SAndroid Build Coastguard Worker 217*6777b538SAndroid Build Coastguard Worker /* For ReadHuffmanCode. */ 218*6777b538SAndroid Build Coastguard Worker uint32_t symbol; 219*6777b538SAndroid Build Coastguard Worker uint32_t repeat; 220*6777b538SAndroid Build Coastguard Worker uint32_t space; 221*6777b538SAndroid Build Coastguard Worker 222*6777b538SAndroid Build Coastguard Worker /* Huffman table for "histograms". */ 223*6777b538SAndroid Build Coastguard Worker HuffmanCode table[32]; 224*6777b538SAndroid Build Coastguard Worker /* List of heads of symbol chains. */ 225*6777b538SAndroid Build Coastguard Worker uint16_t* symbol_lists; 226*6777b538SAndroid Build Coastguard Worker /* Storage from symbol_lists. */ 227*6777b538SAndroid Build Coastguard Worker uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 + 228*6777b538SAndroid Build Coastguard Worker BROTLI_NUM_COMMAND_SYMBOLS]; 229*6777b538SAndroid Build Coastguard Worker /* Tails of symbol chains. */ 230*6777b538SAndroid Build Coastguard Worker int next_symbol[32]; 231*6777b538SAndroid Build Coastguard Worker uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES]; 232*6777b538SAndroid Build Coastguard Worker /* Population counts for the code lengths. */ 233*6777b538SAndroid Build Coastguard Worker uint16_t code_length_histo[16]; 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker /* For HuffmanTreeGroupDecode. */ 236*6777b538SAndroid Build Coastguard Worker int htree_index; 237*6777b538SAndroid Build Coastguard Worker HuffmanCode* next; 238*6777b538SAndroid Build Coastguard Worker 239*6777b538SAndroid Build Coastguard Worker /* For DecodeContextMap. */ 240*6777b538SAndroid Build Coastguard Worker uint32_t context_index; 241*6777b538SAndroid Build Coastguard Worker uint32_t max_run_length_prefix; 242*6777b538SAndroid Build Coastguard Worker uint32_t code; 243*6777b538SAndroid Build Coastguard Worker HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272]; 244*6777b538SAndroid Build Coastguard Worker } BrotliMetablockHeaderArena; 245*6777b538SAndroid Build Coastguard Worker 246*6777b538SAndroid Build Coastguard Worker typedef struct BrotliMetablockBodyArena { 247*6777b538SAndroid Build Coastguard Worker uint8_t dist_extra_bits[544]; 248*6777b538SAndroid Build Coastguard Worker uint32_t dist_offset[544]; 249*6777b538SAndroid Build Coastguard Worker } BrotliMetablockBodyArena; 250*6777b538SAndroid Build Coastguard Worker 251*6777b538SAndroid Build Coastguard Worker struct BrotliDecoderStateStruct { 252*6777b538SAndroid Build Coastguard Worker BrotliRunningState state; 253*6777b538SAndroid Build Coastguard Worker 254*6777b538SAndroid Build Coastguard Worker /* This counter is reused for several disjoint loops. */ 255*6777b538SAndroid Build Coastguard Worker int loop_counter; 256*6777b538SAndroid Build Coastguard Worker 257*6777b538SAndroid Build Coastguard Worker BrotliBitReader br; 258*6777b538SAndroid Build Coastguard Worker 259*6777b538SAndroid Build Coastguard Worker brotli_alloc_func alloc_func; 260*6777b538SAndroid Build Coastguard Worker brotli_free_func free_func; 261*6777b538SAndroid Build Coastguard Worker void* memory_manager_opaque; 262*6777b538SAndroid Build Coastguard Worker 263*6777b538SAndroid Build Coastguard Worker /* Temporary storage for remaining input. Brotli stream format is designed in 264*6777b538SAndroid Build Coastguard Worker a way, that 64 bits are enough to make progress in decoding. */ 265*6777b538SAndroid Build Coastguard Worker union { 266*6777b538SAndroid Build Coastguard Worker uint64_t u64; 267*6777b538SAndroid Build Coastguard Worker uint8_t u8[8]; 268*6777b538SAndroid Build Coastguard Worker } buffer; 269*6777b538SAndroid Build Coastguard Worker uint32_t buffer_length; 270*6777b538SAndroid Build Coastguard Worker 271*6777b538SAndroid Build Coastguard Worker int pos; 272*6777b538SAndroid Build Coastguard Worker int max_backward_distance; 273*6777b538SAndroid Build Coastguard Worker int max_distance; 274*6777b538SAndroid Build Coastguard Worker int ringbuffer_size; 275*6777b538SAndroid Build Coastguard Worker int ringbuffer_mask; 276*6777b538SAndroid Build Coastguard Worker int dist_rb_idx; 277*6777b538SAndroid Build Coastguard Worker int dist_rb[4]; 278*6777b538SAndroid Build Coastguard Worker int error_code; 279*6777b538SAndroid Build Coastguard Worker uint8_t* ringbuffer; 280*6777b538SAndroid Build Coastguard Worker uint8_t* ringbuffer_end; 281*6777b538SAndroid Build Coastguard Worker HuffmanCode* htree_command; 282*6777b538SAndroid Build Coastguard Worker const uint8_t* context_lookup; 283*6777b538SAndroid Build Coastguard Worker uint8_t* context_map_slice; 284*6777b538SAndroid Build Coastguard Worker uint8_t* dist_context_map_slice; 285*6777b538SAndroid Build Coastguard Worker 286*6777b538SAndroid Build Coastguard Worker /* This ring buffer holds a few past copy distances that will be used by 287*6777b538SAndroid Build Coastguard Worker some special distance codes. */ 288*6777b538SAndroid Build Coastguard Worker HuffmanTreeGroup literal_hgroup; 289*6777b538SAndroid Build Coastguard Worker HuffmanTreeGroup insert_copy_hgroup; 290*6777b538SAndroid Build Coastguard Worker HuffmanTreeGroup distance_hgroup; 291*6777b538SAndroid Build Coastguard Worker HuffmanCode* block_type_trees; 292*6777b538SAndroid Build Coastguard Worker HuffmanCode* block_len_trees; 293*6777b538SAndroid Build Coastguard Worker /* This is true if the literal context map histogram type always matches the 294*6777b538SAndroid Build Coastguard Worker block type. It is then not needed to keep the context (faster decoding). */ 295*6777b538SAndroid Build Coastguard Worker int trivial_literal_context; 296*6777b538SAndroid Build Coastguard Worker /* Distance context is actual after command is decoded and before distance is 297*6777b538SAndroid Build Coastguard Worker computed. After distance computation it is used as a temporary variable. */ 298*6777b538SAndroid Build Coastguard Worker int distance_context; 299*6777b538SAndroid Build Coastguard Worker int meta_block_remaining_len; 300*6777b538SAndroid Build Coastguard Worker uint32_t block_length_index; 301*6777b538SAndroid Build Coastguard Worker uint32_t block_length[3]; 302*6777b538SAndroid Build Coastguard Worker uint32_t num_block_types[3]; 303*6777b538SAndroid Build Coastguard Worker uint32_t block_type_rb[6]; 304*6777b538SAndroid Build Coastguard Worker uint32_t distance_postfix_bits; 305*6777b538SAndroid Build Coastguard Worker uint32_t num_direct_distance_codes; 306*6777b538SAndroid Build Coastguard Worker uint32_t num_dist_htrees; 307*6777b538SAndroid Build Coastguard Worker uint8_t* dist_context_map; 308*6777b538SAndroid Build Coastguard Worker HuffmanCode* literal_htree; 309*6777b538SAndroid Build Coastguard Worker uint8_t dist_htree_index; 310*6777b538SAndroid Build Coastguard Worker 311*6777b538SAndroid Build Coastguard Worker int copy_length; 312*6777b538SAndroid Build Coastguard Worker int distance_code; 313*6777b538SAndroid Build Coastguard Worker 314*6777b538SAndroid Build Coastguard Worker /* For partial write operations. */ 315*6777b538SAndroid Build Coastguard Worker size_t rb_roundtrips; /* how many times we went around the ring-buffer */ 316*6777b538SAndroid Build Coastguard Worker size_t partial_pos_out; /* how much output to the user in total */ 317*6777b538SAndroid Build Coastguard Worker 318*6777b538SAndroid Build Coastguard Worker /* For InverseMoveToFrontTransform. */ 319*6777b538SAndroid Build Coastguard Worker uint32_t mtf_upper_bound; 320*6777b538SAndroid Build Coastguard Worker uint32_t mtf[64 + 1]; 321*6777b538SAndroid Build Coastguard Worker 322*6777b538SAndroid Build Coastguard Worker /* Less used attributes are at the end of this struct. */ 323*6777b538SAndroid Build Coastguard Worker 324*6777b538SAndroid Build Coastguard Worker /* States inside function calls. */ 325*6777b538SAndroid Build Coastguard Worker BrotliRunningMetablockHeaderState substate_metablock_header; 326*6777b538SAndroid Build Coastguard Worker BrotliRunningUncompressedState substate_uncompressed; 327*6777b538SAndroid Build Coastguard Worker BrotliRunningDecodeUint8State substate_decode_uint8; 328*6777b538SAndroid Build Coastguard Worker BrotliRunningReadBlockLengthState substate_read_block_length; 329*6777b538SAndroid Build Coastguard Worker 330*6777b538SAndroid Build Coastguard Worker unsigned int is_last_metablock : 1; 331*6777b538SAndroid Build Coastguard Worker unsigned int is_uncompressed : 1; 332*6777b538SAndroid Build Coastguard Worker unsigned int is_metadata : 1; 333*6777b538SAndroid Build Coastguard Worker unsigned int should_wrap_ringbuffer : 1; 334*6777b538SAndroid Build Coastguard Worker unsigned int canny_ringbuffer_allocation : 1; 335*6777b538SAndroid Build Coastguard Worker unsigned int large_window : 1; 336*6777b538SAndroid Build Coastguard Worker unsigned int size_nibbles : 8; 337*6777b538SAndroid Build Coastguard Worker uint32_t window_bits; 338*6777b538SAndroid Build Coastguard Worker 339*6777b538SAndroid Build Coastguard Worker int new_ringbuffer_size; 340*6777b538SAndroid Build Coastguard Worker 341*6777b538SAndroid Build Coastguard Worker uint32_t num_literal_htrees; 342*6777b538SAndroid Build Coastguard Worker uint8_t* context_map; 343*6777b538SAndroid Build Coastguard Worker uint8_t* context_modes; 344*6777b538SAndroid Build Coastguard Worker 345*6777b538SAndroid Build Coastguard Worker BrotliSharedDictionary* dictionary; 346*6777b538SAndroid Build Coastguard Worker BrotliDecoderCompoundDictionary* compound_dictionary; 347*6777b538SAndroid Build Coastguard Worker 348*6777b538SAndroid Build Coastguard Worker uint32_t trivial_literal_contexts[8]; /* 256 bits */ 349*6777b538SAndroid Build Coastguard Worker 350*6777b538SAndroid Build Coastguard Worker union { 351*6777b538SAndroid Build Coastguard Worker BrotliMetablockHeaderArena header; 352*6777b538SAndroid Build Coastguard Worker BrotliMetablockBodyArena body; 353*6777b538SAndroid Build Coastguard Worker } arena; 354*6777b538SAndroid Build Coastguard Worker }; 355*6777b538SAndroid Build Coastguard Worker 356*6777b538SAndroid Build Coastguard Worker typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal; 357*6777b538SAndroid Build Coastguard Worker #define BrotliDecoderState BrotliDecoderStateInternal 358*6777b538SAndroid Build Coastguard Worker 359*6777b538SAndroid Build Coastguard Worker BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s, 360*6777b538SAndroid Build Coastguard Worker brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); 361*6777b538SAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s); 362*6777b538SAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s); 363*6777b538SAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock( 364*6777b538SAndroid Build Coastguard Worker BrotliDecoderState* s); 365*6777b538SAndroid Build Coastguard Worker BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit( 366*6777b538SAndroid Build Coastguard Worker BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max, 367*6777b538SAndroid Build Coastguard Worker uint32_t alphabet_size_limit, uint32_t ntrees); 368*6777b538SAndroid Build Coastguard Worker 369*6777b538SAndroid Build Coastguard Worker #define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) 370*6777b538SAndroid Build Coastguard Worker 371*6777b538SAndroid Build Coastguard Worker #define BROTLI_DECODER_FREE(S, X) { \ 372*6777b538SAndroid Build Coastguard Worker S->free_func(S->memory_manager_opaque, X); \ 373*6777b538SAndroid Build Coastguard Worker X = NULL; \ 374*6777b538SAndroid Build Coastguard Worker } 375*6777b538SAndroid Build Coastguard Worker 376*6777b538SAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus) 377*6777b538SAndroid Build Coastguard Worker } /* extern "C" */ 378*6777b538SAndroid Build Coastguard Worker #endif 379*6777b538SAndroid Build Coastguard Worker 380*6777b538SAndroid Build Coastguard Worker #endif /* BROTLI_DEC_STATE_H_ */ 381