Packbits-rle
Packbits-rle is a rust implementation of the PackBits algorithm commonly used on the classic Apple Macintosh platform.
The PackBits algorithm
PackBits is a lossless compression algorithm using run-length encoding. It was commonly used on the Macintosh computer, especially in graphics related applications, but can also be found in StuffIt archive files.
The algorithm described nicely on the PackBits Wikipedia page and Apple's Technical Note TN1023 (kindly preserved by the Internet Archive).
Overview
The crate provides high level functions to expand PackBits from a buffer using [unpack_buf] and [unpack] to expand all data coming from an [io::Read] stream.
// Using the canonical sample input from Apple Technical Note TN1023
let packbits_data = b"\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA";
let data = unpack_buf
.expect;
assert_eq!;
These functions allocate data in a [Vec] as needed and might not be suitable
for large or unknown inputs.
To gain finer control over how much memory is used during decoding, you can employ a
packbits_rle::Reader to wrap an existing [io::Read] stream and unpack data in chunks:
use ;
const CHUNK_SIZE: usize = 1024;
let packbits_data = b"\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA";
let reader = new;
let mut reader = new;
let mut buffer = vec!;
loop
Once you're done expanding the data, you can get the original [io::Read] back via the
into_inner method.
Data can also be expanded from [io::Read]ers without the need to relinquish
ownership by importing the [PackBitsReaderExt] trait and calling its [PackBitsReaderExt::read_packbits]
function on the reader you already have.
use ;
use PackBitsReaderExt;
// Build an input stream specifying the size of unpacked data (0x18) in a single byte,
// followed by PackBits data and then some more unpacked bytes (0xBA)
let mixed_data = b"\x18\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA\xBA";
let mut reader = new;
let mut size = ;
let mut more_data = ;
// Read unpacked size from reader
reader.read.unwrap;
// Unpack PackBits at current reader position until the buffer is full or the stream ends
let mut unpacked_packbit_bits = vec!;
reader.read_packbits.unwrap;
// Continue reading "regular" data from the reader
reader.read.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
While this approach keeps allocations in check, it does not lend itself well to precise error handling.
You can assert even finer control over the unpacking process by using the [Operation] struct.
This is especially useful if PackBits compressed data has been split up between chunks and might end abruptly.
use ;
use ;
let input_chunk_1 = b"\xFE\xAA\x02\x80\x00\x2A".as_slice;
let input_chunk_2 = b"\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA".as_slice;
let mut stream = new;
let mut operation = default;
loop