1use crate::huffman::HuffmanTree;
2
3pub struct RLESequence {
4 pub num_zeroes: u8,
5 pub coeff_size: u8,
6 pub coeff: i16,
7}
8
9pub fn rle_encode(into: &mut Vec<RLESequence>, data: &[i16]) {
10 let mut run: u32 = 0;
11
12 for idx in 0..data.len() {
13 let val = data[idx];
14
15 if val == 0 {
16 run += 1;
17 } else {
18 while run > 15 {
19 into.push(RLESequence { num_zeroes: 15, coeff_size: 0, coeff: 0 });
20 run -= 15;
21 }
22
23 let c = val.abs() as u16;
24 let numbits = (16 - c.leading_zeros()) + 1;
25
26 into.push(RLESequence { num_zeroes: run as u8, coeff_size: numbits as u8, coeff: val });
27 run = 0;
28 }
29 }
30
31 while run > 15 {
32 into.push(RLESequence { num_zeroes: 15, coeff_size: 0, coeff: 0 });
33 run -= 15;
34 }
35
36 if run > 0 {
37 into.push(RLESequence { num_zeroes: run as u8, coeff_size: 0, coeff: 0 });
38 }
39}
40
41pub fn update_table(table: &mut [i32;16], sequence: &[RLESequence]) {
42 for s in sequence {
43 debug_assert!(s.num_zeroes < 16 && s.coeff_size < 16);
44 table[s.num_zeroes as usize] += 1;
45 table[s.coeff_size as usize] += 1;
46 }
47}
48
49pub fn rle_create_huffman(table: &[i32;16]) -> HuffmanTree {
50 let mut max = 0;
51 for x in table {
52 max = max.max(*x);
53 }
54
55 let table = table.map(|x| {
56 if x > 0 {
57 let val = ((x * 255) / max).max(1) as u8;
58 debug_assert!(val > 0);
59 val
60 } else {
61 0
62 }
63 });
64
65 HuffmanTree::from_table(&table)
66}