chess/formats/cbv/
huffman.rs1use super::*;
2
3#[derive(Default)]
5pub struct Tree {
6 pub left: Option<Box<Tree>>,
7 pub right: Option<Box<Tree>>,
8 pub value: Option<u8>,
9}
10
11impl From<u8> for Tree {
12 fn from(value: u8) -> Self {
13 Self { left: None, right: None, value: Some(value) }
14 }
15}
16
17impl Tree {
18 fn visit<'a>(
22 &'a self,
23 current: &mut &'a Tree,
24 result: &mut Vec<u8>,
25 right: bool,
26 ) -> Option<()> {
27 let direction = if right { current.right.as_ref()? } else { current.left.as_ref()? };
28 if let Some(byte) = direction.value {
29 result.push(byte);
30 *current = self;
31 } else {
32 *current = direction;
33 }
34 Some(())
35 }
36
37 #[must_use]
38 pub fn unpack(&self, bits: Bits<'_>, decompressed: usize) -> Option<Vec<u8>> {
40 let mut current = self;
41 let mut result = Vec::new();
42
43 for direction in bits {
44 if result.len() == decompressed {
45 break;
46 }
47
48 self.visit(&mut current, &mut result, direction)?;
49 }
50
51 Some(result)
52 }
53
54 pub fn get_mut_or_insert(&mut self, right: bool) -> &mut Self {
55 if right { self.right.get_or_insert_default() } else { self.left.get_or_insert_default() }
56 }
57
58 pub fn load(values: [(usize, u16); 256]) -> Self {
59 let mut tree = Tree::default();
60 for (i, (len, bits)) in values.into_iter().enumerate() {
61 if len > 0 {
62 let mut node = &mut tree;
63 let bits = (bits << (16 - len)).to_be_bytes();
64
65 for direction in Bits::from(bits.as_slice()).take(len) {
66 node = node.get_mut_or_insert(direction);
67 }
68
69 node.value = Some(i as u8);
70 }
71 }
72 tree
73 }
74}