#![warn(missing_docs)]
#![forbid(unsafe_code)]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
mod compress_1;
mod compress_999;
mod config;
mod decompress;
mod optimize;
mod swd;
use core::fmt::{self, Display, Formatter};
pub use decompress::decompress;
pub use optimize::optimize;
use alloc::vec::Vec;
use compress_1::compress_1;
use compress_999::compress_999;
pub fn compress(src: &[u8], level: CompressLevel) -> Vec<u8> {
match level.0 {
1 => compress_1(src, 11),
2 => compress_1(src, 12),
3 => compress_1(src, 14),
4 => compress_1(src, 15),
5 => compress_999(src, 0, 0, 0, 8, 4, 0),
6 => compress_999(src, 0, 0, 0, 16, 8, 0),
7 => compress_999(src, 0, 0, 0, 32, 16, 0),
8 => compress_999(src, 1, 5, 5, 16, 16, 0),
9 => compress_999(src, 1, 8, 16, 32, 32, 0),
10 => compress_999(src, 1, 8, 16, 128, 128, 0),
11 => compress_999(src, 2, 8, 32, 128, 256, 0),
12 => compress_999(src, 2, 32, 128, 2048, 2048, 1),
13 => compress_999(src, 2, 2048, 2048, 2048, 4096, 1),
_ => unreachable!(),
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct CompressLevel(u8);
impl CompressLevel {
pub const fn new(level: u8) -> Self {
if level < Self::MIN.0 {
Self::MIN
} else if level > Self::MAX.0 {
Self::MAX
} else {
Self(level)
}
}
pub const MIN: Self = Self(1);
pub const MAX: Self = Self(13);
}
impl Default for CompressLevel {
fn default() -> Self {
Self(3)
}
}
impl Display for CompressLevel {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}
impl From<u8> for CompressLevel {
fn from(level: u8) -> Self {
Self::new(level)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum DecompressError {
InvalidInput,
OutputLength,
}
impl Display for DecompressError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match *self {
Self::InvalidInput => f.write_str("invalid input"),
Self::OutputLength => f.write_str("output length does not match"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for DecompressError {}