Initial commit
[io-compress-brotli.git] / dec / state.c
1 /* Copyright 2015 Google Inc. All Rights Reserved.
2
3 Distributed under MIT license.
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 */
6
7 #include "./huffman.h"
8 #include "./state.h"
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #if defined(__cplusplus) || defined(c_plusplus)
14 extern "C" {
15 #endif
16
17 static void* DefaultAllocFunc(void* opaque, size_t size) {
18 BROTLI_UNUSED(opaque);
19 return malloc(size);
20 }
21
22 static void DefaultFreeFunc(void* opaque, void* address) {
23 BROTLI_UNUSED(opaque);
24 free(address);
25 }
26
27 void BrotliStateInit(BrotliState* s) {
28 BrotliStateInitWithCustomAllocators(s, 0, 0, 0);
29 }
30
31 void BrotliStateInitWithCustomAllocators(BrotliState* s,
32 brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
33 if (!alloc_func) {
34 s->alloc_func = DefaultAllocFunc;
35 s->free_func = DefaultFreeFunc;
36 s->memory_manager_opaque = 0;
37 } else {
38 s->alloc_func = alloc_func;
39 s->free_func = free_func;
40 s->memory_manager_opaque = opaque;
41 }
42
43 BrotliInitBitReader(&s->br);
44 s->state = BROTLI_STATE_UNINITED;
45 s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
46 s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
47 s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
48 s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
49 s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
50 s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
51 s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
52
53 s->buffer_length = 0;
54 s->loop_counter = 0;
55 s->pos = 0;
56 s->rb_roundtrips = 0;
57 s->partial_pos_out = 0;
58
59 s->block_type_trees = NULL;
60 s->block_len_trees = NULL;
61 s->ringbuffer = NULL;
62
63 s->context_map = NULL;
64 s->context_modes = NULL;
65 s->dist_context_map = NULL;
66 s->context_map_slice = NULL;
67 s->dist_context_map_slice = NULL;
68
69 s->sub_loop_counter = 0;
70
71 s->literal_hgroup.codes = NULL;
72 s->literal_hgroup.htrees = NULL;
73 s->insert_copy_hgroup.codes = NULL;
74 s->insert_copy_hgroup.htrees = NULL;
75 s->distance_hgroup.codes = NULL;
76 s->distance_hgroup.htrees = NULL;
77
78
79 s->custom_dict = NULL;
80 s->custom_dict_size = 0;
81
82 s->is_last_metablock = 0;
83 s->window_bits = 0;
84 s->max_distance = 0;
85 s->dist_rb[0] = 16;
86 s->dist_rb[1] = 15;
87 s->dist_rb[2] = 11;
88 s->dist_rb[3] = 4;
89 s->dist_rb_idx = 0;
90 s->block_type_trees = NULL;
91 s->block_len_trees = NULL;
92
93 /* Make small negative indexes addressable. */
94 s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
95
96 s->mtf_upper_bound = 255;
97
98 s->legacy_input_buffer = 0;
99 s->legacy_output_buffer = 0;
100 s->legacy_input_len = 0;
101 s->legacy_output_len = 0;
102 s->legacy_input_pos = 0;
103 s->legacy_output_pos = 0;
104 }
105
106 void BrotliStateMetablockBegin(BrotliState* s) {
107 s->meta_block_remaining_len = 0;
108 s->block_length[0] = 1U << 28;
109 s->block_length[1] = 1U << 28;
110 s->block_length[2] = 1U << 28;
111 s->num_block_types[0] = 1;
112 s->num_block_types[1] = 1;
113 s->num_block_types[2] = 1;
114 s->block_type_rb[0] = 1;
115 s->block_type_rb[1] = 0;
116 s->block_type_rb[2] = 1;
117 s->block_type_rb[3] = 0;
118 s->block_type_rb[4] = 1;
119 s->block_type_rb[5] = 0;
120 s->context_map = NULL;
121 s->context_modes = NULL;
122 s->dist_context_map = NULL;
123 s->context_map_slice = NULL;
124 s->literal_htree_index = 0;
125 s->literal_htree = NULL;
126 s->dist_context_map_slice = NULL;
127 s->dist_htree_index = 0;
128 s->context_lookup1 = NULL;
129 s->context_lookup2 = NULL;
130 s->literal_hgroup.codes = NULL;
131 s->literal_hgroup.htrees = NULL;
132 s->insert_copy_hgroup.codes = NULL;
133 s->insert_copy_hgroup.htrees = NULL;
134 s->distance_hgroup.codes = NULL;
135 s->distance_hgroup.htrees = NULL;
136 }
137
138 void BrotliStateCleanupAfterMetablock(BrotliState* s) {
139 BROTLI_FREE(s, s->context_modes);
140 BROTLI_FREE(s, s->context_map);
141 BROTLI_FREE(s, s->dist_context_map);
142
143 BrotliHuffmanTreeGroupRelease(s, &s->literal_hgroup);
144 BrotliHuffmanTreeGroupRelease(s, &s->insert_copy_hgroup);
145 BrotliHuffmanTreeGroupRelease(s, &s->distance_hgroup);
146 }
147
148 void BrotliStateCleanup(BrotliState* s) {
149 BrotliStateCleanupAfterMetablock(s);
150
151 BROTLI_FREE(s, s->ringbuffer);
152 BROTLI_FREE(s, s->block_type_trees);
153 BROTLI_FREE(s, s->legacy_input_buffer);
154 BROTLI_FREE(s, s->legacy_output_buffer);
155 }
156
157 int BrotliStateIsStreamStart(const BrotliState* s) {
158 return (s->state == BROTLI_STATE_UNINITED &&
159 BrotliGetAvailableBits(&s->br) == 0);
160 }
161
162 int BrotliStateIsStreamEnd(const BrotliState* s) {
163 return s->state == BROTLI_STATE_DONE;
164 }
165
166 void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group,
167 uint32_t alphabet_size, uint32_t ntrees) {
168 /* Pack two allocations into one */
169 const size_t code_size =
170 sizeof(HuffmanCode) * (size_t)(ntrees * BROTLI_HUFFMAN_MAX_TABLE_SIZE);
171 const size_t htree_size = sizeof(HuffmanCode*) * (size_t)ntrees;
172 char *p = (char*)BROTLI_ALLOC(s, code_size + htree_size);
173 group->alphabet_size = (uint16_t)alphabet_size;
174 group->num_htrees = (uint16_t)ntrees;
175 group->codes = (HuffmanCode*)p;
176 group->htrees = (HuffmanCode**)(p + code_size);
177 }
178
179 void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group) {
180 BROTLI_FREE(s, group->codes);
181 group->htrees = NULL;
182 }
183
184 #if defined(__cplusplus) || defined(c_plusplus)
185 } /* extern "C" */
186 #endif
This page took 0.02585 seconds and 4 git commands to generate.