Skip to main content

Crate depthpack

Crate depthpack 

Source
Expand description

§depthpack

Compact codec for 16-bit raster fields with nodata — built for depth maps produced by projecting LiDAR into panoramic (equirectangular) camera frames.

A depthpack blob stores an integer lattice of u16 counts (0 = nodata) plus a physical mapping value = count · scale + offset and an opaque unit label. The encoder predicts each valid count from its causal neighbours with the LOCO-I / JPEG-LS median edge detector (MED) and compresses the zigzag residuals plus a 1-bpp validity mask with zstd. Smooth surfaces — the dominant content of a depth map built from a triangulated point cloud — leave near-zero residuals, which is why this beats generic image codecs on both size and speed for this data.

The lattice roundtrips bit-exact; the codec never quantizes. Pick your precision by choosing scale and quantizing before you encode (e.g. millimetres → scale = 0.001, unit = "m"; a 5 mm lattice → scale = 0.005). depthpack applies scale/offset on decode_scaled but never interprets unit — it carries the label verbatim, so a survey-foot producer stores foot counts with unit = "ftUS" and no unit conversion happens anywhere in this crate.

§Feature flags

The crate is pure Rust by default — both encode and decode compile for wasm32-unknown-unknown unchanged (zstd via ruzstd).

  • zstd-c (optional) — swap the encoder’s entropy stage to the C zstd bindings. Measured on a real 7200×3600 depth map: ~2.6× faster encode and ~27% smaller output than the pure-Rust encoder (ruzstd’s Fastest compresses less densely than C zstd level 1), and it honours EncodeOptions::zstd_level. Recommended for native bulk pipelines; decoding always stays pure Rust either way.

§Example

let (w, h) = (64u32, 32u32);
// A smooth surface (millimetre counts) with a nodata hole.
let counts: Vec<u16> = (0..w * h)
    .map(|i| if i % 97 == 0 { 0 } else { 2500 + (i % w) as u16 })
    .collect();

// Millimetre lattice interpreted as metres.
let opts = depthpack::EncodeOptions { scale: 0.001, unit: "m".into(), ..Default::default() };
let blob = depthpack::encode(&counts, w, h, &opts).unwrap();

// Raw lattice roundtrips bit-exact…
let img = depthpack::decode(&blob).unwrap();
assert_eq!(img.values, counts);

// …and decode_scaled applies scale, NaN for nodata.
let scaled = depthpack::decode_scaled(&blob).unwrap();
assert_eq!(scaled.unit, "m");
assert!((scaled.values[1] - 2.501).abs() < 1e-6); // count 2501 · 0.001 m
assert!(scaled.values[0].is_nan()); // nodata

Structs§

DepthImage
A decoded raster: the raw integer lattice plus its physical mapping. values is row-major, 0 = nodata.
EncodeOptions
Options for encode.
Header
Parsed container header. Obtain with decode_header.
ScaledImage
A decoded raster in physical units: count · scale + offset, with NaN at nodata pixels. Returned by decode_scaled.

Enums§

Error
Errors returned by encode and the decode functions.

Constants§

HEADER_LEN
Fixed header length in bytes.
MAGIC
Magic bytes at the start of every blob.
MAX_PIXELS
Upper bound on width × height accepted by the decoder, so a malformed header cannot request an arbitrarily large allocation. 2²⁷ px comfortably covers 7200×3600 panoramas with a wide margin.
UNIT_LEN
Maximum length of the unit label in bytes.
VERSION
Container version this library reads and writes.

Functions§

decode
Decode a depthpack blob into a fresh DepthImage (raw lattice + physical mapping).
decode_header
Parse and validate the fixed header without decoding pixel data.
decode_into
Decode into a caller-provided lattice buffer of exactly width × height counts, avoiding the output allocation. Nodata pixels are written as 0.
decode_scaled
Decode a blob directly to physical values (count · scale + offset), with NaN at nodata pixels. depthpack applies the scale but never the unit — the returned ScaledImage::unit is the stored label.
decode_scaled_into
Decode physical values into a caller-provided f32 buffer of exactly width × height (NaN = nodata). Uses an internal u16 scratch for the lattice reconstruction, then applies scale/offset.
encode
Encode a row-major lattice of u16 counts (0 = nodata).