ppmd_rust/
lib.rs

1//! PPMd compression / decompression. It's a port of the PPMd C-code from 7-Zip to Rust.
2//!
3//! The following variants are provided:
4//!
5//! - The PPMd7 (PPMdH) as used by the 7z archive format
6//! - The PPMd8 (PPMdI rev.1) as used by the zip archive format
7//!
8//!
9//! ## Acknowledgement
10//!
11//! This port is based on the 7zip version of PPMd by Igor Pavlov, which in turn was based on the
12//! PPMd var.H (2001) / PPMd var.I (2002) code by Dmitry Shkarin. The carryless range coder of
13//! PPMd8 was originally written by Dmitry Subbotin (1999).
14//!
15//! ## License
16//!
17//! The code in this crate is in the public domain as the original code by their authors.
18mod decoder_7;
19mod encoder_7;
20
21mod decoder_8;
22mod encoder_8;
23mod internal;
24
25pub use decoder_7::Ppmd7Decoder;
26pub use decoder_8::Ppmd8Decoder;
27pub use encoder_7::Ppmd7Encoder;
28pub use encoder_8::Ppmd8Encoder;
29
30/// The minimal order PPMd7 supports.
31pub const PPMD7_MIN_ORDER: u32 = 2;
32
33/// The maximal order PPMd7 supports.
34pub const PPMD7_MAX_ORDER: u32 = 64;
35
36/// The minimal memory that PPMd7 supports.
37pub const PPMD7_MIN_MEM_SIZE: u32 = 2048;
38
39/// The maximal memory that PPMd7 supports.
40pub const PPMD7_MAX_MEM_SIZE: u32 = 4294967259;
41
42/// The minimal order PPMd8 supports.
43pub const PPMD8_MIN_ORDER: u32 = 2;
44
45/// The maximal order PPMd8 supports.
46pub const PPMD8_MAX_ORDER: u32 = 16;
47
48/// The minimal memory that PPMd8 supports.
49pub const PPMD8_MIN_MEM_SIZE: u32 = 2048;
50
51/// The maximal memory that PPMd8 supports.
52pub const PPMD8_MAX_MEM_SIZE: u32 = u32::MAX;
53
54const SYM_END: i32 = -1;
55const SYM_ERROR: i32 = -2;
56
57/// Error type of the crate.
58pub type Result<T> = core::result::Result<T, Error>;
59
60/// The restore method used in PPMd8.
61#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
62pub enum RestoreMethod {
63    Restart = 0 as _,
64    CutOff = 1 as _,
65    Unsupported = 2 as _,
66}
67
68macro_rules! impl_from_int_for_restore_method {
69    ($($int_type:ty),+ $(,)?) => {
70        $(
71            impl From<$int_type> for RestoreMethod {
72                fn from(value: $int_type) -> Self {
73                    match value {
74                        0 => RestoreMethod::Restart,
75                        1 => RestoreMethod::CutOff,
76                        _ => RestoreMethod::Unsupported,
77                    }
78                }
79            }
80        )+
81    };
82}
83
84impl_from_int_for_restore_method!(u8, u16, u32, u64, u128, usize);
85impl_from_int_for_restore_method!(i8, i16, i32, i64, i128, isize);
86
87/// Crate error type.
88pub enum Error {
89    /// The range decoder could not be properly initialized.
90    RangeDecoderInitialization,
91    /// Invalid parameters provided.
92    InvalidParameter,
93    /// General IO error.
94    IoError(std::io::Error),
95    /// The needed memory could not be allocated.
96    MemoryAllocation,
97}
98
99impl std::fmt::Debug for Error {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        match self {
102            Error::RangeDecoderInitialization => {
103                write!(f, "Could not initialize the range decoder")
104            }
105            Error::InvalidParameter => write!(f, "Wrong PPMd parameter"),
106            Error::IoError(err) => write!(f, "Io error: {err}"),
107            Error::MemoryAllocation => write!(f, "Memory allocation error (out of memory?)"),
108        }
109    }
110}
111
112impl std::fmt::Display for Error {
113    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114        std::fmt::Debug::fmt(self, f)
115    }
116}
117
118impl std::error::Error for Error {}