pfv_rs/
rle.rs

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}