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