| 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 | |