xref: /aosp_15_r20/external/cronet/third_party/brotli/dec/state.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #include "state.h"
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>  /* free, malloc */
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "../common/dictionary.h"
12*6777b538SAndroid Build Coastguard Worker #include <brotli/types.h>
13*6777b538SAndroid Build Coastguard Worker #include "huffman.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
16*6777b538SAndroid Build Coastguard Worker extern "C" {
17*6777b538SAndroid Build Coastguard Worker #endif
18*6777b538SAndroid Build Coastguard Worker 
BrotliDecoderStateInit(BrotliDecoderState * s,brotli_alloc_func alloc_func,brotli_free_func free_func,void * opaque)19*6777b538SAndroid Build Coastguard Worker BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
20*6777b538SAndroid Build Coastguard Worker     brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
21*6777b538SAndroid Build Coastguard Worker   if (!alloc_func) {
22*6777b538SAndroid Build Coastguard Worker     s->alloc_func = BrotliDefaultAllocFunc;
23*6777b538SAndroid Build Coastguard Worker     s->free_func = BrotliDefaultFreeFunc;
24*6777b538SAndroid Build Coastguard Worker     s->memory_manager_opaque = 0;
25*6777b538SAndroid Build Coastguard Worker   } else {
26*6777b538SAndroid Build Coastguard Worker     s->alloc_func = alloc_func;
27*6777b538SAndroid Build Coastguard Worker     s->free_func = free_func;
28*6777b538SAndroid Build Coastguard Worker     s->memory_manager_opaque = opaque;
29*6777b538SAndroid Build Coastguard Worker   }
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker   s->error_code = 0; /* BROTLI_DECODER_NO_ERROR */
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker   BrotliInitBitReader(&s->br);
34*6777b538SAndroid Build Coastguard Worker   s->state = BROTLI_STATE_UNINITED;
35*6777b538SAndroid Build Coastguard Worker   s->large_window = 0;
36*6777b538SAndroid Build Coastguard Worker   s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
37*6777b538SAndroid Build Coastguard Worker   s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
38*6777b538SAndroid Build Coastguard Worker   s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
39*6777b538SAndroid Build Coastguard Worker   s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker   s->buffer_length = 0;
42*6777b538SAndroid Build Coastguard Worker   s->loop_counter = 0;
43*6777b538SAndroid Build Coastguard Worker   s->pos = 0;
44*6777b538SAndroid Build Coastguard Worker   s->rb_roundtrips = 0;
45*6777b538SAndroid Build Coastguard Worker   s->partial_pos_out = 0;
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker   s->block_type_trees = NULL;
48*6777b538SAndroid Build Coastguard Worker   s->block_len_trees = NULL;
49*6777b538SAndroid Build Coastguard Worker   s->ringbuffer = NULL;
50*6777b538SAndroid Build Coastguard Worker   s->ringbuffer_size = 0;
51*6777b538SAndroid Build Coastguard Worker   s->new_ringbuffer_size = 0;
52*6777b538SAndroid Build Coastguard Worker   s->ringbuffer_mask = 0;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   s->context_map = NULL;
55*6777b538SAndroid Build Coastguard Worker   s->context_modes = NULL;
56*6777b538SAndroid Build Coastguard Worker   s->dist_context_map = NULL;
57*6777b538SAndroid Build Coastguard Worker   s->context_map_slice = NULL;
58*6777b538SAndroid Build Coastguard Worker   s->dist_context_map_slice = NULL;
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker   s->literal_hgroup.codes = NULL;
61*6777b538SAndroid Build Coastguard Worker   s->literal_hgroup.htrees = NULL;
62*6777b538SAndroid Build Coastguard Worker   s->insert_copy_hgroup.codes = NULL;
63*6777b538SAndroid Build Coastguard Worker   s->insert_copy_hgroup.htrees = NULL;
64*6777b538SAndroid Build Coastguard Worker   s->distance_hgroup.codes = NULL;
65*6777b538SAndroid Build Coastguard Worker   s->distance_hgroup.htrees = NULL;
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker   s->is_last_metablock = 0;
68*6777b538SAndroid Build Coastguard Worker   s->is_uncompressed = 0;
69*6777b538SAndroid Build Coastguard Worker   s->is_metadata = 0;
70*6777b538SAndroid Build Coastguard Worker   s->should_wrap_ringbuffer = 0;
71*6777b538SAndroid Build Coastguard Worker   s->canny_ringbuffer_allocation = 1;
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   s->window_bits = 0;
74*6777b538SAndroid Build Coastguard Worker   s->max_distance = 0;
75*6777b538SAndroid Build Coastguard Worker   s->dist_rb[0] = 16;
76*6777b538SAndroid Build Coastguard Worker   s->dist_rb[1] = 15;
77*6777b538SAndroid Build Coastguard Worker   s->dist_rb[2] = 11;
78*6777b538SAndroid Build Coastguard Worker   s->dist_rb[3] = 4;
79*6777b538SAndroid Build Coastguard Worker   s->dist_rb_idx = 0;
80*6777b538SAndroid Build Coastguard Worker   s->block_type_trees = NULL;
81*6777b538SAndroid Build Coastguard Worker   s->block_len_trees = NULL;
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   s->mtf_upper_bound = 63;
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker   s->compound_dictionary = NULL;
86*6777b538SAndroid Build Coastguard Worker   s->dictionary =
87*6777b538SAndroid Build Coastguard Worker       BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
88*6777b538SAndroid Build Coastguard Worker   if (!s->dictionary) return BROTLI_FALSE;
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   return BROTLI_TRUE;
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker 
BrotliDecoderStateMetablockBegin(BrotliDecoderState * s)93*6777b538SAndroid Build Coastguard Worker void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
94*6777b538SAndroid Build Coastguard Worker   s->meta_block_remaining_len = 0;
95*6777b538SAndroid Build Coastguard Worker   s->block_length[0] = 1U << 24;
96*6777b538SAndroid Build Coastguard Worker   s->block_length[1] = 1U << 24;
97*6777b538SAndroid Build Coastguard Worker   s->block_length[2] = 1U << 24;
98*6777b538SAndroid Build Coastguard Worker   s->num_block_types[0] = 1;
99*6777b538SAndroid Build Coastguard Worker   s->num_block_types[1] = 1;
100*6777b538SAndroid Build Coastguard Worker   s->num_block_types[2] = 1;
101*6777b538SAndroid Build Coastguard Worker   s->block_type_rb[0] = 1;
102*6777b538SAndroid Build Coastguard Worker   s->block_type_rb[1] = 0;
103*6777b538SAndroid Build Coastguard Worker   s->block_type_rb[2] = 1;
104*6777b538SAndroid Build Coastguard Worker   s->block_type_rb[3] = 0;
105*6777b538SAndroid Build Coastguard Worker   s->block_type_rb[4] = 1;
106*6777b538SAndroid Build Coastguard Worker   s->block_type_rb[5] = 0;
107*6777b538SAndroid Build Coastguard Worker   s->context_map = NULL;
108*6777b538SAndroid Build Coastguard Worker   s->context_modes = NULL;
109*6777b538SAndroid Build Coastguard Worker   s->dist_context_map = NULL;
110*6777b538SAndroid Build Coastguard Worker   s->context_map_slice = NULL;
111*6777b538SAndroid Build Coastguard Worker   s->literal_htree = NULL;
112*6777b538SAndroid Build Coastguard Worker   s->dist_context_map_slice = NULL;
113*6777b538SAndroid Build Coastguard Worker   s->dist_htree_index = 0;
114*6777b538SAndroid Build Coastguard Worker   s->context_lookup = NULL;
115*6777b538SAndroid Build Coastguard Worker   s->literal_hgroup.codes = NULL;
116*6777b538SAndroid Build Coastguard Worker   s->literal_hgroup.htrees = NULL;
117*6777b538SAndroid Build Coastguard Worker   s->insert_copy_hgroup.codes = NULL;
118*6777b538SAndroid Build Coastguard Worker   s->insert_copy_hgroup.htrees = NULL;
119*6777b538SAndroid Build Coastguard Worker   s->distance_hgroup.codes = NULL;
120*6777b538SAndroid Build Coastguard Worker   s->distance_hgroup.htrees = NULL;
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker 
BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState * s)123*6777b538SAndroid Build Coastguard Worker void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
124*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->context_modes);
125*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->context_map);
126*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->dist_context_map);
127*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->literal_hgroup.htrees);
128*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->insert_copy_hgroup.htrees);
129*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
130*6777b538SAndroid Build Coastguard Worker }
131*6777b538SAndroid Build Coastguard Worker 
BrotliDecoderStateCleanup(BrotliDecoderState * s)132*6777b538SAndroid Build Coastguard Worker void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
133*6777b538SAndroid Build Coastguard Worker   BrotliDecoderStateCleanupAfterMetablock(s);
134*6777b538SAndroid Build Coastguard Worker 
135*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->compound_dictionary);
136*6777b538SAndroid Build Coastguard Worker   BrotliSharedDictionaryDestroyInstance(s->dictionary);
137*6777b538SAndroid Build Coastguard Worker   s->dictionary = NULL;
138*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->ringbuffer);
139*6777b538SAndroid Build Coastguard Worker   BROTLI_DECODER_FREE(s, s->block_type_trees);
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker 
BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState * s,HuffmanTreeGroup * group,uint32_t alphabet_size_max,uint32_t alphabet_size_limit,uint32_t ntrees)142*6777b538SAndroid Build Coastguard Worker BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
143*6777b538SAndroid Build Coastguard Worker     HuffmanTreeGroup* group, uint32_t alphabet_size_max,
144*6777b538SAndroid Build Coastguard Worker     uint32_t alphabet_size_limit, uint32_t ntrees) {
145*6777b538SAndroid Build Coastguard Worker   /* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
146*6777b538SAndroid Build Coastguard Worker      This number is discovered "unlimited" "enough" calculator; it is actually
147*6777b538SAndroid Build Coastguard Worker      a wee bigger than required in several cases (especially for alphabets with
148*6777b538SAndroid Build Coastguard Worker      less than 16 symbols). */
149*6777b538SAndroid Build Coastguard Worker   const size_t max_table_size = alphabet_size_limit + 376;
150*6777b538SAndroid Build Coastguard Worker   const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
151*6777b538SAndroid Build Coastguard Worker   const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
152*6777b538SAndroid Build Coastguard Worker   /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
153*6777b538SAndroid Build Coastguard Worker   HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
154*6777b538SAndroid Build Coastguard Worker       code_size + htree_size);
155*6777b538SAndroid Build Coastguard Worker   group->alphabet_size_max = (uint16_t)alphabet_size_max;
156*6777b538SAndroid Build Coastguard Worker   group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
157*6777b538SAndroid Build Coastguard Worker   group->num_htrees = (uint16_t)ntrees;
158*6777b538SAndroid Build Coastguard Worker   group->htrees = p;
159*6777b538SAndroid Build Coastguard Worker   group->codes = (HuffmanCode*)(&p[ntrees]);
160*6777b538SAndroid Build Coastguard Worker   return !!p;
161*6777b538SAndroid Build Coastguard Worker }
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
164*6777b538SAndroid Build Coastguard Worker }  /* extern "C" */
165*6777b538SAndroid Build Coastguard Worker #endif
166