1#![allow(non_snake_case)]
2#![allow(non_upper_case_globals)]
3mod tests;
4use ::core;
5use alloc;
6use alloc::SliceWrapper;
7use alloc::SliceWrapperMut;
8use core::default::Default;
9pub const BROTLI_HUFFMAN_MAX_CODE_LENGTH : usize = 15;
10
11pub const BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE : usize = 704;
13
14pub const BROTLI_HUFFMAN_MAX_TABLE_SIZE : u32 = 1080;
24pub const BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH : u32 = 5;
25
26#[derive(PartialEq, Copy, Clone, Debug)]
27pub struct HuffmanCode {
28 pub bits : u8, pub value : u16, }
31impl HuffmanCode {
32 pub fn eq(&self, other: &Self) -> bool {
33 return self.value == other.value && self.bits == other.bits;
34 }
35}
36
37impl Default for HuffmanCode {
38 fn default() -> Self {
39 return HuffmanCode { value : 0, bits : 0};
40 }
41}
42
43pub struct HuffmanTreeGroup<Alloc32 : alloc::Allocator<u32>,
45 AllocHC : alloc::Allocator<HuffmanCode>> {
46 pub htrees : Alloc32::AllocatedMemory,
47 pub codes : AllocHC::AllocatedMemory,
48 pub alphabet_size : u16,
49 pub num_htrees : u16,
50}
51impl<AllocU32 : alloc::Allocator<u32>,
52 AllocHC : alloc::Allocator<HuffmanCode> > HuffmanTreeGroup<AllocU32, AllocHC> {
53 pub fn init(self : &mut Self, mut alloc_u32 : &mut AllocU32, mut alloc_hc : &mut AllocHC,
54 alphabet_size : u16, ntrees : u16) {
55 self.reset(&mut alloc_u32, &mut alloc_hc);
56 self.alphabet_size = alphabet_size;
57 self.num_htrees = ntrees;
58 core::mem::replace(&mut self.htrees,
59 alloc_u32.alloc_cell(ntrees as usize));
60 core::mem::replace(&mut self.codes,
61 alloc_hc.alloc_cell(ntrees as usize * BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize));
62 }
63
64#[allow(dead_code)]
73 pub fn get_tree_mut<'a>(self :&'a mut Self, index : u32) -> &'a mut [HuffmanCode] {
74 let start : usize = self.htrees.slice()[index as usize] as usize;
75 return &mut self.codes.slice_mut()[start..];
76 }
77 #[allow(dead_code)]
78 pub fn get_tree<'a>(self :&'a Self, index : u32) -> &'a [HuffmanCode] {
79 let start : usize = self.htrees.slice()[index as usize] as usize;
80 return & self.codes.slice()[start..];
81 }
82 pub fn reset(self : &mut Self, alloc_u32 : &mut AllocU32, alloc_hc : &mut AllocHC) {
83 alloc_u32.free_cell(core::mem::replace(&mut self.htrees,
84 AllocU32::AllocatedMemory::default()));
85 alloc_hc.free_cell(core::mem::replace(&mut self.codes,
86 AllocHC::AllocatedMemory::default()));
87
88 }
96 pub fn build_hgroup_cache<'a>(self : &'a Self) -> [&'a [HuffmanCode]; 256] {
97 let mut ret : [&'a [HuffmanCode]; 256] = [&[]; 256];
98 let mut index : usize = 0;
99 for htree in self.htrees.slice() {
100 ret[index] = &self.codes.slice()[*htree as usize .. ];
101 index += 1;
102 }
103 return ret;
104 }
105}
106
107impl<AllocU32 : alloc::Allocator<u32>,
108 AllocHC : alloc::Allocator<HuffmanCode> > Default for HuffmanTreeGroup<AllocU32, AllocHC> {
109 fn default() -> Self {
110 return HuffmanTreeGroup::<AllocU32, AllocHC> {
111 htrees : AllocU32::AllocatedMemory::default(),
112 codes : AllocHC::AllocatedMemory::default(),
113 alphabet_size : 0,
114 num_htrees : 0,
115 };
116 }
117}
118
119
120
121const BROTLI_REVERSE_BITS_MAX : usize = 8;
122
123const BROTLI_REVERSE_BITS_BASE: u8 = 0;
124const kReverseBits : [u8; (1 << BROTLI_REVERSE_BITS_MAX)] = [
125 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
126 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
127 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
128 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
129 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
130 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
131 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
132 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
133 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
134 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
135 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
136 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
137 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
138 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
139 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
140 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
141 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
142 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
143 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
144 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
145 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
146 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
147 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
148 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
149 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
150 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
151 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
152 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
153 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
154 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
155 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
156 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
157];
158
159const BROTLI_REVERSE_BITS_LOWEST : u32 =
160 (1u32 << (BROTLI_REVERSE_BITS_MAX as u32 - 1 + BROTLI_REVERSE_BITS_BASE as u32));
161
162fn BrotliReverseBits(num : u32) -> u32{
166 return kReverseBits[num as usize] as u32;
167}
168
169fn ReplicateValue(table : &mut [HuffmanCode],
172 offset :usize,
173 step : i32,
174 mut end : i32,
175 code : HuffmanCode) {
176 loop {
177 end -= step;
178 table[offset + end as usize] = code;
179 if end <= 0 {
180 break;
181 }
182 };
183}
184
185fn NextTableBitSize(count : &[u16],
189 mut len : i32, root_bits : i32) -> i32{
190 let mut left : i32 = 1 << (len - root_bits);
191 while len < BROTLI_HUFFMAN_MAX_CODE_LENGTH as i32 {
192 left -= count[len as usize] as i32;
193 if left <= 0 {
194 break;
195 }
196 len += 1;
197 left <<= 1;
198 }
199 return len - root_bits;
200}
201
202
203pub fn BrotliBuildCodeLengthsHuffmanTable(mut table : &mut [HuffmanCode],
204 code_lengths : &[u8],
205 count : &[u16]) {
206 let mut sorted : [i32;18] = [0i32;18]; let mut offset : [i32 ; (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1) as usize] =
209 [0i32;(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1) as usize];
210 assert!(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as usize<=
211 BROTLI_REVERSE_BITS_MAX as usize);
212
213 let mut symbol : i32 = -1; let mut bits : i32 = 1;
216 for _ in 0..BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH {
217 symbol += count[bits as usize] as i32;
218 offset[bits as usize] = symbol;
219 bits += 1;
220 }
221 offset[0] = 17;
223
224 symbol = 18;
226 loop {
227 for _ in 0..6 {
228 symbol-=1;
229 let index = offset[code_lengths[symbol as usize] as usize];
230 offset[code_lengths[symbol as usize] as usize] -= 1;
231 sorted[index as usize] = symbol;
232 }
233 if symbol == 0 {
234 break;
235 }
236 }
237
238 const table_size : i32 = 1 << BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH;
239
240 if offset[0] == 0 {
242 let code : HuffmanCode = HuffmanCode{bits: 0, value: sorted[0] as u16};
243 for val in table[0..table_size as usize].iter_mut() {
244 *val = code;
245 }
246 return;
247 }
248
249 let mut key : u32 = 0; let mut key_step : u32 = BROTLI_REVERSE_BITS_LOWEST; symbol = 0;
253 bits = 1;
254 let mut step : i32 = 2;
255 loop {
256 let mut code : HuffmanCode = HuffmanCode{bits : (bits as u8), value : 0};
257 let mut bits_count : i32 = count[bits as usize] as i32;
258
259 while bits_count != 0 {
260 code.value = sorted[symbol as usize] as u16;
261 symbol += 1;
262 ReplicateValue(&mut table, BrotliReverseBits(key) as usize, step, table_size, code);
263 key += key_step;
264 bits_count -= 1;
265 }
266 step <<= 1;
267 key_step >>= 1;
268 bits += 1;
269 if !(bits <= BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as i32) {
270 break;
271 }
272 }
273}
274
275pub fn BrotliBuildHuffmanTable(mut root_table : &mut[HuffmanCode],
276 root_bits : i32,
277 symbol_lists : &[u16],
278 symbol_lists_offset : usize, count : &mut[u16]) -> u32{
280 let mut code : HuffmanCode = HuffmanCode {bits : 0, value : 0}; let mut max_length : i32 = -1;
282
283 assert!(root_bits as isize <= BROTLI_REVERSE_BITS_MAX as isize);
284 assert!(BROTLI_HUFFMAN_MAX_CODE_LENGTH as isize - root_bits as isize <=
285 BROTLI_REVERSE_BITS_MAX as isize);
286
287 while symbol_lists[((symbol_lists_offset as isize) + max_length as isize) as usize] == 0xFFFF {
288 max_length -= 1;
289 }
290 max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH as i32 + 1;
291
292 let mut table_free_offset : usize = 0;
293 let mut table_bits : i32 = root_bits; let mut table_size : i32 = 1 << table_bits;let mut total_size : i32 = table_size; if table_bits > max_length {
301 table_bits = max_length;
302 table_size = 1 << table_bits;
303 }
304 let mut key : u32 = 0; let mut key_step : u32 = BROTLI_REVERSE_BITS_LOWEST; let mut bits : i32 = 1;
307 let mut step : i32 = 2; loop {
309 code.bits = bits as u8;
310 let mut symbol : i32 = bits - (BROTLI_HUFFMAN_MAX_CODE_LENGTH as i32 + 1);
311 let mut bits_count : i32 = count[bits as usize] as i32;
312 while bits_count != 0 {
313 symbol = symbol_lists[(symbol_lists_offset as isize + symbol as isize) as usize] as i32;
314 code.value = symbol as u16;
315 ReplicateValue(&mut root_table, table_free_offset + BrotliReverseBits(key) as usize,
316 step, table_size, code);
317 key += key_step;
318 bits_count -= 1;
319 }
320 step <<= 1;
321 key_step >>= 1;
322 bits += 1;
323 if !(bits <= table_bits) {
324 break;
325 }
326 }
327
328 while total_size != table_size {
331 for index in 0..table_size { root_table[table_free_offset + table_size as usize + index as usize]
333 = root_table[table_free_offset + index as usize];
334 }
335 table_size <<= 1;
336 }
337
338 key_step = BROTLI_REVERSE_BITS_LOWEST >> (root_bits - 1);
340 let mut sub_key : u32 = BROTLI_REVERSE_BITS_LOWEST << 1; let mut sub_key_step : u32 = BROTLI_REVERSE_BITS_LOWEST; step = 2;
344
345 let mut len : i32 = root_bits + 1; while len <= max_length {
347 let mut symbol : i32 = len - (BROTLI_HUFFMAN_MAX_CODE_LENGTH as i32 + 1);
348 while count[len as usize] != 0 {
349 if sub_key == (BROTLI_REVERSE_BITS_LOWEST << 1u32) {
350 table_free_offset += table_size as usize;
351 table_bits = NextTableBitSize(count, len, root_bits);
352 table_size = 1 << table_bits;
353 total_size += table_size;
354 sub_key = BrotliReverseBits(key);
355 key += key_step;
356 root_table[sub_key as usize].bits = (table_bits + root_bits) as u8;
357 root_table[sub_key as usize].value =
358 ((table_free_offset) - sub_key as usize) as u16;
359 sub_key = 0;
360 }
361 code.bits = (len - root_bits) as u8;
362 symbol = symbol_lists[(symbol_lists_offset as isize + symbol as isize) as usize] as i32;
363 code.value = symbol as u16;
364 ReplicateValue(
365 &mut root_table,table_free_offset + BrotliReverseBits(sub_key) as usize, step, table_size, code);
366 sub_key += sub_key_step;
367 count[len as usize] -= 1;
368 }
369 step <<= 1;
370 sub_key_step >>= 1;
371 len += 1
372 }
373 return total_size as u32;
374}
375
376
377
378pub fn BrotliBuildSimpleHuffmanTable(table : &mut [HuffmanCode],
379 root_bits : i32,
380 val : &[u16],
381 num_symbols: u32) -> u32 {
382 let mut table_size : u32 = 1;
383 let goal_size : u32 = 1u32 << root_bits;
384 assert!(num_symbols <= 4);
385 if num_symbols == 0 {
386 table[0].bits = 0;
387 table[0].value = val[0];
388 } else if num_symbols == 1 {
389 table[0].bits = 1;
390 table[1].bits = 1;
391 if val[1] > val[0] {
392 table[0].value = val[0];
393 table[1].value = val[1];
394 } else {
395 table[0].value = val[1];
396 table[1].value = val[0];
397 }
398 table_size = 2;
399 } else if num_symbols == 2 {
400 table[0].bits = 1;
401 table[0].value = val[0];
402 table[2].bits = 1;
403 table[2].value = val[0];
404 if val[2] > val[1] {
405 table[1].value = val[1];
406 table[3].value = val[2];
407 } else {
408 table[1].value = val[2];
409 table[3].value = val[1];
410 }
411 table[1].bits = 2;
412 table[3].bits = 2;
413 table_size = 4;
414 } else if num_symbols == 3 {
415 let last : u16;
416 if val.len() > 3 {
417 last = val[3];
418 } else {
419 last = 65535;
420 }
421 let mut mval : [u16 ; 4] = [val[0], val[1], val[2], last];
422 for i in 0..3 {
423 for k in i + 1..4 {
424 if mval[k] < mval[i] {
425 let t : u16 = mval[k];
426 mval[k] = mval[i];
427 mval[i] = t;
428 }
429 }
430 }
431 for i in 0..4 {
432 table[i].bits = 2;
433 }
434 table[0].value = mval[0];
435 table[2].value = mval[1];
436 table[1].value = mval[2];
437 table[3].value = mval[3];
438 table_size = 4;
439 } else if num_symbols == 4 {
440 let mut mval : [u16; 4] = [val[0], val[1], val[2], val[3]];
441 if mval[3] < mval[2] {
442 let t : u16 = mval[3];
443 mval[3] = mval[2];
444 mval[2] = t;
445 }
446 for i in 0..7 {
447 table[i].value = mval[0];
448 table[i].bits = (1 + (i & 1)) as u8;
449 }
450 table[1].value = mval[1];
451 table[3].value = mval[2];
452 table[5].value = mval[1];
453 table[7].value = mval[3];
454 table[3].bits = 3;
455 table[7].bits = 3;
456 table_size = 8;
457 } else {
458 assert!(false);
459 }
460 while table_size != goal_size {
461 for index in 0..table_size {
462 table[(table_size + index) as usize] = table[index as usize];
463 }
464 table_size <<= 1;
465 }
466 return goal_size;
467}
468