Skip to main content

zrip_core/fse/
decode.rs

1#![forbid(unsafe_code)]
2
3use crate::bitstream::reader_reverse::ReverseBitReader;
4use crate::error::DecompressError;
5use crate::fse::FseDecodeEntry;
6
7pub struct FseState<'t> {
8    table: &'t [FseDecodeEntry],
9    state: u32,
10}
11
12impl<'t> FseState<'t> {
13    pub fn new(
14        table: &'t [FseDecodeEntry],
15        accuracy_log: u8,
16        reader: &mut ReverseBitReader,
17    ) -> Result<Self, DecompressError> {
18        let state = reader.read_bits(accuracy_log)?;
19        Ok(Self { table, state })
20    }
21
22    #[inline]
23    pub fn symbol(&self) -> u8 {
24        self.table[self.state as usize].symbol
25    }
26
27    #[inline]
28    pub fn baseline(&self) -> u16 {
29        self.table[self.state as usize].base_line
30    }
31
32    #[inline]
33    pub fn num_bits(&self) -> u8 {
34        self.table[self.state as usize].num_bits
35    }
36
37    #[inline]
38    pub fn update_state(&mut self, reader: &mut ReverseBitReader) -> Result<(), DecompressError> {
39        let entry = &self.table[self.state as usize];
40        let bits = reader.read_bits(entry.num_bits)?;
41        self.state = entry.base_line as u32 + bits;
42        Ok(())
43    }
44
45    #[inline]
46    pub fn decode_symbol(&mut self, reader: &mut ReverseBitReader) -> Result<u8, DecompressError> {
47        let sym = self.symbol();
48        self.update_state(reader)?;
49        Ok(sym)
50    }
51
52    pub fn state(&self) -> u32 {
53        self.state
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use crate::bitstream::writer::BitWriter;
61    use crate::fse::table_builder::build_decode_table_from_default;
62    use crate::fse::{LL_DEFAULT_ACCURACY, LL_DEFAULT_DIST};
63
64    #[test]
65    fn init_and_read_symbol() {
66        let table = build_decode_table_from_default(&LL_DEFAULT_DIST, LL_DEFAULT_ACCURACY);
67
68        let mut w = BitWriter::new();
69        w.write_bits(0, LL_DEFAULT_ACCURACY);
70        w.close_reverse_stream();
71        let data = w.into_bytes();
72
73        let mut reader = ReverseBitReader::new(&data).unwrap();
74        let state = FseState::new(&table, LL_DEFAULT_ACCURACY, &mut reader).unwrap();
75        let sym = state.symbol();
76        assert!(sym <= 35);
77    }
78}