ruzstd/decoding/
scratch.rs

1//! Structures that wrap around various decoders to make decoding easier.
2
3use super::super::blocks::sequence_section::Sequence;
4use super::decodebuffer::DecodeBuffer;
5use crate::decoding::dictionary::Dictionary;
6use crate::fse::FSETable;
7use crate::huff0::HuffmanTable;
8use alloc::vec::Vec;
9
10use crate::blocks::sequence_section::{
11    MAX_LITERAL_LENGTH_CODE, MAX_MATCH_LENGTH_CODE, MAX_OFFSET_CODE,
12};
13
14/// A block level decoding buffer.
15pub struct DecoderScratch {
16    /// The decoder used for Huffman blocks.
17    pub huf: HuffmanScratch,
18    /// The decoder used for FSE blocks.
19    pub fse: FSEScratch,
20
21    pub buffer: DecodeBuffer,
22    pub offset_hist: [u32; 3],
23
24    pub literals_buffer: Vec<u8>,
25    pub sequences: Vec<Sequence>,
26    pub block_content_buffer: Vec<u8>,
27}
28
29impl DecoderScratch {
30    pub fn new(window_size: usize) -> DecoderScratch {
31        DecoderScratch {
32            huf: HuffmanScratch {
33                table: HuffmanTable::new(),
34            },
35            fse: FSEScratch {
36                offsets: FSETable::new(MAX_OFFSET_CODE),
37                of_rle: None,
38                literal_lengths: FSETable::new(MAX_LITERAL_LENGTH_CODE),
39                ll_rle: None,
40                match_lengths: FSETable::new(MAX_MATCH_LENGTH_CODE),
41                ml_rle: None,
42            },
43            buffer: DecodeBuffer::new(window_size),
44            offset_hist: [1, 4, 8],
45
46            block_content_buffer: Vec::new(),
47            literals_buffer: Vec::new(),
48            sequences: Vec::new(),
49        }
50    }
51
52    pub fn reset(&mut self, window_size: usize) {
53        self.offset_hist = [1, 4, 8];
54        self.literals_buffer.clear();
55        self.sequences.clear();
56        self.block_content_buffer.clear();
57
58        self.buffer.reset(window_size);
59
60        self.fse.literal_lengths.reset();
61        self.fse.match_lengths.reset();
62        self.fse.offsets.reset();
63        self.fse.ll_rle = None;
64        self.fse.ml_rle = None;
65        self.fse.of_rle = None;
66
67        self.huf.table.reset();
68    }
69
70    pub fn init_from_dict(&mut self, dict: &Dictionary) {
71        self.fse.reinit_from(&dict.fse);
72        self.huf.table.reinit_from(&dict.huf.table);
73        self.offset_hist = dict.offset_hist;
74        self.buffer.dict_content.clear();
75        self.buffer
76            .dict_content
77            .extend_from_slice(&dict.dict_content);
78    }
79}
80
81pub struct HuffmanScratch {
82    pub table: HuffmanTable,
83}
84
85impl HuffmanScratch {
86    pub fn new() -> HuffmanScratch {
87        HuffmanScratch {
88            table: HuffmanTable::new(),
89        }
90    }
91}
92
93impl Default for HuffmanScratch {
94    fn default() -> Self {
95        Self::new()
96    }
97}
98
99pub struct FSEScratch {
100    pub offsets: FSETable,
101    pub of_rle: Option<u8>,
102    pub literal_lengths: FSETable,
103    pub ll_rle: Option<u8>,
104    pub match_lengths: FSETable,
105    pub ml_rle: Option<u8>,
106}
107
108impl FSEScratch {
109    pub fn new() -> FSEScratch {
110        FSEScratch {
111            offsets: FSETable::new(MAX_OFFSET_CODE),
112            of_rle: None,
113            literal_lengths: FSETable::new(MAX_LITERAL_LENGTH_CODE),
114            ll_rle: None,
115            match_lengths: FSETable::new(MAX_MATCH_LENGTH_CODE),
116            ml_rle: None,
117        }
118    }
119
120    pub fn reinit_from(&mut self, other: &Self) {
121        self.offsets.reinit_from(&other.offsets);
122        self.literal_lengths.reinit_from(&other.literal_lengths);
123        self.match_lengths.reinit_from(&other.match_lengths);
124        self.of_rle = other.of_rle;
125        self.ll_rle = other.ll_rle;
126        self.ml_rle = other.ml_rle;
127    }
128}
129
130impl Default for FSEScratch {
131    fn default() -> Self {
132        Self::new()
133    }
134}