c8069b5cc194325e75050f591d8e8671fa52f6cc
[nihav.git] / nihav-core / src / compr / mod.rs
1 //! Various compression formats support.
2 #[cfg(feature="deflate")]
3 pub mod deflate;
4
5 use crate::io::byteio::ByteIOError;
6 use crate::io::bitreader::BitReaderError;
7 use crate::io::codebook::CodebookError;
8
9 /// A list specifying general compression errors.
10 #[derive(Debug)]
11 pub enum DecompressError {
12 /// Compressed stream header contains errors.
13 InvalidHeader,
14 /// Compressed stream checksum does not match unpacked contents.
15 CRCError,
16 /// Compressed stream contains a combination of bits that cannot be decoded.
17 InvalidData,
18 /// Compressed stream ended prematurely.
19 ShortData,
20 /// There is more data than what can fit output buffer.
21 OutputFull,
22 /// Provided function argument is invalid.
23 InvalidArgument,
24 /// Compressed stream contains features that cannot be decoded.
25 Unsupported,
26 /// Underlying input reader had a problem.
27 IOError,
28 }
29
30 /// A specialised `Result` type for codebook operations.
31 pub type DecompressResult<T> = Result<T, DecompressError>;
32
33 impl From<ByteIOError> for DecompressError {
34 fn from(e: ByteIOError) -> Self {
35 match e {
36 ByteIOError::EOF => DecompressError::ShortData,
37 _ => DecompressError::IOError,
38 }
39 }
40 }
41
42 impl From<BitReaderError> for DecompressError {
43 fn from(e: BitReaderError) -> Self {
44 match e {
45 BitReaderError::BitstreamEnd => DecompressError::ShortData,
46 _ => DecompressError::InvalidData,
47 }
48 }
49 }
50
51 impl From<CodebookError> for DecompressError {
52 fn from(_: CodebookError) -> Self {
53 DecompressError::InvalidData
54 }
55 }
56
57 ///! Copies requested amount of bytes from previous position in the same buffer.
58 ///! If source area overlaps with destination area already copied values should be used e.g. copying with offset 1 means essentially to repeat previous byte requested number of times.
59 pub fn lz_copy(buf: &mut [u8], dst_pos: usize, offset: usize, len: usize) {
60 if dst_pos < offset {
61 panic!("Copy offset is before buffer start.");
62 }
63 let ipos = dst_pos - offset;
64 let buf = &mut buf[ipos..];
65 if ipos + len <= dst_pos {
66 let (src, dst) = buf.split_at_mut(offset);
67 (&mut dst[..len]).copy_from_slice(&src[..len]);
68 } else {
69 for i in 0..len {
70 buf[offset + i] = buf[i];
71 }
72 }
73 }