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