12 releases

0.1.6 Apr 21, 2022
0.1.5 Apr 17, 2021
0.1.4 Jan 29, 2021
0.1.3 Nov 10, 2020
0.1.0-alpha Jul 27, 2020

#128 in #hacktoberfest

Download history 50818/week @ 2022-03-11 57184/week @ 2022-03-18 57210/week @ 2022-03-25 61642/week @ 2022-04-01 58380/week @ 2022-04-08 49525/week @ 2022-04-15 58400/week @ 2022-04-22 59228/week @ 2022-04-29 61941/week @ 2022-05-06 57319/week @ 2022-05-13 59430/week @ 2022-05-20 56033/week @ 2022-05-27 58898/week @ 2022-06-03 57246/week @ 2022-06-10 65125/week @ 2022-06-17 51797/week @ 2022-06-24

241,839 downloads per month
Used in 974 crates (8 directly)

MIT/Apache

110KB
2K SLoC

weezl

LZW en- and decoding that goes weeeee!

Overview

This library, written in purely safe and dependency-less Rust, provides encoding and decoding for lzw compression in the style as it occurs in gif and tiff image formats. It has a standalone binary that may be used to handle those data streams but it is not compatible with Spencer's compress and uncompress binaries (though a drop-in may be developed at a later point).

Using in a no_std environment is also possible though an allocator is required. This, too, may be relaxed in a later release. A feature flag already exists but currently turns off almost all interfaces.

License

All code is dual licensed MIT OR Apache-2.0.


lib.rs:

LZW decoder and encoder

This crates provides an Encoder and a Decoder in their respective modules. The code words are written from and to bit byte slices (or streams) where it is possible to write either the most or least significant bits first. The maximum possible code size is 12 bits, the smallest available code size is 2 bits.

Example

These two code blocks show the compression and corresponding decompression. Note that you must use the same arguments to Encoder and Decoder, otherwise the decoding might fail or produce bad results.

use weezl::{BitOrder, encode::Encoder};

let data = b"Hello, world"; let compressed = Encoder::new(BitOrder::Msb, 9) .encode(data) .unwrap();


use weezl::{BitOrder, decode::Decoder};
# let compressed = b"\x80\x04\x81\x94l\x1b\x06\xf0\xb0 \x1d\xc6\xf1\xc8l\x19 \x10".to_vec();
# let data = b"Hello, world";

let decompressed = Decoder::new(BitOrder::Msb, 9)
    .decode(&compressed)
    .unwrap();
assert_eq!(decompressed, data);

LZW Details

The de- and encoder expect the LZW stream to start with a clear code and end with an end code which are defined as follows:

  • CLEAR_CODE == 1 << min_code_size
  • END_CODE == CLEAR_CODE + 1

For optimal performance, all buffers and input and output slices should be as large as possible and at least 2048 bytes long. This extends to input streams which should have similarly sized buffers. This library uses Rust's standard allocation interfaces (Box and Vec to be precise). Since there are no ways to handle allocation errors it is not recommended to operate it on 16-bit targets.

Allocations and standard library

The main algorithm can be used in no_std as well, although it requires an allocator. This restriction might be lifted at a later stage. For this you should deactivate the std feature. The main interfaces stay intact but the into_stream combinator is no available.

Dependencies

~170KB