1#![warn(missing_docs)]
13
14use super::BitQueue;
15use super::Endianness;
16#[cfg(feature = "alloc")]
17use alloc::boxed::Box;
18#[cfg(feature = "alloc")]
19use alloc::collections::BTreeMap;
20#[cfg(feature = "alloc")]
21use alloc::vec::Vec;
22#[cfg(feature = "alloc")]
23use core::fmt;
24#[cfg(feature = "alloc")]
25use core::marker::PhantomData;
26#[cfg(feature = "alloc")]
27use core2::error::Error;
28
29#[cfg(not(feature = "alloc"))]
30use std::collections::BTreeMap;
31#[cfg(not(feature = "alloc"))]
32use std::error::Error;
33#[cfg(not(feature = "alloc"))]
34use std::fmt;
35#[cfg(not(feature = "alloc"))]
36use std::marker::PhantomData;
37
38pub enum ReadHuffmanTree<E: Endianness, T: Clone> {
49 Done(T, u8, u32, PhantomData<E>),
51 Continue(Box<[ReadHuffmanTree<E, T>]>),
53 InvalidState,
55}
56
57pub fn compile_read_tree<E, T>(
94 values: Vec<(T, Vec<u8>)>,
95) -> Result<Box<[ReadHuffmanTree<E, T>]>, HuffmanTreeError>
96where
97 E: Endianness,
98 T: Clone,
99{
100 let tree = FinalHuffmanTree::new(values)?;
101
102 let mut result = Vec::with_capacity(256);
103 result.extend((0..256).map(|_| ReadHuffmanTree::InvalidState));
104 let queue = BitQueue::from_value(0, 0);
105 let i = queue.to_state();
106 result[i] = compile_queue(queue, &tree);
107 for bits in 1..8 {
108 for value in 0..(1 << bits) {
109 let queue = BitQueue::from_value(value, bits);
110 let i = queue.to_state();
111 result[i] = compile_queue(queue, &tree);
112 }
113 }
114 assert_eq!(result.len(), 256);
115 Ok(result.into_boxed_slice())
116}
117
118fn compile_queue<E, T>(
119 mut queue: BitQueue<E, u8>,
120 tree: &FinalHuffmanTree<T>,
121) -> ReadHuffmanTree<E, T>
122where
123 E: Endianness,
124 T: Clone,
125{
126 match tree {
127 FinalHuffmanTree::Leaf(ref value) => {
128 let len = queue.len();
129 ReadHuffmanTree::Done(value.clone(), queue.value(), len, PhantomData)
130 }
131 FinalHuffmanTree::Tree(ref bit0, ref bit1) => {
132 if queue.is_empty() {
133 ReadHuffmanTree::Continue(
134 (0..256)
135 .map(|byte| compile_queue(BitQueue::from_value(byte as u8, 8), tree))
136 .collect::<Vec<ReadHuffmanTree<E, T>>>()
137 .into_boxed_slice(),
138 )
139 } else if queue.pop(1) == 0 {
140 compile_queue(queue, bit0)
141 } else {
142 compile_queue(queue, bit1)
143 }
144 }
145 }
146}
147
148enum FinalHuffmanTree<T: Clone> {
150 Leaf(T),
151 Tree(Box<FinalHuffmanTree<T>>, Box<FinalHuffmanTree<T>>),
152}
153
154impl<T: Clone> FinalHuffmanTree<T> {
155 fn new(values: Vec<(T, Vec<u8>)>) -> Result<FinalHuffmanTree<T>, HuffmanTreeError> {
156 let mut tree = WipHuffmanTree::new_empty();
157
158 for (symbol, code) in values {
159 tree.add(code.as_slice(), symbol)?;
160 }
161
162 tree.into_read_tree()
163 }
164}
165
166enum WipHuffmanTree<T: Clone> {
171 Empty,
172 Leaf(T),
173 Tree(Box<WipHuffmanTree<T>>, Box<WipHuffmanTree<T>>),
174}
175
176impl<T: Clone> WipHuffmanTree<T> {
177 fn new_empty() -> WipHuffmanTree<T> {
178 WipHuffmanTree::Empty
179 }
180
181 fn new_leaf(value: T) -> WipHuffmanTree<T> {
182 WipHuffmanTree::Leaf(value)
183 }
184
185 fn new_tree() -> WipHuffmanTree<T> {
186 WipHuffmanTree::Tree(Box::new(Self::new_empty()), Box::new(Self::new_empty()))
187 }
188
189 fn into_read_tree(self) -> Result<FinalHuffmanTree<T>, HuffmanTreeError> {
190 match self {
191 WipHuffmanTree::Empty => Err(HuffmanTreeError::MissingLeaf),
192 WipHuffmanTree::Leaf(v) => Ok(FinalHuffmanTree::Leaf(v)),
193 WipHuffmanTree::Tree(zero, one) => {
194 let zero = zero.into_read_tree()?;
195 let one = one.into_read_tree()?;
196 Ok(FinalHuffmanTree::Tree(Box::new(zero), Box::new(one)))
197 }
198 }
199 }
200
201 fn add(&mut self, code: &[u8], symbol: T) -> Result<(), HuffmanTreeError> {
202 match self {
203 WipHuffmanTree::Empty => {
204 if code.is_empty() {
205 *self = WipHuffmanTree::new_leaf(symbol);
206 Ok(())
207 } else {
208 *self = WipHuffmanTree::new_tree();
209 self.add(code, symbol)
210 }
211 }
212 WipHuffmanTree::Leaf(_) => Err(if code.is_empty() {
213 HuffmanTreeError::DuplicateLeaf
214 } else {
215 HuffmanTreeError::OrphanedLeaf
216 }),
217 WipHuffmanTree::Tree(ref mut zero, ref mut one) => {
218 if code.is_empty() {
219 Err(HuffmanTreeError::DuplicateLeaf)
220 } else {
221 match code[0] {
222 0 => zero.add(&code[1..], symbol),
223 1 => one.add(&code[1..], symbol),
224 _ => Err(HuffmanTreeError::InvalidBit),
225 }
226 }
227 }
228 }
229 }
230}
231
232#[derive(PartialEq, Eq, Copy, Clone, Debug)]
234pub enum HuffmanTreeError {
235 InvalidBit,
237 MissingLeaf,
239 DuplicateLeaf,
241 OrphanedLeaf,
243}
244
245impl fmt::Display for HuffmanTreeError {
246 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247 match *self {
248 HuffmanTreeError::InvalidBit => write!(f, "invalid bit in code"),
249 HuffmanTreeError::MissingLeaf => write!(f, "missing leaf node in specification"),
250 HuffmanTreeError::DuplicateLeaf => write!(f, "duplicate leaf node in specification"),
251 HuffmanTreeError::OrphanedLeaf => write!(f, "orphaned leaf node in specification"),
252 }
253 }
254}
255
256impl Error for HuffmanTreeError {}
257
258pub fn compile_write_tree<E, T>(
298 values: Vec<(T, Vec<u8>)>,
299) -> Result<WriteHuffmanTree<E, T>, HuffmanTreeError>
300where
301 E: Endianness,
302 T: Ord + Clone,
303{
304 let mut map = BTreeMap::new();
305
306 for (symbol, code) in values {
307 let mut encoded = Vec::new();
308 for bits in code.chunks(32) {
309 let mut acc = BitQueue::<E, u32>::new();
310 for bit in bits {
311 match *bit {
312 0 => acc.push(1, 0),
313 1 => acc.push(1, 1),
314 _ => return Err(HuffmanTreeError::InvalidBit),
315 }
316 }
317 let len = acc.len();
318 encoded.push((len, acc.value()))
319 }
320 map.entry(symbol)
321 .or_insert_with(|| encoded.into_boxed_slice());
322 }
323
324 Ok(WriteHuffmanTree {
325 map,
326 phantom: PhantomData,
327 })
328}
329
330pub struct WriteHuffmanTree<E: Endianness, T: Ord> {
333 map: BTreeMap<T, Box<[(u32, u32)]>>,
334 phantom: PhantomData<E>,
335}
336
337impl<E: Endianness, T: Ord + Clone> WriteHuffmanTree<E, T> {
338 #[inline]
340 pub fn has_symbol(&self, symbol: &T) -> bool {
341 self.map.contains_key(symbol)
342 }
343
344 #[inline]
348 pub fn get(&self, symbol: &T) -> impl Iterator<Item = &(u32, u32)> {
349 self.map[symbol].iter()
350 }
351}