salzweg/
lib.rs

1//! LZW encoder and decoder.
2//!
3//! This crate provides a Encoder and Decoder to compress and decompress LZW data.
4//! This particular implementation provides the GIF and TIFF variation, as well
5//! as the original fixed 12 bit LZW variation.
6//!
7//! It's fast, and use limited memory to do so: the decoder only uses the stack.
8//!
9//! It works with any [std::io::Read] and [std::io::Write].
10//!
11//! # Examples
12//!
13//! ## Encoding GIF data
14//! ```
15//! use salzweg::{
16//!     decoder::{DecodingError, GifStyleDecoder},
17//!     encoder::{EncodingError, GifStyleEncoder},
18//!     Endianness,
19//! };
20//!
21//! let data = [0, 0, 1, 3];
22//! let mut compressed = vec![];
23//! let mut decompressed = vec![];
24//!
25//! GifStyleEncoder::encode(&data[..], &mut compressed, 2).expect("Compression failed");
26//!
27//! assert_eq!(compressed, [0x04, 0x32, 0x05]);
28//!
29//! GifStyleDecoder::decode(&compressed[..], &mut decompressed, 2).expect("Decompression failed");
30//!
31//! assert_eq!(decompressed, data);
32//! ```
33//!
34//! ## Compressing a file using the TIFF variation
35//! ```
36//! use salzweg::encoder::TiffStyleEncoder;
37//! use std::{fs::File, io::BufReader};
38//!
39//! let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
40//!     .parent()
41//!     .expect("Couldn't find parent folder")
42//!     .join("test-assets/lorem_ipsum.txt");
43//!
44//! let output_file = std::io::sink(); // Let's pretend this is a file.
45//!
46//! let data = BufReader::new(File::open(path).expect("Couldn't open the file"));
47//!
48//! TiffStyleEncoder::encode(data, output_file).expect("Compression failed");
49//! ```
50
51pub mod decoder;
52pub mod encoder;
53mod io;
54
55/// The bit ordering when encoding or decoding LZW.
56///
57/// This crate currently only supports the GIF variation and GIF typically use little endian,
58/// but big endian still works.
59#[derive(Debug)]
60pub enum Endianness {
61    /// Most significant order.
62    BigEndian,
63    /// Least significant order.
64    LittleEndian,
65}
66
67/// Code size increase strategy.
68///
69/// For variable code size encoding, there is a difference between the strategy used
70/// by TIFF compared to GIF or other variable code LZW.
71#[derive(Debug)]
72pub enum CodeSizeStrategy {
73    /// Default code size increase.
74    ///
75    /// The read and write size increase when the dictionary's size is equal to 2.pow2(code-size).
76    Default,
77    /// Code size increase strategy for TIFF.
78    ///
79    /// The read and write size increase when the dictionary's size is equal
80    /// to 2.pow2(code-size) - 1.
81    Tiff,
82}
83
84impl CodeSizeStrategy {
85    pub(crate) const fn increment(&self) -> u16 {
86        match self {
87            CodeSizeStrategy::Default => 0,
88            CodeSizeStrategy::Tiff => 1,
89        }
90    }
91}