Skip to content

feat(hwdec,heic)!: create rawshift-hwdec; rebuild HEIC on gamut-heic; drop libheif-rs - #50

Merged
justin13888 merged 1 commit into
masterfrom
27-hwdec-heic-gamut
Jul 19, 2026
Merged

feat(hwdec,heic)!: create rawshift-hwdec; rebuild HEIC on gamut-heic; drop libheif-rs#50
justin13888 merged 1 commit into
masterfrom
27-hwdec-heic-gamut

Conversation

@justin13888

Copy link
Copy Markdown
Collaborator

Closes #27.

Stacked on #49; merge order #42#44#45#46#47#48#49 → this.

What is Delivered

rawshift-hwdec (new leaf crate)

  • Safe public API per the issue + docs/V1_DESIGN.md: HwCodec{Hevc,Av1}, HwBackend, CodecConfig<'a>{Hvcc,Av1c} + StillDecodeRequest, DecodedFrame (Nv12/P010/I420/I010, validated planes/strides/bit-depths at construction), HwStillDecoder, decoder()/backend()/available_codecs(), HwDecodeError#![deny(unsafe_op_in_unsafe_fn)], zero unsafe in this PR (backends are Hardware decode: VideoToolbox backend (macOS/iOS, HEVC + AV1) #28/Hardware decode: VAAPI backend (Linux, HEVC + AV1, dlopen) #29/Hardware decode: MediaCodec backend (Android, HEVC + AV1) #30; VAAPI is next).
  • Structural strictness: the codec is implied by the config variant — a mismatched codec/payload state cannot be constructed.
  • Verified feature boundaries, proven on this host: cargo check -p rawshift-hwdec --features videotoolbox fails with error: rawshift-hwdec: the 'videotoolbox' feature requires an Apple target…; the hw meta-flag build-script warns and compiles the stub on no-API targets (musl demonstrated); vaapi compiles on Linux as the stub.
  • Workspace/release-plz/facade wiring (hw/hw-* weak-dep features; publish order core → hwdec → image → rawshift).

HEIC on gamut-heic

  • Container/thumbnail/auxiliary (depth/gain-map/alpha URN classification)/EXIF/XMP/ICC/bit-depth enumeration fully backend-less — verified live against fixture HEICs and the rewired heic_inspect example.
  • Pixel decode routes through an adapter implementing gamut-heic's HevcDecoder (grid stitch, overlays, irot/imir/clap, alpha merge, YCbCr→RGB all owned by gamut — nothing duplicated). With no backend: new RawError::HwDecoderUnavailable{codec,reason} + public heic_hw_decode_available(). The full decode pipeline is exercised end-to-end in tests via a synthetic in-process decoder — the exact seam Hardware decode: VAAPI backend (Linux, HEVC + AV1, dlopen) #29 plugs into, so the VAAPI PR touches no HEIC code.
  • Deleted: libheif-rs, heic-decode-libheif, heic-vendored, codecs/heic.rs; CI drops the heic-vendored steps. DecodeOptions::HeicLibheifHeic; codec id heic/gamut.

Upstream notes (non-blocking here, gating #29's HDR story)

gamut-heic's RGBA presentation is 8-bit/BT.601-identity only — 10-bit HDR HEIC needs an upstream presentation surface (issue being filed); a raw-hvcC accessor upstream would delete rawshift's small round-trip-tested re-serialiser; two more cosmetic gaps noted in commit/report.

Fixture note

The Apple fixture tarball contains only the DNG — no real iPhone HEIC exists in the fixtures repo (worth adding). Fixture tests run against a locally generated metadata-rich HEIC (gitignored); synthetic in-memory containers keep all suites running in CI.

Verification Done

Run independently after implementation: cargo test --workspace 386/0 (incl. 8 rawshift-hwdec stub/validation tests); -p rawshift-image --features full 540/0 (7 heic_aux tests all RAN backend-less); --features serde 360/0; clippy workspace + full -D warnings 0+0; --no-default-features --features heic standalone clean; the compile_error! proof captured above; libheif absent from every manifest and the lockfile. lefthook green.

… drop libheif-rs

New leaf crate rawshift-hwdec holds the hardware still-decode boundary: safe
public API (HwCodec, HwBackend, CodecConfig/StillDecodeRequest, DecodedFrame
with validated planes, HwStillDecoder, decoder()/backend()/available_codecs(),
HwDecodeError), #[deny(unsafe_op_in_unsafe_fn)], zero unsafe in this change —
platform backends are follow-up issues (#29 VAAPI next). The codec is implied
by the config variant, so a mismatched codec/payload state is unrepresentable.
Feature boundaries are verified: videotoolbox/vaapi/mediacodec hard
compile_error! on foreign targets; the portable hw meta-flag selects the
native backend in build.rs and compiles a warning-emitting stub on no-API
targets per docs/SUPPORT.md. Wired into the workspace, release-plz publish
order (core -> hwdec -> image -> rawshift), and facade hw/hw-* features.

HEIC is rebuilt on gamut-heic: container, thumbnail, auxiliary (depth/gain
map/alpha URN classification), EXIF/XMP/ICC, and bit-depth enumeration all
work with no hardware backend present. Pixel decode routes through a
rawshift-hwdec adapter implementing gamut-heic's HevcDecoder (hvcC
re-serialisation round-trip tested; NV12/P010/I420/I010 plane lift;
grid/overlay/rotation/mirror/crop/alpha and YCbCr->RGB owned by gamut, not
duplicated); with no backend it returns the new
RawError::HwDecoderUnavailable, and heic_hw_decode_available() reports the
state. The full decode pipeline is exercised end-to-end in tests by a
synthetic in-process decoder — the exact seam the VAAPI backend plugs into.

libheif-rs, heic-decode-libheif, heic-vendored, and codecs/heic.rs are
deleted; heic-decode = dep:gamut-heic (+gamut-isobmff for colr/ICC).
DecodeOptions::HeicLibheif -> Heic; codec id heic/gamut. CI drops the
heic-vendored feature and libheif comments.

Upstream notes: gamut-heic's RGBA presentation is 8-bit BT.601/identity only
— 10-bit HDR HEIC needs an upstream presentation surface before #29 delivers
HDR end-to-end (issue to follow); a raw hvcC bytes accessor upstream would
delete rawshift's re-serialiser.

BREAKING CHANGE: libheif backend and its features/config are gone; HEIC pixel
decode requires a hardware backend (none ships until #29) and returns
HwDecoderUnavailable until then; container/metadata/aux paths are unaffected.
Base automatically changed from 26-migrate-avif-encode-gamut to master July 19, 2026 01:41
@justin13888
justin13888 merged commit 742cc00 into master Jul 19, 2026
@justin13888
justin13888 deleted the 27-hwdec-heic-gamut branch July 19, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create rawshift-hwdec (HEVC+AV1); HEIC on gamut-heic; drop libheif-rs

1 participant