Skip to main content

tiff/encoder/compression/
mod.rs

1use crate::tags::CompressionMethod;
2use std::io::{self, Write};
3
4#[cfg(feature = "deflate")]
5mod deflate;
6#[cfg(feature = "lzw")]
7mod lzw;
8mod packbits;
9mod uncompressed;
10
11#[cfg(feature = "deflate")]
12pub use self::deflate::{Deflate, DeflateLevel};
13
14#[cfg(feature = "lzw")]
15pub use self::lzw::Lzw;
16
17pub use self::packbits::Packbits;
18pub use self::uncompressed::Uncompressed;
19
20/// An algorithm used for compression
21pub trait CompressionAlgorithm {
22    /// The algorithm writes data directly into the writer.
23    /// It returns the total number of bytes written.
24    fn write_to<W: Write>(&mut self, writer: &mut W, bytes: &[u8]) -> Result<u64, io::Error>;
25}
26
27/// An algorithm used for compression with associated enums and optional configurations.
28pub trait Compression: CompressionAlgorithm {
29    /// The corresponding tag to the algorithm.
30    const COMPRESSION_METHOD: CompressionMethod;
31
32    /// Method to optain a type that can store each variant of comression algorithm.
33    fn get_algorithm(&self) -> Compressor;
34}
35
36/// An enum to store each compression algorithm.
37#[non_exhaustive]
38pub enum Compressor {
39    Uncompressed(Uncompressed),
40    #[cfg(feature = "lzw")]
41    Lzw(Lzw),
42    #[cfg(feature = "deflate")]
43    Deflate(Deflate),
44    Packbits(Packbits),
45}
46
47impl Default for Compressor {
48    /// The default compression strategy does not apply any compression.
49    fn default() -> Self {
50        Compressor::Uncompressed(Uncompressed)
51    }
52}
53
54impl CompressionAlgorithm for Compressor {
55    fn write_to<W: Write>(&mut self, writer: &mut W, bytes: &[u8]) -> Result<u64, io::Error> {
56        match self {
57            Compressor::Uncompressed(algorithm) => algorithm.write_to(writer, bytes),
58            #[cfg(feature = "lzw")]
59            Compressor::Lzw(algorithm) => algorithm.write_to(writer, bytes),
60            #[cfg(feature = "deflate")]
61            Compressor::Deflate(algorithm) => algorithm.write_to(writer, bytes),
62            Compressor::Packbits(algorithm) => algorithm.write_to(writer, bytes),
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    pub const TEST_DATA: &[u8] = b"This is a string for checking various compression algorithms.";
70}