1 #![allow(non_camel_case_types)]
2 #![allow(non_snake_case)]
3 #![allow(non_upper_case_globals)]
4
5
6 use alloc;
7 use core;
8 use context::kContextLookup;
9 use bit_reader::{BrotliBitReader, BrotliGetAvailableBits, BrotliInitBitReader};
10 use huffman::{BROTLI_HUFFMAN_MAX_CODE_LENGTH, BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE,
11 BROTLI_HUFFMAN_MAX_TABLE_SIZE, HuffmanCode, HuffmanTreeGroup};
12 use alloc::SliceWrapper;
13
14 #[allow(dead_code)]
15 pub enum WhichTreeGroup {
16 LITERAL,
17 INSERT_COPY,
18 DISTANCE,
19 }
20 #[repr(C)]
21 #[derive(Clone,Copy, Debug)]
22 pub enum BrotliDecoderErrorCode{
23 BROTLI_DECODER_NO_ERROR = 0,
24 /* Same as BrotliDecoderResult values */
25 BROTLI_DECODER_SUCCESS = 1,
26 BROTLI_DECODER_NEEDS_MORE_INPUT = 2,
27 BROTLI_DECODER_NEEDS_MORE_OUTPUT = 3,
28
29 /* Errors caused by invalid input */
30 BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE = -1,
31 BROTLI_DECODER_ERROR_FORMAT_RESERVED = -2,
32 BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE = -3,
33 BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET = -4,
34 BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME = -5,
35 BROTLI_DECODER_ERROR_FORMAT_CL_SPACE = -6,
36 BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE = -7,
37 BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT = -8,
38 BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1 = -9,
39 BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2 = -10,
40 BROTLI_DECODER_ERROR_FORMAT_TRANSFORM = -11,
41 BROTLI_DECODER_ERROR_FORMAT_DICTIONARY = -12,
42 BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS = -13,
43 BROTLI_DECODER_ERROR_FORMAT_PADDING_1 = -14,
44 BROTLI_DECODER_ERROR_FORMAT_PADDING_2 = -15,
45 BROTLI_DECODER_ERROR_FORMAT_DISTANCE = -16,
46
47 /* -17..-18 codes are reserved */
48
49 BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET = -19,
50 BROTLI_DECODER_ERROR_INVALID_ARGUMENTS = -20,
51
52 /* Memory allocation problems */
53 BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES = -21,
54 /* Literal = insert and distance trees together */
55 BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS = -22,
56 /* -23..-24 codes are reserved for distinct tree groups */
57 BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP = -25,
58 BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1 = -26,
59 BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2 = -27,
60 /* -28..-29 codes are reserved for dynamic ring-buffer allocation */
61 BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES = -30,
62
63 /* "Impossible" states */
64 BROTLI_DECODER_ERROR_UNREACHABLE = -31,
65 }
66
67 #[derive(Debug)]
68 pub enum BrotliRunningState {
69 BROTLI_STATE_UNINITED,
70 BROTLI_STATE_LARGE_WINDOW_BITS,
71 BROTLI_STATE_INITIALIZE,
72 BROTLI_STATE_METABLOCK_BEGIN,
73 BROTLI_STATE_METABLOCK_HEADER,
74 BROTLI_STATE_METABLOCK_HEADER_2,
75 BROTLI_STATE_CONTEXT_MODES,
76 BROTLI_STATE_COMMAND_BEGIN,
77 BROTLI_STATE_COMMAND_INNER,
78 BROTLI_STATE_COMMAND_POST_DECODE_LITERALS,
79 BROTLI_STATE_COMMAND_POST_WRAP_COPY,
80 BROTLI_STATE_UNCOMPRESSED,
81 BROTLI_STATE_METADATA,
82 BROTLI_STATE_COMMAND_INNER_WRITE,
83 BROTLI_STATE_METABLOCK_DONE,
84 BROTLI_STATE_COMMAND_POST_WRITE_1,
85 BROTLI_STATE_COMMAND_POST_WRITE_2,
86 BROTLI_STATE_HUFFMAN_CODE_0,
87 BROTLI_STATE_HUFFMAN_CODE_1,
88 BROTLI_STATE_HUFFMAN_CODE_2,
89 BROTLI_STATE_HUFFMAN_CODE_3,
90 BROTLI_STATE_CONTEXT_MAP_1,
91 BROTLI_STATE_CONTEXT_MAP_2,
92 BROTLI_STATE_TREE_GROUP,
93 BROTLI_STATE_DONE,
94 }
95
96 pub enum BrotliRunningMetablockHeaderState {
97 BROTLI_STATE_METABLOCK_HEADER_NONE,
98 BROTLI_STATE_METABLOCK_HEADER_EMPTY,
99 BROTLI_STATE_METABLOCK_HEADER_NIBBLES,
100 BROTLI_STATE_METABLOCK_HEADER_SIZE,
101 BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED,
102 BROTLI_STATE_METABLOCK_HEADER_RESERVED,
103 BROTLI_STATE_METABLOCK_HEADER_BYTES,
104 BROTLI_STATE_METABLOCK_HEADER_METADATA,
105 }
106 pub enum BrotliRunningUncompressedState {
107 BROTLI_STATE_UNCOMPRESSED_NONE,
108 BROTLI_STATE_UNCOMPRESSED_WRITE,
109 }
110
111 pub enum BrotliRunningTreeGroupState {
112 BROTLI_STATE_TREE_GROUP_NONE,
113 BROTLI_STATE_TREE_GROUP_LOOP,
114 }
115
116 pub enum BrotliRunningContextMapState {
117 BROTLI_STATE_CONTEXT_MAP_NONE,
118 BROTLI_STATE_CONTEXT_MAP_READ_PREFIX,
119 BROTLI_STATE_CONTEXT_MAP_HUFFMAN,
120 BROTLI_STATE_CONTEXT_MAP_DECODE,
121 BROTLI_STATE_CONTEXT_MAP_TRANSFORM,
122 }
123
124 pub enum BrotliRunningHuffmanState {
125 BROTLI_STATE_HUFFMAN_NONE,
126 BROTLI_STATE_HUFFMAN_SIMPLE_SIZE,
127 BROTLI_STATE_HUFFMAN_SIMPLE_READ,
128 BROTLI_STATE_HUFFMAN_SIMPLE_BUILD,
129 BROTLI_STATE_HUFFMAN_COMPLEX,
130 BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS,
131 }
132
133 pub enum BrotliRunningDecodeUint8State {
134 BROTLI_STATE_DECODE_UINT8_NONE,
135 BROTLI_STATE_DECODE_UINT8_SHORT,
136 BROTLI_STATE_DECODE_UINT8_LONG,
137 }
138
139 pub enum BrotliRunningReadBlockLengthState {
140 BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
141 BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX,
142 }
143
144 pub const kLiteralContextBits: usize = 6;
145
146 pub struct BlockTypeAndLengthState<AllocHC: alloc::Allocator<HuffmanCode>> {
147 pub substate_read_block_length: BrotliRunningReadBlockLengthState,
148 pub num_block_types: [u32; 3],
149 pub block_length_index: u32,
150 pub block_length: [u32; 3],
151 pub block_type_trees: AllocHC::AllocatedMemory,
152 pub block_len_trees: AllocHC::AllocatedMemory,
153 pub block_type_rb: [u32; 6],
154 }
155
156 pub struct BrotliState<AllocU8: alloc::Allocator<u8>,
157 AllocU32: alloc::Allocator<u32>,
158 AllocHC: alloc::Allocator<HuffmanCode>>
159 {
160 pub state: BrotliRunningState,
161
162 // This counter is reused for several disjoint loops.
163 pub loop_counter: i32,
164 pub br: BrotliBitReader,
165 pub alloc_u8: AllocU8,
166 pub alloc_u32: AllocU32,
167 pub alloc_hc: AllocHC,
168 // void* memory_manager_opaque,
169 pub buffer: [u8; 8],
170 pub buffer_length: u32,
171 pub pos: i32,
172 pub max_backward_distance: i32,
173 pub max_backward_distance_minus_custom_dict_size: i32,
174 pub max_distance: i32,
175 pub ringbuffer_size: i32,
176 pub ringbuffer_mask: i32,
177 pub dist_rb_idx: i32,
178 pub dist_rb: [i32; 4],
179 pub ringbuffer: AllocU8::AllocatedMemory,
180 // pub ringbuffer_end : usize,
181 pub htree_command_index: u16,
182 pub context_lookup: &'static [u8;512],
183 pub context_map_slice_index: usize,
184 pub dist_context_map_slice_index: usize,
185
186 pub sub_loop_counter: u32,
187
188 // This ring buffer holds a few past copy distances that will be used by */
189 // some special distance codes.
190 pub literal_hgroup: HuffmanTreeGroup<AllocU32, AllocHC>,
191 pub insert_copy_hgroup: HuffmanTreeGroup<AllocU32, AllocHC>,
192 pub distance_hgroup: HuffmanTreeGroup<AllocU32, AllocHC>,
193 // This is true if the literal context map histogram type always matches the
194 // block type. It is then not needed to keep the context (faster decoding).
195 pub trivial_literal_context: i32,
196 // Distance context is actual after command is decoded and before distance
197 // is computed. After distance computation it is used as a temporary variable
198 pub distance_context: i32,
199 pub meta_block_remaining_len: i32,
200 pub block_type_length_state: BlockTypeAndLengthState<AllocHC>,
201 pub distance_postfix_bits: u32,
202 pub num_direct_distance_codes: u32,
203 pub distance_postfix_mask: i32,
204 pub num_dist_htrees: u32,
205 pub dist_context_map: AllocU8::AllocatedMemory,
206 // NOT NEEDED? the index below seems to supersede it pub literal_htree : AllocHC::AllocatedMemory,
207 pub literal_htree_index: u8,
208 pub dist_htree_index: u8,
209 pub large_window: bool,
210 pub should_wrap_ringbuffer: bool,
211 pub error_code: BrotliDecoderErrorCode,
212 pub repeat_code_len: u32,
213 pub prev_code_len: u32,
214
215 pub copy_length: i32,
216 pub distance_code: i32,
217
218 // For partial write operations
219 pub rb_roundtrips: usize, // How many times we went around the ringbuffer
220 pub partial_pos_out: usize, // How much output to the user in total (<= rb)
221
222 // For ReadHuffmanCode
223 pub symbol: u32,
224 pub repeat: u32,
225 pub space: u32,
226
227 pub table: [HuffmanCode; 32],
228 // List of of symbol chains.
229 pub symbol_lists_index: usize, // AllocU16::AllocatedMemory,
230 // Storage from symbol_lists.
231 pub symbols_lists_array: [u16; BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
232 BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE],
233 // Tails of symbol chains.
234 pub next_symbol: [i32; 32],
235 pub code_length_code_lengths: [u8; 18],
236 // Population counts for the code lengths
237 pub code_length_histo: [u16; 16],
238
239 // For HuffmanTreeGroupDecode
240 pub htree_index: i32,
241 pub htree_next_offset: u32,
242
243 // For DecodeContextMap
244 pub context_index: u32,
245 pub max_run_length_prefix: u32,
246 pub code: u32,
247 // always pre-allocated on state creation
248 pub context_map_table: AllocHC::AllocatedMemory,
249
250 // For InverseMoveToFrontTransform
251 pub mtf_upper_bound: u32,
252 pub mtf_or_error_string: Result<[u8; 256], [u8; 256]>,
253
254 // For custom dictionaries
255 pub custom_dict: AllocU8::AllocatedMemory,
256 pub custom_dict_size: i32,
257 // less used attributes are in the end of this struct */
258 // States inside function calls
259 pub substate_metablock_header: BrotliRunningMetablockHeaderState,
260 pub substate_tree_group: BrotliRunningTreeGroupState,
261 pub substate_context_map: BrotliRunningContextMapState,
262 pub substate_uncompressed: BrotliRunningUncompressedState,
263 pub substate_huffman: BrotliRunningHuffmanState,
264 pub substate_decode_uint8: BrotliRunningDecodeUint8State,
265
266 pub is_last_metablock: u8,
267 pub is_uncompressed: u8,
268 pub is_metadata: u8,
269 pub size_nibbles: u8,
270 pub window_bits: u32,
271
272 pub num_literal_htrees: u32,
273 pub context_map: AllocU8::AllocatedMemory,
274 pub context_modes: AllocU8::AllocatedMemory,
275 pub trivial_literal_contexts: [u32; 8],
276 }
277 macro_rules! make_brotli_state {
278 ($alloc_u8 : expr, $alloc_u32 : expr, $alloc_hc : expr, $custom_dict : expr, $custom_dict_len: expr) => (BrotliState::<AllocU8, AllocU32, AllocHC>{
279 state : BrotliRunningState::BROTLI_STATE_UNINITED,
280 loop_counter : 0,
281 br : BrotliBitReader::default(),
282 alloc_u8 : $alloc_u8,
283 alloc_u32 : $alloc_u32,
284 alloc_hc : $alloc_hc,
285 buffer : [0u8; 8],
286 buffer_length : 0,
287 pos : 0,
288 max_backward_distance : 0,
289 max_backward_distance_minus_custom_dict_size : 0,
290 max_distance : 0,
291 ringbuffer_size : 0,
292 ringbuffer_mask: 0,
293 dist_rb_idx : 0,
294 dist_rb : [16, 15, 11, 4],
295 ringbuffer : AllocU8::AllocatedMemory::default(),
296 htree_command_index : 0,
297 context_lookup : &kContextLookup[0],
298 context_map_slice_index : 0,
299 dist_context_map_slice_index : 0,
300 sub_loop_counter : 0,
301
302 literal_hgroup : HuffmanTreeGroup::<AllocU32, AllocHC>::default(),
303 insert_copy_hgroup : HuffmanTreeGroup::<AllocU32, AllocHC>::default(),
304 distance_hgroup : HuffmanTreeGroup::<AllocU32, AllocHC>::default(),
305 trivial_literal_context : 0,
306 distance_context : 0,
307 meta_block_remaining_len : 0,
308 block_type_length_state : BlockTypeAndLengthState::<AllocHC> {
309 block_length_index : 0,
310 block_length : [0; 3],
311 num_block_types : [0;3],
312 block_type_rb: [0;6],
313 substate_read_block_length : BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
314 block_type_trees : AllocHC::AllocatedMemory::default(),
315 block_len_trees : AllocHC::AllocatedMemory::default(),
316 },
317 distance_postfix_bits : 0,
318 num_direct_distance_codes : 0,
319 distance_postfix_mask : 0,
320 num_dist_htrees : 0,
321 dist_context_map : AllocU8::AllocatedMemory::default(),
322 //// not needed literal_htree : AllocHC::AllocatedMemory::default(),
323 literal_htree_index : 0,
324 dist_htree_index : 0,
325 repeat_code_len : 0,
326 prev_code_len : 0,
327 copy_length : 0,
328 distance_code : 0,
329 rb_roundtrips : 0, /* How many times we went around the ringbuffer */
330 partial_pos_out : 0, /* How much output to the user in total (<= rb) */
331 symbol : 0,
332 repeat : 0,
333 space : 0,
334 table : [HuffmanCode::default(); 32],
335 //symbol_lists: AllocU16::AllocatedMemory::default(),
336 symbol_lists_index : BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1,
337 symbols_lists_array : [0;BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
338 BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE],
339 next_symbol : [0; 32],
340 code_length_code_lengths : [0; 18],
341 code_length_histo : [0; 16],
342 htree_index : 0,
343 htree_next_offset : 0,
344
345 /* For DecodeContextMap */
346 context_index : 0,
347 max_run_length_prefix : 0,
348 code : 0,
349 context_map_table : AllocHC::AllocatedMemory::default(),
350
351 /* For InverseMoveToFrontTransform */
352 mtf_upper_bound : 255,
353 mtf_or_error_string : Ok([0; 256]),
354
355 /* For custom dictionaries */
356 custom_dict : $custom_dict,
357 custom_dict_size : $custom_dict_len as i32,
358
359 /* less used attributes are in the end of this struct */
360 /* States inside function calls */
361 substate_metablock_header : BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE,
362 substate_tree_group : BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_NONE,
363 substate_context_map : BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_NONE,
364 substate_uncompressed : BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_NONE,
365 substate_huffman : BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE,
366 substate_decode_uint8 : BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE,
367
368 is_last_metablock : 0,
369 is_uncompressed : 0,
370 is_metadata : 0,
371 size_nibbles : 0,
372 window_bits : 0,
373 large_window: false,
374 should_wrap_ringbuffer: false,
375 error_code: BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS,
376 num_literal_htrees : 0,
377 context_map : AllocU8::AllocatedMemory::default(),
378 context_modes : AllocU8::AllocatedMemory::default(),
379 trivial_literal_contexts : [0u32; 8],
380 }
381 );
382 }
383 impl <'brotli_state,
384 AllocU8 : alloc::Allocator<u8>,
385 AllocU32 : alloc::Allocator<u32>,
386 AllocHC : alloc::Allocator<HuffmanCode> > BrotliState<AllocU8, AllocU32, AllocHC> {
new(alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self387 pub fn new(alloc_u8 : AllocU8,
388 alloc_u32 : AllocU32,
389 alloc_hc : AllocHC) -> Self{
390 let mut retval = make_brotli_state!(alloc_u8, alloc_u32, alloc_hc, AllocU8::AllocatedMemory::default(), 0);
391 retval.large_window = true;
392 retval.context_map_table = retval.alloc_hc.alloc_cell(
393 BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
394 BrotliInitBitReader(&mut retval.br);
395 retval
396 }
new_with_custom_dictionary(alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, custom_dict: AllocU8::AllocatedMemory) -> Self397 pub fn new_with_custom_dictionary(alloc_u8 : AllocU8,
398 alloc_u32 : AllocU32,
399 alloc_hc : AllocHC,
400 custom_dict: AllocU8::AllocatedMemory) -> Self{
401 let custom_dict_len = custom_dict.slice().len();
402 let mut retval = make_brotli_state!(alloc_u8, alloc_u32, alloc_hc, custom_dict, custom_dict_len);
403 retval.context_map_table = retval.alloc_hc.alloc_cell(
404 BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
405 retval.large_window = true;
406 BrotliInitBitReader(&mut retval.br);
407 retval
408 }
new_strict(alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self409 pub fn new_strict(alloc_u8 : AllocU8,
410 alloc_u32 : AllocU32,
411 alloc_hc : AllocHC) -> Self{
412 let mut retval = make_brotli_state!(alloc_u8, alloc_u32, alloc_hc, AllocU8::AllocatedMemory::default(), 0);
413 retval.context_map_table = retval.alloc_hc.alloc_cell(
414 BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
415 retval.large_window = false;
416 BrotliInitBitReader(&mut retval.br);
417 retval
418 }
BrotliStateMetablockBegin(self : &mut Self)419 pub fn BrotliStateMetablockBegin(self : &mut Self) {
420 self.meta_block_remaining_len = 0;
421 self.block_type_length_state.block_length[0] = 1u32 << 24;
422 self.block_type_length_state.block_length[1] = 1u32 << 24;
423 self.block_type_length_state.block_length[2] = 1u32 << 24;
424 self.block_type_length_state.num_block_types[0] = 1;
425 self.block_type_length_state.num_block_types[1] = 1;
426 self.block_type_length_state.num_block_types[2] = 1;
427 self.block_type_length_state.block_type_rb[0] = 1;
428 self.block_type_length_state.block_type_rb[1] = 0;
429 self.block_type_length_state.block_type_rb[2] = 1;
430 self.block_type_length_state.block_type_rb[3] = 0;
431 self.block_type_length_state.block_type_rb[4] = 1;
432 self.block_type_length_state.block_type_rb[5] = 0;
433 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_map,
434 AllocU8::AllocatedMemory::default()));
435 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_modes,
436 AllocU8::AllocatedMemory::default()));
437 self.alloc_u8.free_cell(core::mem::replace(&mut self.dist_context_map,
438 AllocU8::AllocatedMemory::default()));
439 self.context_map_slice_index = 0;
440 self.literal_htree_index = 0;
441 self.dist_context_map_slice_index = 0;
442 self.dist_htree_index = 0;
443 self.context_lookup = &kContextLookup[0];
444 self.literal_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
445 self.insert_copy_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
446 self.distance_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
447 }
BrotliStateCleanupAfterMetablock(self : &mut Self)448 pub fn BrotliStateCleanupAfterMetablock(self : &mut Self) {
449 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_map,
450 AllocU8::AllocatedMemory::default()));
451 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_modes,
452 AllocU8::AllocatedMemory::default()));
453 self.alloc_u8.free_cell(core::mem::replace(&mut self.dist_context_map,
454 AllocU8::AllocatedMemory::default()));
455
456
457 self.literal_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
458 self.insert_copy_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
459 self.distance_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
460 }
461
BrotliStateCleanup(self : &mut Self)462 fn BrotliStateCleanup(self : &mut Self) {
463 self.BrotliStateCleanupAfterMetablock();
464 self.alloc_u8.free_cell(core::mem::replace(&mut self.ringbuffer,
465 AllocU8::AllocatedMemory::default()));
466 self.alloc_hc.free_cell(core::mem::replace(&mut self.block_type_length_state.block_type_trees,
467 AllocHC::AllocatedMemory::default()));
468 self.alloc_hc.free_cell(core::mem::replace(&mut self.block_type_length_state.block_len_trees,
469 AllocHC::AllocatedMemory::default()));
470 self.alloc_hc.free_cell(core::mem::replace(&mut self.context_map_table,
471 AllocHC::AllocatedMemory::default()));
472 self.alloc_u8.free_cell(core::mem::replace(&mut self.custom_dict,
473 AllocU8::AllocatedMemory::default()));
474
475 //FIXME?? BROTLI_FREE(s, s->legacy_input_buffer);
476 //FIXME?? BROTLI_FREE(s, s->legacy_output_buffer);
477 }
478
BrotliStateIsStreamStart(self : &Self) -> bool479 pub fn BrotliStateIsStreamStart(self : &Self) -> bool {
480 match self.state {
481 BrotliRunningState::BROTLI_STATE_UNINITED =>
482 BrotliGetAvailableBits(&self.br) == 0,
483 _ => false,
484 }
485 }
486
BrotliStateIsStreamEnd(self : &Self) -> bool487 pub fn BrotliStateIsStreamEnd(self : &Self) -> bool {
488 match self.state {
489 BrotliRunningState::BROTLI_STATE_DONE => true,
490 _ => false
491 }
492 }
BrotliHuffmanTreeGroupInit(self :&mut Self, group : WhichTreeGroup, alphabet_size : u16, max_symbol: u16, ntrees : u16)493 pub fn BrotliHuffmanTreeGroupInit(self :&mut Self, group : WhichTreeGroup,
494 alphabet_size : u16, max_symbol: u16, ntrees : u16) {
495 match group {
496 WhichTreeGroup::LITERAL => self.literal_hgroup.init(&mut self.alloc_u32,
497 &mut self.alloc_hc,
498 alphabet_size, max_symbol, ntrees),
499 WhichTreeGroup::INSERT_COPY => self.insert_copy_hgroup.init(&mut self.alloc_u32,
500 &mut self.alloc_hc,
501 alphabet_size, max_symbol, ntrees),
502 WhichTreeGroup::DISTANCE => self.distance_hgroup.init(&mut self.alloc_u32,
503 &mut self.alloc_hc,
504 alphabet_size, max_symbol, ntrees),
505 }
506 }
BrotliHuffmanTreeGroupRelease(self :&mut Self, group : WhichTreeGroup)507 pub fn BrotliHuffmanTreeGroupRelease(self :&mut Self, group : WhichTreeGroup) {
508 match group {
509 WhichTreeGroup::LITERAL => self.literal_hgroup.reset(&mut self.alloc_u32,
510 &mut self.alloc_hc),
511 WhichTreeGroup::INSERT_COPY => self.insert_copy_hgroup.reset(&mut self.alloc_u32,
512 &mut self.alloc_hc),
513 WhichTreeGroup::DISTANCE => self.distance_hgroup.reset(&mut self.alloc_u32,
514 &mut self.alloc_hc),
515 }
516 }
517 }
518
519 impl <'brotli_state,
520 AllocU8 : alloc::Allocator<u8>,
521 AllocU32 : alloc::Allocator<u32>,
522 AllocHC : alloc::Allocator<HuffmanCode> > Drop for BrotliState<AllocU8, AllocU32, AllocHC> {
drop(&mut self)523 fn drop(&mut self) {
524 self.BrotliStateCleanup();
525 }
526 }
527
528
529
BrotliDecoderErrorStr(c: BrotliDecoderErrorCode) -> &'static str530 pub fn BrotliDecoderErrorStr(c: BrotliDecoderErrorCode) -> &'static str {
531 match c {
532 BrotliDecoderErrorCode::BROTLI_DECODER_NO_ERROR => "NO_ERROR\0",
533 /* Same as BrotliDecoderResult values */
534 BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => "SUCCESS\0",
535 BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT => "NEEDS_MORE_INPUT\0",
536 BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT => "NEEDS_MORE_OUTPUT\0",
537
538 /* Errors caused by invalid input */
539 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE => "ERROR_FORMAT_EXUBERANT_NIBBLE\0",
540 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_RESERVED => "ERROR_FORMAT_RESERVED\0",
541 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE => "ERROR_FORMAT_EXUBERANT_META_NIBBLE\0",
542 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET => "ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET\0",
543 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME => "ERROR_FORMAT_SIMPLE_HUFFMAN_SAME\0",
544 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_CL_SPACE => "ERROR_FORMAT_FL_SPACE\0",
545 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE => "ERROR_FORMAT_HUFFMAN_SPACE\0",
546 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT => "ERROR_FORMAT_CONTEXT_MAP_REPEAT\0",
547 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1 =>"ERROR_FORMAT_BLOCK_LENGTH_1\0",
548 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2 =>"ERROR_FORMAT_BLOCK_LENGTH_2\0",
549 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_TRANSFORM => "ERROR_FORMAT_TRANSFORM\0",
550 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DICTIONARY =>"ERROR_FORMAT_DICTIONARY\0",
551 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS =>"ERROR_FORMAT_WINDOW_BITS\0",
552 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_PADDING_1 =>"ERROR_FORMAT_PADDING_1\0",
553 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_PADDING_2 =>"ERROR_FORMAT_PADDING_2\0",
554 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DISTANCE =>"ERROR_FORMAT_DISTANCE\0",
555
556 /* -17..-18 codes are reserved */
557
558 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET => "ERROR_DICTIONARY_NOT_SET\0",
559 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS => "ERROR_INVALID_ARGUMENTS\0",
560
561 /* Memory allocation problems */
562 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES => "ERROR_ALLOC_CONTEXT_MODES\0",
563 /* Literal => insert and distance trees together */
564 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS => "ERROR_ALLOC_TREE_GROUPS\0",
565 /* -23..-24 codes are reserved for distinct tree groups */
566 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP => "ERROR_ALLOC_CONTEXT_MAP\0",
567 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1 => "ERROR_ALLOC_RING_BUFFER_1\0",
568 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2 => "ERROR_ALLOC_RING_BUFFER_2\0",
569 /* -28..-29 codes are reserved for dynamic ring-buffer allocation */
570 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES => "ERROR_ALLOC_BLOCK_TYPE_TREES\0",
571
572 /* "Impossible" states */
573 BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE => "ERROR_UNREACHABLE\0",
574 }
575 }
576