1 | /// Given an array containing the number of codes of each code length, |
2 | /// this function generates the huffman codes lengths and their respective |
3 | /// code lengths as specified by the JPEG spec. |
4 | const fn derive_codes_and_sizes(bits: &[u8; 16]) -> ([u8; 256], [u16; 256]) { |
5 | let mut huffsize = [0u8; 256]; |
6 | let mut huffcode = [0u16; 256]; |
7 | |
8 | let mut k = 0; |
9 | |
10 | // Annex C.2 |
11 | // Figure C.1 |
12 | // Generate table of individual code lengths |
13 | let mut i = 0; |
14 | while i < 16 { |
15 | let mut j = 0; |
16 | while j < bits[i as usize] { |
17 | huffsize[k] = i + 1; |
18 | k += 1; |
19 | j += 1; |
20 | } |
21 | i += 1; |
22 | } |
23 | |
24 | huffsize[k] = 0; |
25 | |
26 | // Annex C.2 |
27 | // Figure C.2 |
28 | // Generate table of huffman codes |
29 | k = 0; |
30 | let mut code = 0u16; |
31 | let mut size = huffsize[0]; |
32 | |
33 | while huffsize[k] != 0 { |
34 | huffcode[k] = code; |
35 | code += 1; |
36 | k += 1; |
37 | |
38 | if huffsize[k] == size { |
39 | continue; |
40 | } |
41 | |
42 | // FIXME there is something wrong with this code |
43 | let diff = huffsize[k].wrapping_sub(size); |
44 | code = if diff < 16 { code << diff as usize } else { 0 }; |
45 | |
46 | size = size.wrapping_add(diff); |
47 | } |
48 | |
49 | (huffsize, huffcode) |
50 | } |
51 | |
52 | pub(crate) const fn build_huff_lut_const(bits: &[u8; 16], huffval: &[u8]) -> [(u8, u16); 256] { |
53 | let mut lut: [(u8, u16); 256] = [(17u8, 0u16); 256]; |
54 | let (huffsize: [u8; 256], huffcode: [u16; 256]) = derive_codes_and_sizes(bits); |
55 | |
56 | let mut i: usize = 0; |
57 | while i < huffval.len() { |
58 | lut[huffval[i] as usize] = (huffsize[i], huffcode[i]); |
59 | i += 1; |
60 | } |
61 | |
62 | lut |
63 | } |
64 | |