]>
Commit | Line | Data |
---|---|---|
0443d0c5 KS |
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 | } |