gamut-isobmff 1.0.0

ISO Base Media File Format (ISOBMFF) still-image container: the typed box tree, with read/write, shared by the AVIF and HEIC codecs.
Documentation

gamut-isobmff

gamut-isobmff is a pure-Rust implementation of the ISO Base Media File Format (ISOBMFF) still-image container core: the ftyp brands, the meta box of image items with their properties and payloads, and the offset-driven read/write spine. It models structure only — the coded bitstream (the av1C/hvcC record and the sample data) stays opaque.

Goals

Part of the gamut workspace, this crate exists because the ISOBMFF/HEIF container is shared by two otherwise-separate codecs:

  • AVIF (gamut-avif) — AV1 still images: item type av01, codec config av1C.
  • HEIC (gamut-heic) — HEVC still images: item type hvc1, codec config hvcC.

Factoring the container out keeps the two from duplicating the box tree and the fiddly, security-sensitive iloc offset machinery. It is:

  • Codec-agnostic. The codec configuration is carried as opaque bytes ([PropertyKind::CodecConfiguration]), so the same write/read serve av01/av1C and hvc1/hvcC with no container changes.
  • Memory-safe on hostile input. #![forbid(unsafe_code)] — ISOBMFF is offset-driven, a classic parser-exploit surface (truncation, overruns, out-of-range indices), so every read is bounds-checked.
  • Dependency-light. Builds only on gamut-core.

Usage

write serialises an [IsoBmffImage] (its ftyp brands, the pitm primary item, and the image items) into a complete ftyp + meta + mdat file; read parses one back. Each [Item] carries its type, name, properties, and payload; the writer derives the iloc offsets and the shared ipco/ipma so the two are inverse for any file this crate writes.

use gamut_isobmff::{IsoBmffImage, Item, Property, PropertyKind, read, write};

let img = IsoBmffImage {
    major_brand: *b"avif",
    minor_version: 0,
    compatible_brands: vec![*b"avif", *b"mif1", *b"miaf"],
    primary_item_id: 1,
    items: vec![Item {
        id: 1,
        item_type: *b"av01",
        name: String::new(),
        properties: vec![Property {
            essential: false,
            kind: PropertyKind::ImageSpatialExtents { width: 64, height: 64 },
        }],
        payload: vec![/* the coded bitstream, opaque to this crate */],
    }],
};
let bytes = write(&img);
assert_eq!(read(&bytes).unwrap(), img);

See gamut-avif for the full encode path that drives this crate (it builds the av1C record and the AVIF brand set, then calls write).

Status

Models the HEIF still-image box set: ftyp, meta (hdlr/pitm/iloc v0/iinf+infe v2/iprp), the ispe/pixi/colr/irot/imir properties, opaque codec configuration, and mdat. Unrecognised property boxes round-trip verbatim. Image sequences/tracks, iloc v1/v2, multi-extent items, idat/grid/alpha, and ICC colr are out of scope — see STATUS.md.

Box byte layouts follow ISO/IEC 14496-12 (ISOBMFF) and ISO/IEC 23008-12 (HEIF) — paywalled, so cross-checked against the public AVIF box table and a vendored libavif/dav1d differential oracle (via gamut-avif). See references/isobmff.

License

Licensed under either of MIT or Apache-2.0 at your option.