Skip to content

Releases: mindeng/nom-exif

v3.6.0

28 May 14:25
a65033a

Choose a tag to compare

Changed

  • Split tokio feature into tokio and tokio-fs — the tokio
    feature now only pulls in tokio/io-util, enabling the async
    streaming API (AsyncMediaSource::seekable/unseekable/from_memory,
    MediaParser::parse_*_async) on wasm32-unknown-unknown. Path-based
    helpers (read_exif_async, read_track_async, read_metadata_async,
    AsyncMediaSource::open) moved to the new tokio-fs feature (implies
    tokio). Users who previously used features = ["tokio"] with
    read_exif_async etc. should switch to features = ["tokio-fs"].
    #53

Fixed

  • Slice coercion in MotionPhoto attribute comparison — comparing
    extract_attr_value() against byte-string literals now uses explicit
    &b"..."[..] coercion, fixing a compile error when a crate like rkyv
    is present in the dependency graph. #58

Full changelog: CHANGELOG.md · crates.io: nom-exif 3.6.0

v3.5.1

28 May 14:10
6150bcb

Choose a tag to compare

Fixed

  • Slice coercion in MotionPhoto attribute comparison — comparing
    extract_attr_value() against byte-string literals now uses explicit
    &b"..."[..] coercion, fixing a compile error when a crate like rkyv
    is present in the dependency graph. #58

Full changelog: CHANGELOG.md · crates.io: nom-exif 3.5.1

v3.5.0

23 May 10:40
acb56d1

Choose a tag to compare

Added

  • CameraSerialNumber EXIF tag (0xa431). Standard EXIF tag for the
    camera body serial number. #56

  • LensSerialNumber EXIF tag (0xa435). Standard EXIF tag for the
    lens serial number. #57


Full changelog: CHANGELOG.md · crates.io: nom-exif 3.5.0

rexiftool-v0.2.3

23 May 10:35
9bd5ac7

Choose a tag to compare

rexiftool v0.2.3 — pick up nom-exif 3.5.0

v3.4.2

20 May 08:08
22f41ab

Choose a tag to compare

Fixed

  • Streaming PNG parsing for files with non-trivial IDAT — every
    real-world PNG (i.e. anything beyond a stripped-down test fixture)
    surfaced malformed iso-bmff box: PNG: bad signature from
    parse_exif / parse_image_metadata. Root cause was a two-part
    bug in the chunk walker: (a) ClearAndSkip(total - remaining)
    under-requested the skip distance by exactly cursor + remaining
    bytes — semantically the caller should advance the parser's
    logical position by cursor + total, not just past the buffer's
    end — leaving the parser stranded mid-IDAT; (b) on the resumed call
    extract_chunks always re-validated buf[..8] against the PNG
    signature, but the resumed buffer started mid-stream and the check
    failed. Fixed both: skip request is now cursor + total, and a new
    ParsingState::PngPastSignature tells the resumed call to skip the
    signature check. In-memory mode (from_memory) was unaffected
    because the full file is buffered at once and ClearAndSkip never
    fires. Fixes #55.

Fixed (behaviour)

  • Error::Malformed.kind correctly identifies the failing
    structural unit.
    Previously every parse failure that flowed
    through From<ParsedError> for Error or
    From<nom::Err<...>> for Error was hard-coded as
    MalformedKind::IsoBmffBox / MalformedKind::TiffHeader
    respectively — misleading for PNG / JPEG / EBML inputs. The
    MalformedKind is now threaded through ParsingError::Failed,
    ParsedError::Failed, and LoopAction::Failed, and surfaced
    unchanged at the Error boundary. Downstream code that
    (incorrectly) matched on kind == IsoBmffBox to catch any
    parse failure will need updating; conformant code that uses a
    _ => arm (required by #[non_exhaustive]) is unaffected.

Added

  • MalformedKind::PngChunk variant. MalformedKind is
    #[non_exhaustive], so adding a variant is non-breaking.

Full changelog: CHANGELOG.md · crates.io: nom-exif 3.4.2

rexiftool-v0.2.2

20 May 07:58
383d0f6

Choose a tag to compare

release(rexiftool): v0.2.2 — pick up nom-exif 3.4.2 PNG streaming fix

v3.4.1

12 May 08:29

Choose a tag to compare

Fixed

  • GPS sub-IFD parsing for Sony A7C2 HIF (and any camera that emits
    GPSVersionID first)
    IfdIter::parse_tag_entry short-circuited
    on tag == 0 as a defensive guard against zero-padded malformed
    IFDs. But tag 0 is also the legitimate GPSVersionID — the
    spec-defined first entry of the GPS sub-IFD. Aborting iteration
    there caused the whole sub-IFD to be dropped, silently losing every
    GPS field. Now gated on !self.is_gps_subifd() so the defense
    survives in non-GPS contexts while GPSVersionID parses normally.
    Fixes #50.

Full changelog: CHANGELOG.md · crates.io: nom-exif 3.4.1

rexiftool-v0.2.1

12 May 08:40

Choose a tag to compare

release(rexiftool): v0.2.1 — pick up nom-exif 3.4.1 GPS sub-IFD fix

Bumps the minimum nom-exif requirement from "3.4" to "3.4.1" so
`cargo install rexiftool --locked` and the pre-built GitHub Releases
binaries actually carry the Sony A7C2 HIF GPS fix (issue #50). Default
`cargo install rexiftool` would already pull 3.4.1 via the caret
range, but locked / binary installs were still serving 3.4.0.

Workflow tweak: pin `make_latest: "false"` on the rexiftool release
upload step so its tag never competes with the nom-exif lib tag for
the GitHub "Latest release" badge. (Today rexiftool-v0.2.0 wasn't
labelled Latest only because v3.4.0 outranks 0.2.0 in semver; future
rexiftool 1.x could accidentally promote itself.)

v3.4.0

10 May 15:56
20f2305

Choose a tag to compare

Changed (BREAKING for serde feature)

  • Structured Serialize for EntryValue. The previous impl
    stringified everything via Display, which meant numeric arrays
    and Undefined byte blobs were truncated with ... after 8 / 9
    elements — JSON consumers silently lost data, and rationals came
    out as opaque strings like "175/100 (1.7500)". The new shape:
    • Scalar numerics → JSON numbers.
    • Text / DateTime / NaiveDateTime → strings (formats
      unchanged).
    • URational / IRational{"numerator", "denominator"}
      objects (uses the existing Rational<T> Serialize derive).
    • URationalArray / IRationalArray → JSON arrays of those
      objects, never truncated.
    • Undefined(Vec<u8>) → continuous lowercase hex string
      (e.g. "30323230"), never truncated.
    • U8Array / U16Array / U32Array → JSON arrays of numbers.

Changed (BREAKING for Display / to_string)

  • Display no longer truncates arrays. The 8-element ellipsis cap
    on Undefined, U8Array, U16Array, U32Array, and the 3-element
    cap on URationalArray / IRationalArray are gone. to_string()
    now emits every element. Callers that need a length cap should
    impose it at their layer (rexiftool already does this).
  • EntryValue::Undefined rendering redesigned. When all bytes are
    printable ASCII (0x20..=0x7E), it now displays as a quoted string
    (e.g. ExifVersion"0220", GPSProcessingMethod"CELLID").
    Otherwise it displays as a continuous lowercase hex string prefixed
    with 0x (e.g. ComponentsConfiguration0x01020300). The
    Undefined[0xNN, 0xNN, ...] wrapper is gone. U8Array /
    U16Array / U32Array keep their Name[...] form.

Full changelog: CHANGELOG.md · crates.io: nom-exif 3.4.0

v3.3.0 — PNG support + source-input unification

10 May 13:14
9444ead

Choose a tag to compare

Highlights

PNG support (#18). read_exif("foo.png") and the rest of the public API now work for PNG files. Both modern PNGs (standard eXIf chunk) and legacy ImageMagick / Photoshop output (hex-encoded EXIF in Raw profile type exif / Raw profile type APP1 tEXt chunks) are covered. Legacy hex-encoded EXIF is transparently decoded and merged so Exif::get(...) returns the same result either way.

New parse_image_metadata entry point. Returns ImageMetadata { exif, format }, which lets callers see PNG tEXt key/value pairs alongside EXIF — the first non-EXIF format-specific metadata surfaced by the library. Single method handles file / stream / memory inputs (no _from_bytes sibling). Async variant under the tokio feature.

use nom_exif::{MediaParser, MediaSource, ImageMetadata, ImageFormatMetadata};

let mut parser = MediaParser::new();
let ms = MediaSource::file_path(\"photo.png\")?;
let meta: ImageMetadata = parser.parse_image_metadata(ms)?;

if let Some(ImageFormatMetadata::Png(text)) = meta.format {
    for (k, v) in text.iter() {
        println!(\"{k}: {v}\");
    }
}

Source-input unification. MediaSource::from_memory (and AsyncMediaSource::from_memory under tokio) replace the <()>::from_bytes / parse_*_from_bytes zoo. All three parse_* methods now accept memory-mode sources directly with the same zero-copy bytes::Bytes story. Old methods remain as #[deprecated] shims for the v3.x line; removal is scheduled for v4.

Added

  • MediaParser::parse_image_metadata and parse_image_metadata_async
  • MediaSource::from_memory / AsyncMediaSource::from_memory
  • New public types: ImageMetadata<E: ExifRepr = Exif>, ImageFormatMetadata (#[non_exhaustive]), PngTextChunks, ExifRepr sealed trait
  • examples/rexiftool prints PNG tEXt chunks under a -- Format Metadata -- section (and _format JSON key); add --no-format to suppress

Deprecated

  • MediaSource::<()>::from_bytes — use MediaSource::from_memory
  • MediaParser::parse_exif_from_bytes / parse_track_from_bytes
  • read_exif_from_bytes, read_exif_iter_from_bytes, read_track_from_bytes, read_metadata_from_bytes

All deprecated symbols still compile and pass their original tests in v3.x.

Not yet supported

  • PNG iTXt and zTXt chunks (would require a flate2 dependency for iTXt's optional zlib-compressed variant). Their addition is non-breaking — PngTextChunks is shaped to extend.

Notes

  • Top-level read_image_metadata helpers are deferred to v4 alongside the planned Metadata enum redesign (a single read_metadata returning Metadata::Image(ImageMetadata)). Mixed-content batch users on v3.3 still match on MediaSource::kind() to dispatch between parse_image_metadata and parse_track.

Full changelog: CHANGELOG.md · crates.io: nom-exif 3.3.0 (publishing after CI passes)