Releases: mindeng/nom-exif
v3.6.0
Changed
- Split
tokiofeature intotokioandtokio-fs— thetokio
feature now only pulls intokio/io-util, enabling the async
streaming API (AsyncMediaSource::seekable/unseekable/from_memory,
MediaParser::parse_*_async) onwasm32-unknown-unknown. Path-based
helpers (read_exif_async,read_track_async,read_metadata_async,
AsyncMediaSource::open) moved to the newtokio-fsfeature (implies
tokio). Users who previously usedfeatures = ["tokio"]with
read_exif_asyncetc. should switch tofeatures = ["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
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
Added
-
CameraSerialNumberEXIF tag (0xa431). Standard EXIF tag for the
camera body serial number. #56 -
LensSerialNumberEXIF 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
rexiftool v0.2.3 — pick up nom-exif 3.5.0
v3.4.2
Fixed
- Streaming PNG parsing for files with non-trivial IDAT — every
real-world PNG (i.e. anything beyond a stripped-down test fixture)
surfacedmalformed iso-bmff box: PNG: bad signaturefrom
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 exactlycursor + remaining
bytes — semantically the caller should advance the parser's
logical position bycursor + total, not just past the buffer's
end — leaving the parser stranded mid-IDAT; (b) on the resumed call
extract_chunksalways re-validatedbuf[..8]against the PNG
signature, but the resumed buffer started mid-stream and the check
failed. Fixed both: skip request is nowcursor + total, and a new
ParsingState::PngPastSignaturetells the resumed call to skip the
signature check. In-memory mode (from_memory) was unaffected
because the full file is buffered at once andClearAndSkipnever
fires. Fixes #55.
Fixed (behaviour)
Error::Malformed.kindcorrectly identifies the failing
structural unit. Previously every parse failure that flowed
throughFrom<ParsedError> for Erroror
From<nom::Err<...>> for Errorwas hard-coded as
MalformedKind::IsoBmffBox/MalformedKind::TiffHeader
respectively — misleading for PNG / JPEG / EBML inputs. The
MalformedKindis now threaded throughParsingError::Failed,
ParsedError::Failed, andLoopAction::Failed, and surfaced
unchanged at theErrorboundary. Downstream code that
(incorrectly) matched onkind == IsoBmffBoxto catch any
parse failure will need updating; conformant code that uses a
_ =>arm (required by#[non_exhaustive]) is unaffected.
Added
MalformedKind::PngChunkvariant.MalformedKindis
#[non_exhaustive], so adding a variant is non-breaking.
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.4.2
rexiftool-v0.2.2
release(rexiftool): v0.2.2 — pick up nom-exif 3.4.2 PNG streaming fix
v3.4.1
Fixed
- GPS sub-IFD parsing for Sony A7C2 HIF (and any camera that emits
GPSVersionID first) —IfdIter::parse_tag_entryshort-circuited
ontag == 0as 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
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
Changed (BREAKING for serde feature)
- Structured
SerializeforEntryValue. The previous impl
stringified everything viaDisplay, which meant numeric arrays
andUndefinedbyte 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 existingRational<T>Serializederive).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)
Displayno longer truncates arrays. The 8-element ellipsis cap
onUndefined,U8Array,U16Array,U32Array, and the 3-element
cap onURationalArray/IRationalArrayare gone.to_string()
now emits every element. Callers that need a length cap should
impose it at their layer (rexiftool already does this).EntryValue::Undefinedrendering 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
with0x(e.g.ComponentsConfiguration→0x01020300). The
Undefined[0xNN, 0xNN, ...]wrapper is gone.U8Array/
U16Array/U32Arraykeep theirName[...]form.
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.4.0
v3.3.0 — PNG support + source-input unification
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_metadataandparse_image_metadata_asyncMediaSource::from_memory/AsyncMediaSource::from_memory- New public types:
ImageMetadata<E: ExifRepr = Exif>,ImageFormatMetadata(#[non_exhaustive]),PngTextChunks,ExifReprsealed trait examples/rexiftoolprints PNGtEXtchunks under a-- Format Metadata --section (and_formatJSON key); add--no-formatto suppress
Deprecated
MediaSource::<()>::from_bytes— useMediaSource::from_memoryMediaParser::parse_exif_from_bytes/parse_track_from_bytesread_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
iTXtandzTXtchunks (would require aflate2dependency foriTXt's optional zlib-compressed variant). Their addition is non-breaking —PngTextChunksis shaped to extend.
Notes
- Top-level
read_image_metadatahelpers are deferred to v4 alongside the plannedMetadataenum redesign (a singleread_metadatareturningMetadata::Image(ImageMetadata)). Mixed-content batch users on v3.3 still match onMediaSource::kind()to dispatch betweenparse_image_metadataandparse_track.
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.3.0 (publishing after CI passes)