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