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
9 //#include <stdlib.h> /* free, malloc */
10 #include <BrotliDecompressLibInternal.h>
12 #include "../common/types.h"
13 #include "./huffman.h"
15 #if defined(__cplusplus) || defined(c_plusplus)
19 static void* DefaultAllocFunc(void* opaque
, size_t size
) {
20 BROTLI_UNUSED(opaque
);
21 return BrDummyMalloc(size
);
24 static void DefaultFreeFunc(void* opaque
, void* address
) {
25 BROTLI_UNUSED(opaque
);
29 void BrotliDecoderStateInit(BrotliDecoderState
* s
) {
30 BrotliDecoderStateInitWithCustomAllocators(s
, 0, 0, 0);
33 void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState
* s
,
34 brotli_alloc_func alloc_func
, brotli_free_func free_func
, void* opaque
) {
36 s
->alloc_func
= DefaultAllocFunc
;
37 s
->free_func
= DefaultFreeFunc
;
38 s
->memory_manager_opaque
= 0;
40 s
->alloc_func
= alloc_func
;
41 s
->free_func
= free_func
;
42 s
->memory_manager_opaque
= opaque
;
45 BrotliInitBitReader(&s
->br
);
46 s
->state
= BROTLI_STATE_UNINITED
;
47 s
->substate_metablock_header
= BROTLI_STATE_METABLOCK_HEADER_NONE
;
48 s
->substate_tree_group
= BROTLI_STATE_TREE_GROUP_NONE
;
49 s
->substate_context_map
= BROTLI_STATE_CONTEXT_MAP_NONE
;
50 s
->substate_uncompressed
= BROTLI_STATE_UNCOMPRESSED_NONE
;
51 s
->substate_huffman
= BROTLI_STATE_HUFFMAN_NONE
;
52 s
->substate_decode_uint8
= BROTLI_STATE_DECODE_UINT8_NONE
;
53 s
->substate_read_block_length
= BROTLI_STATE_READ_BLOCK_LENGTH_NONE
;
59 s
->partial_pos_out
= 0;
61 s
->block_type_trees
= NULL
;
62 s
->block_len_trees
= NULL
;
65 s
->context_map
= NULL
;
66 s
->context_modes
= NULL
;
67 s
->dist_context_map
= NULL
;
68 s
->context_map_slice
= NULL
;
69 s
->dist_context_map_slice
= NULL
;
71 s
->sub_loop_counter
= 0;
73 s
->literal_hgroup
.codes
= NULL
;
74 s
->literal_hgroup
.htrees
= NULL
;
75 s
->insert_copy_hgroup
.codes
= NULL
;
76 s
->insert_copy_hgroup
.htrees
= NULL
;
77 s
->distance_hgroup
.codes
= NULL
;
78 s
->distance_hgroup
.htrees
= NULL
;
80 s
->custom_dict
= NULL
;
81 s
->custom_dict_size
= 0;
83 s
->is_last_metablock
= 0;
91 s
->block_type_trees
= NULL
;
92 s
->block_len_trees
= NULL
;
94 /* Make small negative indexes addressable. */
95 s
->symbol_lists
= &s
->symbols_lists_array
[BROTLI_HUFFMAN_MAX_CODE_LENGTH
+ 1];
97 s
->mtf_upper_bound
= 255;
100 void BrotliDecoderStateMetablockBegin(BrotliDecoderState
* s
) {
101 s
->meta_block_remaining_len
= 0;
102 s
->block_length
[0] = 1U << 28;
103 s
->block_length
[1] = 1U << 28;
104 s
->block_length
[2] = 1U << 28;
105 s
->num_block_types
[0] = 1;
106 s
->num_block_types
[1] = 1;
107 s
->num_block_types
[2] = 1;
108 s
->block_type_rb
[0] = 1;
109 s
->block_type_rb
[1] = 0;
110 s
->block_type_rb
[2] = 1;
111 s
->block_type_rb
[3] = 0;
112 s
->block_type_rb
[4] = 1;
113 s
->block_type_rb
[5] = 0;
114 s
->context_map
= NULL
;
115 s
->context_modes
= NULL
;
116 s
->dist_context_map
= NULL
;
117 s
->context_map_slice
= NULL
;
118 s
->literal_htree
= NULL
;
119 s
->dist_context_map_slice
= NULL
;
120 s
->dist_htree_index
= 0;
121 s
->context_lookup1
= NULL
;
122 s
->context_lookup2
= NULL
;
123 s
->literal_hgroup
.codes
= NULL
;
124 s
->literal_hgroup
.htrees
= NULL
;
125 s
->insert_copy_hgroup
.codes
= NULL
;
126 s
->insert_copy_hgroup
.htrees
= NULL
;
127 s
->distance_hgroup
.codes
= NULL
;
128 s
->distance_hgroup
.htrees
= NULL
;
131 void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState
* s
) {
132 BROTLI_FREE(s
, s
->context_modes
);
133 BROTLI_FREE(s
, s
->context_map
);
134 BROTLI_FREE(s
, s
->dist_context_map
);
136 BrotliDecoderHuffmanTreeGroupRelease(s
, &s
->literal_hgroup
);
137 BrotliDecoderHuffmanTreeGroupRelease(s
, &s
->insert_copy_hgroup
);
138 BrotliDecoderHuffmanTreeGroupRelease(s
, &s
->distance_hgroup
);
141 void BrotliDecoderStateCleanup(BrotliDecoderState
* s
) {
142 BrotliDecoderStateCleanupAfterMetablock(s
);
144 BROTLI_FREE(s
, s
->ringbuffer
);
145 BROTLI_FREE(s
, s
->block_type_trees
);
148 void BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState
* s
,
149 HuffmanTreeGroup
* group
, uint32_t alphabet_size
, uint32_t ntrees
) {
150 /* Pack two allocations into one */
151 const size_t max_table_size
= kMaxHuffmanTableSize
[(alphabet_size
+ 31) >> 5];
152 const size_t code_size
= sizeof(HuffmanCode
) * ntrees
* max_table_size
;
153 const size_t htree_size
= sizeof(HuffmanCode
*) * ntrees
;
154 char* p
= (char*)BROTLI_ALLOC(s
, code_size
+ htree_size
);
155 group
->alphabet_size
= (uint16_t)alphabet_size
;
156 group
->num_htrees
= (uint16_t)ntrees
;
157 group
->codes
= (HuffmanCode
*)p
;
158 group
->htrees
= (HuffmanCode
**)(p
+ code_size
);
161 void BrotliDecoderHuffmanTreeGroupRelease(
162 BrotliDecoderState
* s
, HuffmanTreeGroup
* group
) {
163 BROTLI_FREE(s
, group
->codes
);
164 group
->htrees
= NULL
;
167 #if defined(__cplusplus) || defined(c_plusplus)