1 | //! Structures that wrap around various decoders to make decoding easier. |
2 | |
3 | use super::super::blocks::sequence_section::Sequence; |
4 | use super::decodebuffer::DecodeBuffer; |
5 | use crate::decoding::dictionary::Dictionary; |
6 | use crate::fse::FSETable; |
7 | use crate::huff0::HuffmanTable; |
8 | use alloc::vec::Vec; |
9 | |
10 | use crate::blocks::sequence_section::{ |
11 | MAX_LITERAL_LENGTH_CODE, MAX_MATCH_LENGTH_CODE, MAX_OFFSET_CODE, |
12 | }; |
13 | |
14 | /// A block level decoding buffer. |
15 | pub 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 | |
29 | impl 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 | |
81 | pub struct HuffmanScratch { |
82 | pub table: HuffmanTable, |
83 | } |
84 | |
85 | impl HuffmanScratch { |
86 | pub fn new() -> HuffmanScratch { |
87 | HuffmanScratch { |
88 | table: HuffmanTable::new(), |
89 | } |
90 | } |
91 | } |
92 | |
93 | impl Default for HuffmanScratch { |
94 | fn default() -> Self { |
95 | Self::new() |
96 | } |
97 | } |
98 | |
99 | pub 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 | |
108 | impl 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 | |
130 | impl Default for FSEScratch { |
131 | fn default() -> Self { |
132 | Self::new() |
133 | } |
134 | } |
135 | |