1#![allow(dead_code)]
51#![warn(missing_docs)]
52#![cfg_attr(not(feature = "optimization"), forbid(unsafe_code))]
53#![cfg_attr(docsrs, feature(doc_cfg))]
54#![cfg_attr(not(feature = "std"), no_std)]
55
56extern crate alloc;
57
58mod decoder;
59mod lz;
60#[cfg(feature = "lzip")]
61mod lzip;
62mod lzma2_reader;
63mod lzma_reader;
64mod range_dec;
65mod state;
66#[cfg(feature = "std")]
67mod work_queue;
68#[cfg(feature = "xz")]
69mod xz;
70
71#[cfg(feature = "encoder")]
72mod enc;
73
74pub mod filter;
75
76#[cfg(any(feature = "lzip", feature = "xz"))]
77mod crc;
78#[cfg(feature = "std")]
79mod lzma2_reader_mt;
80#[cfg(not(feature = "std"))]
81mod no_std;
82#[cfg(feature = "std")]
83mod work_pool;
84
85#[cfg(feature = "std")]
86pub(crate) use std::io::Error;
87#[cfg(feature = "std")]
88pub(crate) use std::io::Read;
89#[cfg(feature = "std")]
90pub(crate) use std::io::Write;
91
92#[cfg(feature = "encoder")]
93pub use enc::*;
94pub use lz::MfType;
95#[cfg(feature = "lzip")]
96pub use lzip::LzipReader;
97#[cfg(all(feature = "lzip", feature = "std"))]
98pub use lzip::LzipReaderMt;
99#[cfg(all(feature = "lzip", feature = "encoder", feature = "std"))]
100pub use lzip::LzipWriterMt;
101#[cfg(all(feature = "lzip", feature = "encoder"))]
102pub use lzip::{LzipOptions, LzipWriter};
103pub use lzma_reader::{
104 LzmaReader, get_memory_usage as lzma_get_memory_usage,
105 get_memory_usage_by_props as lzma_get_memory_usage_by_props,
106};
107pub use lzma2_reader::{Lzma2Reader, get_memory_usage as lzma2_get_memory_usage};
108#[cfg(feature = "std")]
109pub use lzma2_reader_mt::Lzma2ReaderMt;
110#[cfg(not(feature = "std"))]
111pub use no_std::Error;
112#[cfg(not(feature = "std"))]
113pub use no_std::Read;
114#[cfg(not(feature = "std"))]
115pub use no_std::Write;
116use state::*;
117#[cfg(all(feature = "xz", feature = "std"))]
118pub use xz::XzReaderMt;
119#[cfg(all(feature = "xz", feature = "encoder", feature = "std"))]
120pub use xz::XzWriterMt;
121#[cfg(feature = "xz")]
122pub use xz::{CheckType, FilterConfig, FilterType, XzReader};
123#[cfg(all(feature = "xz", feature = "encoder"))]
124pub use xz::{XzOptions, XzWriter};
125
126#[cfg(feature = "std")]
128pub type Result<T> = core::result::Result<T, Error>;
129
130#[cfg(not(feature = "std"))]
132pub type Result<T> = core::result::Result<T, Error>;
133
134pub const DICT_SIZE_MIN: u32 = 4096;
136
137pub const DICT_SIZE_MAX: u32 = !15_u32;
139
140const LOW_SYMBOLS: usize = 1 << 3;
141const MID_SYMBOLS: usize = 1 << 3;
142const HIGH_SYMBOLS: usize = 1 << 8;
143
144const POS_STATES_MAX: usize = 1 << 4;
145const MATCH_LEN_MIN: usize = 2;
146const MATCH_LEN_MAX: usize = MATCH_LEN_MIN + LOW_SYMBOLS + MID_SYMBOLS + HIGH_SYMBOLS - 1;
147
148const DIST_STATES: usize = 4;
149const DIST_SLOTS: usize = 1 << 6;
150const DIST_MODEL_START: usize = 4;
151const DIST_MODEL_END: usize = 14;
152const FULL_DISTANCES: usize = 1 << (DIST_MODEL_END / 2);
153
154const ALIGN_BITS: usize = 4;
155const ALIGN_SIZE: usize = 1 << ALIGN_BITS;
156const ALIGN_MASK: usize = ALIGN_SIZE - 1;
157
158const REPS: usize = 4;
159
160const SHIFT_BITS: u32 = 8;
161const TOP_MASK: u32 = 0xFF000000;
162const BIT_MODEL_TOTAL_BITS: u32 = 11;
163const BIT_MODEL_TOTAL: u32 = 1 << BIT_MODEL_TOTAL_BITS;
164const PROB_INIT: u16 = (BIT_MODEL_TOTAL / 2) as u16;
165const MOVE_BITS: u32 = 5;
166const DIST_SPECIAL_INDEX: [usize; 10] = [0, 2, 4, 8, 12, 20, 28, 44, 60, 92];
167const DIST_SPECIAL_END: [usize; 10] = [2, 4, 8, 12, 20, 28, 44, 60, 92, 124];
168const TOP_VALUE: u32 = 0x0100_0000;
169const RC_BIT_MODEL_OFFSET: u32 = (1u32 << MOVE_BITS)
170 .wrapping_sub(1)
171 .wrapping_sub(BIT_MODEL_TOTAL);
172
173#[cfg(feature = "std")]
175fn set_error(
176 error: Error,
177 error_store: &std::sync::Arc<std::sync::Mutex<Option<Error>>>,
178 shutdown_flag: &std::sync::Arc<std::sync::atomic::AtomicBool>,
179) {
180 let mut guard = error_store.lock().unwrap();
181 if guard.is_none() {
182 *guard = Some(error);
183 }
184 shutdown_flag.store(true, std::sync::atomic::Ordering::Release);
185}
186
187pub(crate) struct LzmaCoder {
188 pub(crate) pos_mask: u32,
189 pub(crate) reps: [i32; REPS],
190 pub(crate) state: State,
191 pub(crate) is_match: [[u16; POS_STATES_MAX]; STATES],
192 pub(crate) is_rep: [u16; STATES],
193 pub(crate) is_rep0: [u16; STATES],
194 pub(crate) is_rep1: [u16; STATES],
195 pub(crate) is_rep2: [u16; STATES],
196 pub(crate) is_rep0_long: [[u16; POS_STATES_MAX]; STATES],
197 pub(crate) dist_slots: [[u16; DIST_SLOTS]; DIST_STATES],
198 dist_special: [u16; 124],
199 dist_align: [u16; ALIGN_SIZE],
200}
201
202pub(crate) fn coder_get_dict_size(len: usize) -> usize {
203 if len < DIST_STATES + MATCH_LEN_MIN {
204 len - MATCH_LEN_MIN
205 } else {
206 DIST_STATES - 1
207 }
208}
209
210pub(crate) fn get_dist_state(len: u32) -> u32 {
211 (if (len as usize) < DIST_STATES + MATCH_LEN_MIN {
212 len as usize - MATCH_LEN_MIN
213 } else {
214 DIST_STATES - 1
215 }) as u32
216}
217
218impl LzmaCoder {
219 pub(crate) fn new(pb: usize) -> Self {
220 let mut c = Self {
221 pos_mask: (1 << pb) - 1,
222 reps: Default::default(),
223 state: Default::default(),
224 is_match: Default::default(),
225 is_rep: Default::default(),
226 is_rep0: Default::default(),
227 is_rep1: Default::default(),
228 is_rep2: Default::default(),
229 is_rep0_long: Default::default(),
230 dist_slots: [[Default::default(); DIST_SLOTS]; DIST_STATES],
231 dist_special: [Default::default(); 124],
232 dist_align: Default::default(),
233 };
234 c.reset();
235 c
236 }
237
238 pub(crate) fn reset(&mut self) {
239 self.reps = [0; REPS];
240 self.state.reset();
241 for ele in self.is_match.iter_mut() {
242 init_probs(ele);
243 }
244 init_probs(&mut self.is_rep);
245 init_probs(&mut self.is_rep0);
246 init_probs(&mut self.is_rep1);
247 init_probs(&mut self.is_rep2);
248
249 for ele in self.is_rep0_long.iter_mut() {
250 init_probs(ele);
251 }
252 for ele in self.dist_slots.iter_mut() {
253 init_probs(ele);
254 }
255 init_probs(&mut self.dist_special);
256 init_probs(&mut self.dist_align);
257 }
258
259 #[inline(always)]
260 pub(crate) fn get_dist_special(&mut self, i: usize) -> &mut [u16] {
261 &mut self.dist_special[DIST_SPECIAL_INDEX[i]..DIST_SPECIAL_END[i]]
262 }
263}
264
265#[inline(always)]
266pub(crate) fn init_probs(probs: &mut [u16]) {
267 probs.fill(PROB_INIT);
268}
269
270pub(crate) struct LiteralCoder {
271 lc: u32,
272 literal_pos_mask: u32,
273}
274
275#[derive(Debug, Clone, Copy)]
276pub(crate) struct LiteralSubCoder {
277 probs: [u16; 0x300],
278}
279
280impl LiteralSubCoder {
281 pub fn new() -> Self {
282 let probs = [PROB_INIT; 0x300];
283 Self { probs }
284 }
285
286 pub fn reset(&mut self) {
287 self.probs = [PROB_INIT; 0x300];
288 }
289}
290
291impl LiteralCoder {
292 pub fn new(lc: u32, lp: u32) -> Self {
293 Self {
294 lc,
295 literal_pos_mask: (1 << lp) - 1,
296 }
297 }
298
299 pub(crate) fn get_sub_coder_index(&self, prev_byte: u32, pos: u32) -> u32 {
300 let low = prev_byte >> (8 - self.lc);
301 let high = (pos & self.literal_pos_mask) << self.lc;
302 low + high
303 }
304}
305
306pub(crate) struct LengthCoder {
307 choice: [u16; 2],
308 low: [[u16; LOW_SYMBOLS]; POS_STATES_MAX],
309 mid: [[u16; MID_SYMBOLS]; POS_STATES_MAX],
310 high: [u16; HIGH_SYMBOLS],
311}
312
313impl LengthCoder {
314 pub fn new() -> Self {
315 Self {
316 choice: Default::default(),
317 low: Default::default(),
318 mid: Default::default(),
319 high: [0; HIGH_SYMBOLS],
320 }
321 }
322
323 pub fn reset(&mut self) {
324 init_probs(&mut self.choice);
325 for ele in self.low.iter_mut() {
326 init_probs(ele);
327 }
328 for ele in self.mid.iter_mut() {
329 init_probs(ele);
330 }
331 init_probs(&mut self.high);
332 }
333}
334
335trait ByteReader {
336 fn read_u8(&mut self) -> Result<u8>;
337
338 fn read_u16(&mut self) -> Result<u16>;
339
340 fn read_u16_be(&mut self) -> Result<u16>;
341
342 fn read_u32(&mut self) -> Result<u32>;
343
344 fn read_u32_be(&mut self) -> Result<u32>;
345
346 fn read_u64(&mut self) -> Result<u64>;
347}
348
349trait ByteWriter {
350 fn write_u8(&mut self, value: u8) -> Result<()>;
351
352 fn write_u16(&mut self, value: u16) -> Result<()>;
353
354 fn write_u32(&mut self, value: u32) -> Result<()>;
355
356 fn write_u64(&mut self, value: u64) -> Result<()>;
357}
358
359impl<T: Read> ByteReader for T {
360 #[inline(always)]
361 fn read_u8(&mut self) -> Result<u8> {
362 let mut buf = [0; 1];
363 self.read_exact(&mut buf)?;
364 Ok(buf[0])
365 }
366
367 #[inline(always)]
368 fn read_u16(&mut self) -> Result<u16> {
369 let mut buf = [0; 2];
370 self.read_exact(buf.as_mut())?;
371 Ok(u16::from_le_bytes(buf))
372 }
373
374 #[inline(always)]
375 fn read_u16_be(&mut self) -> Result<u16> {
376 let mut buf = [0; 2];
377 self.read_exact(buf.as_mut())?;
378 Ok(u16::from_be_bytes(buf))
379 }
380
381 #[inline(always)]
382 fn read_u32(&mut self) -> Result<u32> {
383 let mut buf = [0; 4];
384 self.read_exact(buf.as_mut())?;
385 Ok(u32::from_le_bytes(buf))
386 }
387
388 #[inline(always)]
389 fn read_u32_be(&mut self) -> Result<u32> {
390 let mut buf = [0; 4];
391 self.read_exact(buf.as_mut())?;
392 Ok(u32::from_be_bytes(buf))
393 }
394
395 #[inline(always)]
396 fn read_u64(&mut self) -> Result<u64> {
397 let mut buf = [0; 8];
398 self.read_exact(buf.as_mut())?;
399 Ok(u64::from_le_bytes(buf))
400 }
401}
402
403impl<T: Write> ByteWriter for T {
404 #[inline(always)]
405 fn write_u8(&mut self, value: u8) -> Result<()> {
406 self.write_all(&[value])
407 }
408
409 #[inline(always)]
410 fn write_u16(&mut self, value: u16) -> Result<()> {
411 self.write_all(&value.to_le_bytes())
412 }
413
414 #[inline(always)]
415 fn write_u32(&mut self, value: u32) -> Result<()> {
416 self.write_all(&value.to_le_bytes())
417 }
418
419 #[inline(always)]
420 fn write_u64(&mut self, value: u64) -> Result<()> {
421 self.write_all(&value.to_le_bytes())
422 }
423}
424
425#[cfg(feature = "std")]
426#[inline(always)]
427fn error_eof() -> Error {
428 Error::new(std::io::ErrorKind::UnexpectedEof, "unexpected EOF")
429}
430
431#[cfg(feature = "std")]
432#[inline(always)]
433fn error_other(msg: &'static str) -> Error {
434 Error::other(msg)
435}
436
437#[cfg(feature = "std")]
438#[inline(always)]
439fn error_invalid_input(msg: &'static str) -> Error {
440 Error::new(std::io::ErrorKind::InvalidInput, msg)
441}
442
443#[cfg(feature = "std")]
444#[inline(always)]
445fn error_invalid_data(msg: &'static str) -> Error {
446 Error::new(std::io::ErrorKind::InvalidData, msg)
447}
448
449#[cfg(feature = "std")]
450#[inline(always)]
451fn error_out_of_memory(msg: &'static str) -> Error {
452 Error::new(std::io::ErrorKind::OutOfMemory, msg)
453}
454
455#[cfg(feature = "std")]
456#[inline(always)]
457fn error_unsupported(msg: &'static str) -> Error {
458 Error::new(std::io::ErrorKind::Unsupported, msg)
459}
460
461#[cfg(feature = "std")]
462#[inline(always)]
463fn copy_error(error: &Error) -> Error {
464 Error::new(error.kind(), error.to_string())
465}
466
467#[cfg(not(feature = "std"))]
468#[inline(always)]
469fn error_eof() -> Error {
470 Error::Eof
471}
472
473#[cfg(not(feature = "std"))]
474#[inline(always)]
475fn error_other(msg: &'static str) -> Error {
476 Error::Other(msg)
477}
478
479#[cfg(not(feature = "std"))]
480#[inline(always)]
481fn error_invalid_input(msg: &'static str) -> Error {
482 Error::InvalidInput(msg)
483}
484
485#[cfg(not(feature = "std"))]
486#[inline(always)]
487fn error_invalid_data(msg: &'static str) -> Error {
488 Error::InvalidData(msg)
489}
490
491#[cfg(not(feature = "std"))]
492#[inline(always)]
493fn error_out_of_memory(msg: &'static str) -> Error {
494 Error::OutOfMemory(msg)
495}
496
497#[cfg(not(feature = "std"))]
498#[inline(always)]
499fn error_unsupported(msg: &'static str) -> Error {
500 Error::Unsupported(msg)
501}
502
503#[cfg(not(feature = "std"))]
504#[inline(always)]
505fn copy_error(error: &Error) -> Error {
506 *error
507}
508
509struct CountingReader<R> {
510 inner: R,
511 bytes_read: u64,
512}
513
514impl<R> CountingReader<R> {
515 fn new(inner: R) -> Self {
516 Self {
517 inner,
518 bytes_read: 0,
519 }
520 }
521
522 fn with_count(inner: R, bytes_read: u64) -> Self {
523 Self { inner, bytes_read }
524 }
525
526 fn bytes_read(&self) -> u64 {
527 self.bytes_read
528 }
529
530 fn into_inner(self) -> R {
531 self.inner
532 }
533
534 fn inner(&self) -> &R {
535 &self.inner
536 }
537
538 fn inner_mut(&mut self) -> &mut R {
539 &mut self.inner
540 }
541}
542
543impl<R: Read> Read for CountingReader<R> {
544 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
545 let read_size = self.inner.read(buf)?;
546 self.bytes_read += read_size as u64;
547 Ok(read_size)
548 }
549}
550
551#[cfg(feature = "encoder")]
552struct CountingWriter<W> {
553 inner: W,
554 bytes_written: u64,
555}
556
557#[cfg(feature = "encoder")]
558impl<W> CountingWriter<W> {
559 fn new(inner: W) -> Self {
560 Self {
561 inner,
562 bytes_written: 0,
563 }
564 }
565
566 fn bytes_written(&self) -> u64 {
567 self.bytes_written
568 }
569
570 fn into_inner(self) -> W {
571 self.inner
572 }
573
574 fn inner(&self) -> &W {
575 &self.inner
576 }
577
578 fn inner_mut(&mut self) -> &mut W {
579 &mut self.inner
580 }
581}
582
583#[cfg(feature = "encoder")]
584impl<W: Write> Write for CountingWriter<W> {
585 fn write(&mut self, buf: &[u8]) -> Result<usize> {
586 let bytes_written = self.inner.write(buf)?;
587 self.bytes_written += bytes_written as u64;
588 Ok(bytes_written)
589 }
590
591 fn flush(&mut self) -> Result<()> {
592 self.inner.flush()
593 }
594}
595
596trait AutoFinish {
598 fn finish_ignore_error(self);
600}
601
602#[allow(private_bounds)]
604pub struct AutoFinisher<T: AutoFinish>(Option<T>);
605
606impl<T: AutoFinish> Drop for AutoFinisher<T> {
607 fn drop(&mut self) {
608 if let Some(writer) = self.0.take() {
609 writer.finish_ignore_error();
610 }
611 }
612}
613
614impl<T: AutoFinish> core::ops::Deref for AutoFinisher<T> {
615 type Target = T;
616
617 fn deref(&self) -> &Self::Target {
618 self.0.as_ref().unwrap()
619 }
620}
621
622impl<T: AutoFinish> core::ops::DerefMut for AutoFinisher<T> {
623 fn deref_mut(&mut self) -> &mut Self::Target {
624 self.0.as_mut().unwrap()
625 }
626}
627
628impl<T: AutoFinish + Write> Write for AutoFinisher<T> {
629 fn write(&mut self, buf: &[u8]) -> Result<usize> {
630 use core::ops::DerefMut;
631
632 self.deref_mut().write(buf)
633 }
634
635 fn flush(&mut self) -> Result<()> {
636 use core::ops::DerefMut;
637
638 self.deref_mut().flush()
639 }
640}