1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4
5
6use alloc;
7use core;
8use bit_reader::{BrotliBitReader, BrotliGetAvailableBits, BrotliInitBitReader};
9use huffman::{HuffmanCode, HuffmanTreeGroup,
10 BROTLI_HUFFMAN_MAX_CODE_LENGTH, BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE,
11 BROTLI_HUFFMAN_MAX_TABLE_SIZE};
12
13#[allow(dead_code)]
14pub enum WhichTreeGroup {
15 LITERAL,
16 INSERT_COPY,
17 DISTANCE,
18}
19
20pub enum BrotliRunningState {
21 BROTLI_STATE_UNINITED,
22 BROTLI_STATE_METABLOCK_BEGIN,
23 BROTLI_STATE_METABLOCK_HEADER,
24 BROTLI_STATE_METABLOCK_HEADER_2,
25 BROTLI_STATE_CONTEXT_MODES,
26 BROTLI_STATE_COMMAND_BEGIN,
27 BROTLI_STATE_COMMAND_INNER,
28 BROTLI_STATE_COMMAND_POST_DECODE_LITERALS,
29 BROTLI_STATE_COMMAND_POST_WRAP_COPY,
30 BROTLI_STATE_UNCOMPRESSED,
31 BROTLI_STATE_METADATA,
32 BROTLI_STATE_COMMAND_INNER_WRITE,
33 BROTLI_STATE_METABLOCK_DONE,
34 BROTLI_STATE_COMMAND_POST_WRITE_1,
35 BROTLI_STATE_COMMAND_POST_WRITE_2,
36 BROTLI_STATE_HUFFMAN_CODE_0,
37 BROTLI_STATE_HUFFMAN_CODE_1,
38 BROTLI_STATE_HUFFMAN_CODE_2,
39 BROTLI_STATE_HUFFMAN_CODE_3,
40 BROTLI_STATE_CONTEXT_MAP_1,
41 BROTLI_STATE_CONTEXT_MAP_2,
42 BROTLI_STATE_TREE_GROUP,
43 BROTLI_STATE_DONE
44}
45
46pub enum BrotliRunningMetablockHeaderState {
47 BROTLI_STATE_METABLOCK_HEADER_NONE,
48 BROTLI_STATE_METABLOCK_HEADER_EMPTY,
49 BROTLI_STATE_METABLOCK_HEADER_NIBBLES,
50 BROTLI_STATE_METABLOCK_HEADER_SIZE,
51 BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED,
52 BROTLI_STATE_METABLOCK_HEADER_RESERVED,
53 BROTLI_STATE_METABLOCK_HEADER_BYTES,
54 BROTLI_STATE_METABLOCK_HEADER_METADATA
55}
56pub enum BrotliRunningUncompressedState {
57 BROTLI_STATE_UNCOMPRESSED_NONE,
58 BROTLI_STATE_UNCOMPRESSED_WRITE
59}
60
61pub enum BrotliRunningTreeGroupState {
62 BROTLI_STATE_TREE_GROUP_NONE,
63 BROTLI_STATE_TREE_GROUP_LOOP
64}
65
66pub enum BrotliRunningContextMapState {
67 BROTLI_STATE_CONTEXT_MAP_NONE,
68 BROTLI_STATE_CONTEXT_MAP_READ_PREFIX,
69 BROTLI_STATE_CONTEXT_MAP_HUFFMAN,
70 BROTLI_STATE_CONTEXT_MAP_DECODE,
71 BROTLI_STATE_CONTEXT_MAP_TRANSFORM,
72}
73
74pub enum BrotliRunningHuffmanState {
75 BROTLI_STATE_HUFFMAN_NONE,
76 BROTLI_STATE_HUFFMAN_SIMPLE_SIZE,
77 BROTLI_STATE_HUFFMAN_SIMPLE_READ,
78 BROTLI_STATE_HUFFMAN_SIMPLE_BUILD,
79 BROTLI_STATE_HUFFMAN_COMPLEX,
80 BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS
81}
82
83pub enum BrotliRunningDecodeUint8State {
84 BROTLI_STATE_DECODE_UINT8_NONE,
85 BROTLI_STATE_DECODE_UINT8_SHORT,
86 BROTLI_STATE_DECODE_UINT8_LONG
87}
88
89pub enum BrotliRunningReadBlockLengthState {
90 BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
91 BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
92}
93
94pub const kLiteralContextBits : usize = 6;
95
96pub struct BlockTypeAndLengthState<AllocHC : alloc::Allocator<HuffmanCode> > {
97 pub substate_read_block_length : BrotliRunningReadBlockLengthState,
98 pub num_block_types : [u32;3],
99 pub block_length_index : u32,
100 pub block_length : [u32; 3],
101 pub block_type_trees : AllocHC::AllocatedMemory,
102 pub block_len_trees : AllocHC::AllocatedMemory,
103 pub block_type_rb: [u32;6],
104
105}
106
107pub struct BrotliState<AllocU8 : alloc::Allocator<u8>,
108 AllocU32 : alloc::Allocator<u32>,
109 AllocHC : alloc::Allocator<HuffmanCode> > {
110 pub state : BrotliRunningState,
111
112 pub loop_counter : i32,
114 pub br : BrotliBitReader,
115 pub alloc_u8 : AllocU8,
116 pub alloc_u32 : AllocU32,
117 pub alloc_hc : AllocHC,
118 pub buffer : [u8;8],
120 pub buffer_length : u32,
121 pub pos : i32,
122 pub max_backward_distance : i32,
123 pub max_backward_distance_minus_custom_dict_size : i32,
124 pub max_distance : i32,
125 pub ringbuffer_size: i32,
126 pub ringbuffer_mask: i32,
127 pub dist_rb_idx : i32,
128 pub dist_rb : [i32;4],
129 pub ringbuffer : AllocU8::AllocatedMemory,
130 pub htree_command_index : u16,
132 pub context_lookup1 : &'static [u8],
133 pub context_lookup2 : &'static [u8],
134 pub context_map_slice_index : usize,
135 pub dist_context_map_slice_index : usize,
136
137 pub sub_loop_counter : u32,
138
139 pub literal_hgroup : HuffmanTreeGroup<AllocU32, AllocHC>,
142 pub insert_copy_hgroup : HuffmanTreeGroup<AllocU32, AllocHC>,
143 pub distance_hgroup : HuffmanTreeGroup<AllocU32, AllocHC>,
144 pub trivial_literal_context : i32,
147 pub distance_context : i32,
148 pub meta_block_remaining_len : i32,
149 pub block_type_length_state : BlockTypeAndLengthState<AllocHC>,
150 pub distance_postfix_bits : u32,
151 pub num_direct_distance_codes : u32,
152 pub distance_postfix_mask : i32,
153 pub num_dist_htrees : u32,
154 pub dist_context_map : AllocU8::AllocatedMemory,
155 pub literal_htree_index : u8,
157 pub dist_htree_index : u8,
158 pub repeat_code_len : u32,
159 pub prev_code_len : u32,
160
161
162 pub copy_length : i32,
163 pub distance_code : i32,
164
165 pub rb_roundtrips : usize, pub partial_pos_out : usize, pub symbol : u32,
171 pub repeat : u32,
172 pub space : u32,
173
174 pub table : [HuffmanCode;32],
175 pub symbol_lists_index : usize, pub symbols_lists_array : [u16; BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
179 BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE],
180 pub next_symbol: [i32; 32],
182 pub code_length_code_lengths : [u8;18],
183 pub code_length_histo : [u16;16],
185
186 pub htree_index : i32,
188 pub htree_next_offset : u32,
189
190 pub context_index : u32,
192 pub max_run_length_prefix : u32,
193 pub code : u32,
194 pub context_map_table : AllocHC::AllocatedMemory,
196
197 pub mtf_upper_bound : u32,
199 pub mtf : [u8; 256],
200
201 pub custom_dict : AllocU8::AllocatedMemory,
203 pub custom_dict_size : i32,
204 pub substate_metablock_header : BrotliRunningMetablockHeaderState,
207 pub substate_tree_group : BrotliRunningTreeGroupState,
208 pub substate_context_map : BrotliRunningContextMapState,
209 pub substate_uncompressed : BrotliRunningUncompressedState,
210 pub substate_huffman : BrotliRunningHuffmanState,
211 pub substate_decode_uint8 : BrotliRunningDecodeUint8State,
212
213 pub is_last_metablock : u8,
214 pub is_uncompressed : u8,
215 pub is_metadata : u8,
216 pub size_nibbles : u8,
217 pub window_bits : u32,
218
219 pub num_literal_htrees : u32,
220 pub context_map : AllocU8::AllocatedMemory, pub context_modes : AllocU8::AllocatedMemory,}
224
225impl <'brotli_state,
226 AllocU8 : alloc::Allocator<u8>,
227 AllocU32 : alloc::Allocator<u32>,
228 AllocHC : alloc::Allocator<HuffmanCode> > BrotliState<AllocU8, AllocU32, AllocHC> {
229 pub fn new(alloc_u8 : AllocU8,
230 alloc_u32 : AllocU32,
231 alloc_hc : AllocHC) -> Self{
232 let mut retval = BrotliState::<AllocU8, AllocU32, AllocHC>{
233 state : BrotliRunningState::BROTLI_STATE_UNINITED,
234 loop_counter : 0,
235 br : BrotliBitReader::default(),
236 alloc_u8 : alloc_u8,
237 alloc_u32 : alloc_u32,
238 alloc_hc : alloc_hc,
239 buffer : [0u8; 8],
240 buffer_length : 0,
241 pos : 0,
242 max_backward_distance : 0,
243 max_backward_distance_minus_custom_dict_size : 0,
244 max_distance : 0,
245 ringbuffer_size : 0,
246 ringbuffer_mask: 0,
247 dist_rb_idx : 0,
248 dist_rb : [16, 15, 11, 4],
249 ringbuffer : AllocU8::AllocatedMemory::default(),
250 htree_command_index : 0,
251 context_lookup1 : &[],
252 context_lookup2 : &[],
253 context_map_slice_index : 0,
254 dist_context_map_slice_index : 0,
255 sub_loop_counter : 0,
256
257 literal_hgroup : HuffmanTreeGroup::<AllocU32, AllocHC>::default(),
258 insert_copy_hgroup : HuffmanTreeGroup::<AllocU32, AllocHC>::default(),
259 distance_hgroup : HuffmanTreeGroup::<AllocU32, AllocHC>::default(),
260 trivial_literal_context : 0,
261 distance_context : 0,
262 meta_block_remaining_len : 0,
263 block_type_length_state : BlockTypeAndLengthState::<AllocHC> {
264 block_length_index : 0,
265 block_length : [0; 3],
266 num_block_types : [0;3],
267 block_type_rb: [0;6],
268 substate_read_block_length : BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
269 block_type_trees : AllocHC::AllocatedMemory::default(),
270 block_len_trees : AllocHC::AllocatedMemory::default(),
271 },
272 distance_postfix_bits : 0,
273 num_direct_distance_codes : 0,
274 distance_postfix_mask : 0,
275 num_dist_htrees : 0,
276 dist_context_map : AllocU8::AllocatedMemory::default(),
277 literal_htree_index : 0,
279 dist_htree_index : 0,
280 repeat_code_len : 0,
281 prev_code_len : 0,
282 copy_length : 0,
283 distance_code : 0,
284 rb_roundtrips : 0, partial_pos_out : 0, symbol : 0,
287 repeat : 0,
288 space : 0,
289 table : [HuffmanCode::default(); 32],
290 symbol_lists_index : BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1,
292 symbols_lists_array : [0;BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
293 BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE],
294 next_symbol : [0; 32],
295 code_length_code_lengths : [0; 18],
296 code_length_histo : [0; 16],
297 htree_index : 0,
298 htree_next_offset : 0,
299
300 context_index : 0,
302 max_run_length_prefix : 0,
303 code : 0,
304 context_map_table : AllocHC::AllocatedMemory::default(),
305
306 mtf_upper_bound : 255,
308 mtf : [0; 256],
309
310 custom_dict : AllocU8::AllocatedMemory::default(),
312 custom_dict_size : 0,
313
314 substate_metablock_header : BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE,
317 substate_tree_group : BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_NONE,
318 substate_context_map : BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_NONE,
319 substate_uncompressed : BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_NONE,
320 substate_huffman : BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE,
321 substate_decode_uint8 : BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE,
322
323 is_last_metablock : 0,
324 is_uncompressed : 0,
325 is_metadata : 0,
326 size_nibbles : 0,
327 window_bits : 0,
328
329 num_literal_htrees : 0,
330 context_map : AllocU8::AllocatedMemory::default(),context_modes : AllocU8::AllocatedMemory::default(),};
333 retval.context_map_table = retval.alloc_hc.alloc_cell(BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
334 BrotliInitBitReader(&mut retval.br);
335 return retval;
336 }
337 pub fn BrotliStateMetablockBegin(self : &mut Self) {
338 self.meta_block_remaining_len = 0;
339 self.block_type_length_state.block_length[0] = 1u32 << 28;
340 self.block_type_length_state.block_length[1] = 1u32 << 28;
341 self.block_type_length_state.block_length[2] = 1u32 << 28;
342 self.block_type_length_state.num_block_types[0] = 1;
343 self.block_type_length_state.num_block_types[1] = 1;
344 self.block_type_length_state.num_block_types[2] = 1;
345 self.block_type_length_state.block_type_rb[0] = 1;
346 self.block_type_length_state.block_type_rb[1] = 0;
347 self.block_type_length_state.block_type_rb[2] = 1;
348 self.block_type_length_state.block_type_rb[3] = 0;
349 self.block_type_length_state.block_type_rb[4] = 1;
350 self.block_type_length_state.block_type_rb[5] = 0;
351 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_map,
352 AllocU8::AllocatedMemory::default()));
353 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_modes,
354 AllocU8::AllocatedMemory::default()));
355 self.alloc_u8.free_cell(core::mem::replace(&mut self.dist_context_map,
356 AllocU8::AllocatedMemory::default()));
357 self.context_map_slice_index = 0;
358 self.literal_htree_index = 0;
359 self.dist_context_map_slice_index = 0;
360 self.dist_htree_index = 0;
361 self.context_lookup1 = &[];
362 self.context_lookup2 = &[];
363 self.literal_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
364 self.insert_copy_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
365 self.distance_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
366 }
367 pub fn BrotliStateCleanupAfterMetablock(self : &mut Self) {
368 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_map,
369 AllocU8::AllocatedMemory::default()));
370 self.alloc_u8.free_cell(core::mem::replace(&mut self.context_modes,
371 AllocU8::AllocatedMemory::default()));
372 self.alloc_u8.free_cell(core::mem::replace(&mut self.dist_context_map,
373 AllocU8::AllocatedMemory::default()));
374
375
376 self.literal_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
377 self.insert_copy_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
378 self.distance_hgroup.reset(&mut self.alloc_u32, &mut self.alloc_hc);
379 }
380
381 pub fn BrotliStateCleanup(self : &mut Self) {
382 self.BrotliStateCleanupAfterMetablock();
383 self.alloc_u8.free_cell(core::mem::replace(&mut self.ringbuffer,
384 AllocU8::AllocatedMemory::default()));
385 self.alloc_hc.free_cell(core::mem::replace(&mut self.block_type_length_state.block_type_trees,
386 AllocHC::AllocatedMemory::default()));
387 self.alloc_hc.free_cell(core::mem::replace(&mut self.block_type_length_state.block_len_trees,
388 AllocHC::AllocatedMemory::default()));
389 self.alloc_hc.free_cell(core::mem::replace(&mut self.context_map_table,
390 AllocHC::AllocatedMemory::default()));
391
392 }
395
396 pub fn BrotliStateIsStreamStart(self : &Self) -> bool {
397 match self.state {
398 BrotliRunningState::BROTLI_STATE_UNINITED =>
399 return BrotliGetAvailableBits(&self.br) == 0,
400 _ => return false,
401 }
402 }
403
404 pub fn BrotliStateIsStreamEnd(self : &Self) -> bool {
405 match self.state {
406 BrotliRunningState::BROTLI_STATE_DONE => return true,
407 _ => return false,
408 }
409 }
410 pub fn BrotliHuffmanTreeGroupInit(self :&mut Self, group : WhichTreeGroup,
411 alphabet_size : u16, ntrees : u16) {
412 match group {
413 WhichTreeGroup::LITERAL => self.literal_hgroup.init(&mut self.alloc_u32,
414 &mut self.alloc_hc,
415 alphabet_size, ntrees),
416 WhichTreeGroup::INSERT_COPY => self.insert_copy_hgroup.init(&mut self.alloc_u32,
417 &mut self.alloc_hc,
418 alphabet_size, ntrees),
419 WhichTreeGroup::DISTANCE => self.distance_hgroup.init(&mut self.alloc_u32,
420 &mut self.alloc_hc,
421 alphabet_size, ntrees),
422 }
423 }
424 pub fn BrotliHuffmanTreeGroupRelease(self :&mut Self, group : WhichTreeGroup) {
425 match group {
426 WhichTreeGroup::LITERAL => self.literal_hgroup.reset(&mut self.alloc_u32,
427 &mut self.alloc_hc),
428 WhichTreeGroup::INSERT_COPY => self.insert_copy_hgroup.reset(&mut self.alloc_u32,
429 &mut self.alloc_hc),
430 WhichTreeGroup::DISTANCE => self.distance_hgroup.reset(&mut self.alloc_u32,
431 &mut self.alloc_hc),
432 }
433 }
434}