1 /* Copyright 2015 Google Inc. All Rights Reserved.
3 Distributed under MIT license.
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
13 #if defined(__cplusplus) || defined(c_plusplus)
17 static void* DefaultAllocFunc(void* opaque
, size_t size
) {
18 BROTLI_UNUSED(opaque
);
22 static void DefaultFreeFunc(void* opaque
, void* address
) {
23 BROTLI_UNUSED(opaque
);
27 void BrotliStateInit(BrotliState
* s
) {
28 BrotliStateInitWithCustomAllocators(s
, 0, 0, 0);
31 void BrotliStateInitWithCustomAllocators(BrotliState
* s
,
32 brotli_alloc_func alloc_func
, brotli_free_func free_func
, void* opaque
) {
34 s
->alloc_func
= DefaultAllocFunc
;
35 s
->free_func
= DefaultFreeFunc
;
36 s
->memory_manager_opaque
= 0;
38 s
->alloc_func
= alloc_func
;
39 s
->free_func
= free_func
;
40 s
->memory_manager_opaque
= opaque
;
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
;
57 s
->partial_pos_out
= 0;
59 s
->block_type_trees
= NULL
;
60 s
->block_len_trees
= NULL
;
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
;
69 s
->sub_loop_counter
= 0;
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
;
79 s
->custom_dict
= NULL
;
80 s
->custom_dict_size
= 0;
82 s
->is_last_metablock
= 0;
90 s
->block_type_trees
= NULL
;
91 s
->block_len_trees
= NULL
;
93 /* Make small negative indexes addressable. */
94 s
->symbol_lists
= &s
->symbols_lists_array
[BROTLI_HUFFMAN_MAX_CODE_LENGTH
+ 1];
96 s
->mtf_upper_bound
= 255;
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;
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
;
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
);
143 BrotliHuffmanTreeGroupRelease(s
, &s
->literal_hgroup
);
144 BrotliHuffmanTreeGroupRelease(s
, &s
->insert_copy_hgroup
);
145 BrotliHuffmanTreeGroupRelease(s
, &s
->distance_hgroup
);
148 void BrotliStateCleanup(BrotliState
* s
) {
149 BrotliStateCleanupAfterMetablock(s
);
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
);
157 int BrotliStateIsStreamStart(const BrotliState
* s
) {
158 return (s
->state
== BROTLI_STATE_UNINITED
&&
159 BrotliGetAvailableBits(&s
->br
) == 0);
162 int BrotliStateIsStreamEnd(const BrotliState
* s
) {
163 return s
->state
== BROTLI_STATE_DONE
;
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
);
179 void BrotliHuffmanTreeGroupRelease(BrotliState
* s
, HuffmanTreeGroup
* group
) {
180 BROTLI_FREE(s
, group
->codes
);
181 group
->htrees
= NULL
;
184 #if defined(__cplusplus) || defined(c_plusplus)