lightcraft/crates/heif
Walter Boring 853ada7754 LR-IMP-FORMATS: HEIC/HEIF decode behind the optional `heif` feature
New crate `lightcraft-heif` (a port of PhotoCraft's photocraft-heif): a thin,
panic-guarded wrapper around heic-rs (pure Rust, pinned =0.1.1) - 8/10-bit,
alpha, grid tiles, container irot/imir/clap, ICC/EXIF/XMP. `lightcraft-codecs`
decodes HEIF behind its non-default `heif` feature (HEVC patents are the
distributor's call, the same policy as PhotoCraft); the apps forward it. HEIC
files stay recognised without the feature: opening one is a clear
"isn't included in this build" error. Fuzz-found heic-rs panics arrive as
regression fixtures (inline bytes, no media committed).

Verified end-to-end on real iPhone HEICs (lightcraft-cli render, rotation and
metadata correct). Note for reviewers: measured here, the engine currently
ignores the decoded image's source-space matrix on export for ANY format (a
true Display-P3 PNG round-trips unchanged); the ICC and space are carried for
all codecs, so this inherits - and does not worsen - existing behaviour.

Co-Authored-By: opencode <noreply@opencode.ai>
2026-10-08 12:45:33 -04:00
..
src LR-IMP-FORMATS: HEIC/HEIF decode behind the optional `heif` feature 2026-10-08 12:45:33 -04:00
Cargo.toml LR-IMP-FORMATS: HEIC/HEIF decode behind the optional `heif` feature 2026-10-08 12:45:33 -04:00
README.md LR-IMP-FORMATS: HEIC/HEIF decode behind the optional `heif` feature 2026-10-08 12:45:33 -04:00

README.md

lightcraft-heif

The optional HEIF / HEIC decoder of LightCraft: iPhone and Mac photos. A thin, panic-guarded wrapper around heic-rs, a pure-Rust HEVC still-picture decoder (no unsafe, MIT OR Apache-2.0): single pictures and grid-tiled photos, 8- and 10-bit (10-bit decodes to 16-bit), alpha auxiliary images, the container's rotation/mirror/crop, ICC, EXIF and XMP. Read-only: writing would need an HEVC encoder.

let info = lightcraft_heif::probe(&bytes)?;           // size, depth, alpha: check limits first
let img = lightcraft_heif::decode(&bytes, &lightcraft_heif::Options::default())?;
// img.width, img.height, img.has_alpha, img.sixteen_bit, img.data (RGB/RGBA), img.icc, img.exif, img.xmp

Errors are Error::Unsupported (image sequences, overlays, …), Error::Limit or Error::Malformed. It never panics: every call into heic-rs runs under catch_unwind, and a panic inside it (PhotoCraft's fuzzing found two in 0.1.1) becomes Error::Malformed. The crate is a port of PhotoCraft's photocraft-heif — the sibling apps deliberately share one decoder, one pin and one set of regression fixtures.

Why it is a separate, optional crate

  • A young decoder. heic-rs is new and has a single maintainer. It is pinned exactly (=0.1.1); moving the pin is a reviewed change (re-run the crate tests and cargo test -p lightcraft-codecs --features heif).
  • HEVC patents are a distributor's call. HEVC is patent-encumbered in some jurisdictions, so whether a build includes an HEVC decoder is a build-time choice. lightcraft-codecs uses this crate only behind its non-default heif feature; the apps forward it (cargo build -p lightcraft --features heif). Without it, HEIC files are still recognised and opening one is a clear "HEIC/HEIF support isn't included in this build" error — the same policy as PhotoCraft.

The crate depends on no other LightCraft crate; codecs → heif is the only edge between them.