Skip to content

gamut-jxl: JxlDecoder::metadata loses located Exif/XMP boxes when the codestream is at fault #627

Description

@justin13888

What happens today

JxlDecoder::metadata does two independent things and reports one result:

// crates/gamut-jxl/src/decoder.rs
let (exif, xmp) = match JxlFraming::detect(data) {
    JxlFraming::IsoBmff => container_metadata_boxes(data)?,
    ...
};
let icc = crate::jxlrs::embedded_icc_profile(data)?;   // <- parses the codestream
Ok(JxlMetadata { exif, xmp, icc })

The first half is this crate's own walk of the container's top-level box sequence. The second hands
the whole stream to the jxl-rs decoder to read the codestream's colour encoding. A fault in the
codestream — truncated before the colour metadata, an unsupported feature, anything jxl-rs
rejects — therefore fails the entire call, and the Exif and xml boxes that were already located
successfully are discarded with it.

That is the case a metadata reader exists for: recovering what a damaged file still carries. A
caller who wants the EXIF out of a file whose pixels will not decode has no way to ask for it, even
though this crate located it before consulting the codestream at all.

The fork

  • Keep it strict (today) — metadata() is all-or-nothing, and a codestream fault is a fault.
    Simple, and the caller can fall back to nothing.
  • Report per carrierJxlMetadata gains a typed "this carrier could not be read" state, so a
    located box survives a codestream the decoder refuses. This is a shape question the facade may
    want to answer once for every format rather than per crate (gamut-heic has the same split
    between a located item and a payload it cannot parse).
  • Split the API — a box-only reader that never touches the codestream, and today's method as
    the composed convenience.

The third is the cheapest and the least expressive; the second is the one that generalises. Both
change a public signature, which is why neither is being taken at the close of #509.

Evidence

Refs #420.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions