| 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 | |