gamut-ifd 0.1.1

TIFF Image File Directory (IFD) container core — byte order, field types, and IFD read/write — shared by the TIFF codec and EXIF metadata.
Documentation
  • Coverage
  • 100%
    75 out of 75 items documented1 out of 37 items with examples
  • Size
  • Source code size: 62.99 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 926.45 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 10s Average build duration of successful builds.
  • all releases: 9s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • justin13888/gamut
    2 0 32
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • justin13888

gamut-ifd

gamut-ifd is a pure-Rust implementation of the TIFF Image File Directory (IFD) container core: the byte-order header, the field-type / value model, the IFD chain, and the offset-driven read/write spine. It models structure only — no pixels, compression, or photometry.

Goals

Part of the gamut workspace, this crate exists because the TIFF/IFD structure is shared by two otherwise-separate efforts:

  • EXIF (gamut-exif, issue #34) — an EXIF blob is an Exif\0\0 marker followed by a TIFF stream; its 0th/1st IFDs and Exif/GPS/Interop sub-IFDs are exactly IFD chains.
  • TIFF (gamut-tiff, issue #107) — the TIFF image codec, whose container is its IFD structure.

Factoring the IFD core out keeps the two from duplicating the fiddly, security-sensitive offset machinery. It is:

  • Memory-safe on hostile input. #![forbid(unsafe_code)] — IFDs are offset-driven, a classic parser-exploit surface (offset loops, truncation, overlapping extents).
  • Endianness-honest. TIFF carries its own byte order (II/MM); the [ByteOrder] is threaded through every access rather than fixed at compile time.
  • Dependency-light. Builds only on gamut-core.

The public types deliberately mirror gamut-tiff's structural types: the codec was migrated onto this crate as a near-zero-diff refactor (issue #107), and now consumes it instead of an inlined copy.

Usage

read / read_header parse a stream into a [TiffFile] (ByteOrder + Variant + a Vec<Ifd>); write serialises one back, handling the two-pass offset layout. Each Ifd is a tag-sorted set of Fields, each holding a typed [Value]; FieldType carries the on-disk type codes.

use gamut_ifd::{ByteOrder, Ifd, TiffFile, Value, Variant, read, write};

let mut ifd = Ifd::new();
ifd.set(256, Value::Short(vec![640])); // ImageWidth
ifd.set(257, Value::Short(vec![480])); // ImageLength
let file = TiffFile { order: ByteOrder::LittleEndian, variant: Variant::Classic, ifds: vec![ifd] };
let bytes = write(&file);
assert_eq!(read(&bytes).unwrap(), file);

Tag numbers are passed literally — tag semantics live in the consuming codec (e.g. gamut-tiff's tags module), not in this structural core.

BigTIFF

The bigtiff cargo feature adds BigTIFF (references/tiff/bigtiff.html): the Variant::Big container with 64-bit offsets/counts and the Long8 / SLong8 / Ifd8 field types. It is additive and off by default — classic-only consumers (EXIF) stay lean; gamut-tiff enables it.

Status

Structural core implemented (issue #107). The EXIF-specific layers (sub-IFD traversal, fuzz corpus) remain under issue #34. See STATUS.md.

License

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