//! # }
//! ```
+use crate::options::NAOptionDefinitionType;
use crate::io::byteio::*;
use crate::io::bitreader::*;
use crate::io::codebook::*;
///!
///! [`DecompressError::ShortData`]: ../enum.DecompressError.html#variant.ShortData
///! [`DecompressError::OutputFull`]: ../enum.DecompressError.html#variant.OutputFull
- #[allow(clippy::comparison_chain)]
pub fn decompress_data(&mut self, src: &[u8], dst: &mut [u8], continue_block: bool) -> DecompressResult<usize> {
+ self.decompress_data_internal(src, dst, continue_block, false)
+ }
+ ///! Tries to decompress whole input chunk to the output buffer.
+ pub fn decompress_block(&mut self, src: &[u8], dst: &mut [u8]) -> DecompressResult<usize> {
+ self.decompress_data_internal(src, dst, false, true)
+ }
+ #[allow(clippy::comparison_chain)]
+ fn decompress_data_internal(&mut self, src: &[u8], dst: &mut [u8], continue_block: bool, do_one_block: bool) -> DecompressResult<usize> {
if src.is_empty() || dst.is_empty() {
return Err(DecompressError::InvalidArgument);
}
self.output_idx = 0;
CurrentSource::reinit(src, self.br)
};
+ if do_one_block {
+ self.output_idx = 0;
+ }
// check for zlib stream header
if let (&InflateState::Start, true) = (&self.state, src.len() > 2) {
let cm = src[0] & 0xF;
match self.state {
InflateState::Start | InflateState::BlockStart => {
if csrc.left() == 0 {
+ if do_one_block {
+ return Ok(self.output_idx);
+ }
self.br = csrc.br;
return Err(DecompressError::ShortData);
}
}
}
}
+ ///! Resets decoder state.
+ pub fn reset(&mut self) {
+ self.bpos = 0;
+ self.output_idx = 0;
+ self.full_pos = 0;
+ self.state = InflateState::Start;
+ }
+
///! Decompresses input data into output returning the uncompressed data length.
pub fn uncompress(src: &[u8], dst: &mut [u8]) -> DecompressResult<usize> {
let mut inflate = Self::new();
Best,
}
+impl Default for DeflateMode {
+ fn default() -> Self { DeflateMode::Better }
+}
+
+pub const DEFLATE_MODE_DESCRIPTION: &str = "Deflate compression level.";
+///! Deflate option for no compression.
+pub const DEFLATE_MODE_NONE: &str = "none";
+///! Deflate option for fast compression.
+pub const DEFLATE_MODE_FAST: &str = "fast";
+///! Deflate option for better compression.
+pub const DEFLATE_MODE_BETTER: &str = "better";
+///! Deflate option for best compression.
+pub const DEFLATE_MODE_BEST: &str = "best";
+
+///! All possible option values for deflate compression.
+pub const DEFLATE_OPTION_VALUES: NAOptionDefinitionType = NAOptionDefinitionType::String(Some(&[DEFLATE_MODE_NONE, DEFLATE_MODE_FAST, DEFLATE_MODE_BETTER, DEFLATE_MODE_BEST]));
+
+impl std::str::FromStr for DeflateMode {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ DEFLATE_MODE_NONE => Ok(DeflateMode::NoCompr),
+ DEFLATE_MODE_FAST => Ok(DeflateMode::Fast),
+ DEFLATE_MODE_BETTER => Ok(DeflateMode::Better),
+ DEFLATE_MODE_BEST => Ok(DeflateMode::Best),
+ _ => Err(()),
+ }
+ }
+}
+
+impl ToString for DeflateMode {
+ fn to_string(&self) -> String {
+ match *self {
+ DeflateMode::NoCompr => DEFLATE_MODE_NONE.to_string(),
+ DeflateMode::Fast => DEFLATE_MODE_FAST.to_string(),
+ DeflateMode::Better => DEFLATE_MODE_BETTER.to_string(),
+ DeflateMode::Best => DEFLATE_MODE_BEST.to_string(),
+ }
+ }
+}
+
#[derive(Clone,Copy,Debug,PartialEq)]
enum Mode {
Copy,
sum1: u32,
sum2: u32,
zlib_mode: bool,
- parser: Box<dyn LZParse>,
+ parser: Box<dyn LZParse + Send>,
}
impl Deflate {
///! Creates a new instance of `Deflate`.
pub fn new(mode: DeflateMode) -> Self {
let (mode, parser) = match mode {
- DeflateMode::NoCompr => (Mode::Copy, Box::new(NoParser{}) as Box<dyn LZParse>),
- DeflateMode::Fast => (Mode::Fixed, Box::new(GreedyParser{}) as Box<dyn LZParse>),
- DeflateMode::Better => (Mode::Dynamic, Box::new(LazyParser{}) as Box<dyn LZParse>),
- DeflateMode::Best => (Mode::Dynamic, Box::new(OptimalParser::new()) as Box<dyn LZParse>),
+ DeflateMode::NoCompr => (Mode::Copy, Box::new(NoParser{}) as Box<dyn LZParse + Send>),
+ DeflateMode::Fast => (Mode::Fixed, Box::new(GreedyParser{}) as Box<dyn LZParse + Send>),
+ DeflateMode::Better => (Mode::Dynamic, Box::new(LazyParser{}) as Box<dyn LZParse + Send>),
+ DeflateMode::Best => (Mode::Dynamic, Box::new(OptimalParser::new()) as Box<dyn LZParse + Send>),
};
Self {
mode, parser,
self.write_zlib_footer(wr);
}
}
+ ///! Tells the encoder to compress the data it received and flush it.
+ pub fn compress_flush(&mut self, wr: &mut DeflateWriter) {
+ if self.ssize > 0 {
+ self.do_block(wr, false);
+ }
+ if (wr.bits & 7) != 0 {
+ // write zero-length copy block for byte-alignment
+ wr.write(0, 1);
+ wr.write(0, 2);
+ wr.align();
+ wr.write(0, 16);
+ wr.write(0xFFFF, 16);
+ }
+ }
fn do_block(&mut self, wr: &mut DeflateWriter, final_block: bool) {
const CRC_BASE: u32 = 65521;
for &b in self.srcbuf[..self.ssize].iter() {