lzma_rust/
lib.rs

1mod decoder;
2mod lz;
3mod lzma2_reader;
4mod lzma_reader;
5mod range_dec;
6mod state;
7
8pub use lzma2_reader::get_memery_usage as lzma2_get_memery_usage;
9pub use lzma2_reader::LZMA2Reader;
10pub use lzma_reader::get_memery_usage as lzma_get_memery_usage;
11pub use lzma_reader::get_memery_usage_by_props as lzma_get_memery_usage_by_props;
12pub use lzma_reader::LZMAReader;
13#[cfg(feature = "encoder")]
14mod enc;
15#[cfg(feature = "encoder")]
16pub use enc::*;
17
18use state::*;
19
20pub const DICT_SIZE_MIN: u32 = 4096;
21pub const DICT_SIZE_MAX: u32 = u32::MAX & !(15 as u32);
22
23const LOW_SYMBOLS: usize = 1 << 3;
24const MID_SYMBOLS: usize = 1 << 3;
25const HIGH_SYMBOLS: usize = 1 << 8;
26
27const POS_STATES_MAX: usize = 1 << 4;
28const MATCH_LEN_MIN: usize = 2;
29const MATCH_LEN_MAX: usize = MATCH_LEN_MIN + LOW_SYMBOLS + MID_SYMBOLS + HIGH_SYMBOLS - 1;
30
31const DIST_STATES: usize = 4;
32const DIST_SLOTS: usize = 1 << 6;
33const DIST_MODEL_START: usize = 4;
34const DIST_MODEL_END: usize = 14;
35const FULL_DISTANCES: usize = 1 << (DIST_MODEL_END / 2);
36
37const ALIGN_BITS: usize = 4;
38const ALIGN_SIZE: usize = 1 << ALIGN_BITS;
39const ALIGN_MASK: usize = ALIGN_SIZE - 1;
40
41const REPS: usize = 4;
42
43const SHIFT_BITS: u32 = 8;
44const TOP_MASK: u32 = 0xFF000000;
45const BIT_MODEL_TOTAL_BITS: u32 = 11;
46const BIT_MODEL_TOTAL: u32 = 1 << BIT_MODEL_TOTAL_BITS;
47const PROB_INIT: u16 = (BIT_MODEL_TOTAL / 2) as u16;
48const MOVE_BITS: u32 = 5;
49const DIST_SPECIAL_INDEX: [usize; 10] = [0, 2, 4, 8, 12, 20, 28, 44, 60, 92];
50const DIST_SPECIAL_END: [usize; 10] = [2, 4, 8, 12, 20, 28, 44, 60, 92, 124];
51pub struct LZMACoder {
52    pub(crate) pos_mask: u32,
53    pub(crate) reps: [i32; REPS],
54    pub(crate) state: State,
55    pub(crate) is_match: [[u16; POS_STATES_MAX]; state::STATES],
56    pub(crate) is_rep: [u16; state::STATES],
57    pub(crate) is_rep0: [u16; state::STATES],
58    pub(crate) is_rep1: [u16; state::STATES],
59    pub(crate) is_rep2: [u16; state::STATES],
60    pub(crate) is_rep0_long: [[u16; POS_STATES_MAX]; state::STATES],
61    pub(crate) dist_slots: [[u16; DIST_SLOTS]; DIST_STATES],
62    dist_special: [u16; 124],
63    dist_align: [u16; ALIGN_SIZE],
64}
65
66pub(crate) fn coder_get_dict_size(len: usize) -> usize {
67    if len < DIST_STATES + MATCH_LEN_MIN {
68        len - MATCH_LEN_MIN
69    } else {
70        DIST_STATES - 1
71    }
72}
73pub(crate) fn get_dist_state(len: u32) -> u32 {
74    (if (len as usize) < DIST_STATES + MATCH_LEN_MIN {
75        len as usize - MATCH_LEN_MIN
76    } else {
77        DIST_STATES - 1
78    }) as u32
79}
80impl LZMACoder {
81    pub fn new(pb: usize) -> Self {
82        let mut c = Self {
83            pos_mask: (1 << pb) - 1,
84            reps: Default::default(),
85            state: Default::default(),
86            is_match: Default::default(),
87            is_rep: Default::default(),
88            is_rep0: Default::default(),
89            is_rep1: Default::default(),
90            is_rep2: Default::default(),
91            is_rep0_long: Default::default(),
92            dist_slots: [[Default::default(); DIST_SLOTS]; DIST_STATES],
93            dist_special: [Default::default(); 124],
94            dist_align: Default::default(),
95        };
96        c.reset();
97        c
98    }
99
100    pub fn reset(&mut self) {
101        self.reps = [0; REPS];
102        self.state.reset();
103        for ele in self.is_match.iter_mut() {
104            init_probs(ele);
105        }
106        init_probs(&mut self.is_rep);
107        init_probs(&mut self.is_rep0);
108        init_probs(&mut self.is_rep1);
109        init_probs(&mut self.is_rep2);
110
111        for ele in self.is_rep0_long.iter_mut() {
112            init_probs(ele);
113        }
114        for ele in self.dist_slots.iter_mut() {
115            init_probs(ele);
116        }
117        init_probs(&mut self.dist_special);
118        init_probs(&mut self.dist_align);
119    }
120
121    #[inline(always)]
122    pub fn get_dist_special(&mut self, i: usize) -> &mut [u16] {
123        &mut self.dist_special[DIST_SPECIAL_INDEX[i]..DIST_SPECIAL_END[i]]
124    }
125}
126
127#[inline(always)]
128pub(crate) fn init_probs(probs: &mut [u16]) {
129    probs.fill(PROB_INIT);
130}
131
132pub(crate) struct LiteralCoder {
133    lc: u32,
134    literal_pos_mask: u32,
135}
136
137#[derive(Debug, Clone, Copy)]
138pub(crate) struct LiteralSubcoder {
139    probs: [u16; 0x300],
140}
141
142impl LiteralSubcoder {
143    pub fn new() -> Self {
144        let probs = [PROB_INIT; 0x300];
145        // init_probs(&mut probs);
146        Self { probs }
147    }
148    pub fn reset(&mut self) {
149        self.probs = [PROB_INIT; 0x300];
150    }
151}
152
153impl LiteralCoder {
154    pub fn new(lc: u32, lp: u32) -> Self {
155        Self {
156            lc,
157            literal_pos_mask: (1 << lp) - 1,
158        }
159    }
160    pub(crate) fn get_sub_coder_index(&self, prev_byte: u32, pos: u32) -> u32 {
161        let low = prev_byte >> (8 - self.lc);
162        let high = (pos & self.literal_pos_mask) << self.lc;
163        low + high
164    }
165}
166
167pub(crate) struct LengthCoder {
168    choice: [u16; 2],
169    low: [[u16; LOW_SYMBOLS]; POS_STATES_MAX],
170    mid: [[u16; MID_SYMBOLS]; POS_STATES_MAX],
171    high: [u16; HIGH_SYMBOLS],
172}
173
174impl LengthCoder {
175    pub fn new() -> Self {
176        Self {
177            choice: Default::default(),
178            low: Default::default(),
179            mid: Default::default(),
180            high: [0; HIGH_SYMBOLS],
181        }
182    }
183
184    pub fn reset(&mut self) {
185        init_probs(&mut self.choice);
186        for ele in self.low.iter_mut() {
187            init_probs(ele);
188        }
189        for ele in self.mid.iter_mut() {
190            init_probs(ele);
191        }
192        init_probs(&mut self.high);
193    }
194}