hcompress
A pure-Rust port of the CFITSIO implementation of the HCompress image compression algorithm.
HCompress is an image compression scheme developed at the Space Telescope Science Institute and widely used to compress astronomical images (for example, in FITS tile compression). It works particularly well on the smoothly-varying, noisy two-dimensional integer images that are typical in astronomy, and supports both lossless and lossy compression.
For a description of how the algorithm works, and the constraints on its use, see ALGORITHM.md.
Features
- Lossless and lossy compression of 2-D integer images.
- 16-bit images stored in
i32(write/read). - 32-bit images stored in
i64(write64/read64). - Faithful to the reference CFITSIO/HCompress bitstream, including the two-byte magic
code
0xDD 0x99. - No
unsafe-heavy dependencies; pure safe Rust overstd::io::Write.
Installation
Add the crate to your Cargo.toml:
[]
= "0.4"
Usage
16-bit images (i32)
The encoder writes the compressed bytes into any std::io::Write sink. The decoder writes the
reconstructed image into a caller-provided buffer.
use HCDecoder;
use HCEncoder;
// A small 4 x 3 image (ny is the fastest-varying axis).
let nx = 4; // slow axis (rows)
let ny = 3; // fast axis (columns)
let original: = vec!;
// --- Compress ---
// NOTE: the encoder H-transforms the input in place, so pass a copy if you
// still need the original data afterwards.
let mut work = original.clone;
let mut compressed: = Vecnew;
let scale = 0; // 0 = lossless; larger values give more (lossy) compression
let mut encoder = new;
encoder.write.unwrap;
// --- Decompress ---
let mut restored: = vec!;
let mut decoder = new;
let smooth = 0; // apply smoothing on decode (only relevant for lossy data)
let = decoder.read.unwrap;
assert_eq!;
assert_eq!; // lossless round-trip
32-bit images (i64)
Use write64 / read64 for images whose values exceed the 24-bit range that the 16-bit path can
represent losslessly. The working buffer passed to read64 is an i64 slice; the reconstructed
i32 values are written back into the low half of that buffer (see ALGORITHM.md
for the exact layout).
API summary
| Function | Input element | Description |
|---|---|---|
HCEncoder::write(a, ny, nx, scale) |
i32 |
Compress a 16-bit image (16-bit values padded to i32). |
HCEncoder::write64(a, ny, nx, scale) |
i64 |
Compress a 32-bit image (32-bit values padded to i64). |
HCDecoder::read(input, smooth, a) |
i32 |
Decompress into a caller-allocated i32 buffer. |
HCDecoder::read64(input, smooth, a) |
i64 |
Decompress into a caller-allocated i64 buffer. |
The read/read64 functions return (nx, ny, scale) on success.
NOTE: the
nxandnydimensions as used in this library are reversed from the usual FITS notation.nyis the fastest-varying dimension, which is usually considered the X axis in a FITS image display.NOTE: the non-
64functions support shorts padded to int, and the64functions support int padded to long, matching the original implementation.
See ALGORITHM.md for the full set of constraints (minimum sizes, in-place mutation, scale semantics, overflow behaviour).
References
- Paper detailing the algorithm:
https://fits.gsfc.nasa.gov/registry/tilecompression/tilecompression2.3.pdf
(also included in
docs/paper.pdf). - Original library: https://www.stsci.edu/software/hcompress.html
Changes
See CHANGELOG.md.
License
This crate is distributed under the MIT License.
It is derived from the CFITSIO / HCompress sources; the upstream licenses are reproduced in the
licenses/ directory: