v3.8.0
-
IFD namespaces — entries now report which IFD namespace they came from, via the new
IfdKindenum (Tiff/Exif/Gps/Interop). This is orthogonal toIfdIndex, which continues to identify a position in the IFD chain: a GPS sub-IFD hanging off IFD0 isIfdIndex::MAIN+IfdKind::Gps.ExifIterEntry::ifd_kind()on the lazy path.Exif::entries()yielding the newExifEntryRefon the eager path, plusExif::get_by_code_in(ifd, kind, code).TagOrCode::from_code_in(kind, code)andExifTag::namespace()for namespace-aware tag resolution.- New
ExifTagvariants that were previously unnameable because their code was already taken:ProcessingSoftware,InteropIndex,InteropVersion. #68
-
Interoperability sub-IFD is now parsed —
InteropOffset(0xa005) is followed likeExifOffsetandGPSInfo, soInteropIndex/InteropVersionentries are exposed instead of silently skipped. Files carrying an Interop IFD yield two extra entries.
-
Entries were silently dropped when two IFDs shared a tag code — sub-IFDs inherit their parent's
IfdIndex, and the duplicate filter keyed on(ifd_index, code), so a GPS tag whose code also appeared in IFD0 was discarded as a duplicate. A file with0x000bin both IFD0 (ProcessingSoftware) and the GPS IFD (GPSDOP) lost the GPS value entirely. The filter andExif's internal storage are now keyed on(ifd_index, ifd_kind, code). #68 -
Tags were labelled with another namespace's name — codes were resolved against a single flat table, so IFD0's
0x000b(ProcessingSoftware) was reported asGPSDOP. Resolution now happens within the entry's namespace. #68 -
PNG metadata before a large chunk was discarded on streaming sources — metadata found before a chunk larger than the parser buffer was lost when parsing resumed after
ClearAndSkip, so aneXIfchunk preceding a largeIDATreturnedExifNotFoundfor streaming sources even though the same bytes parsed fine from memory. The PNG cursor, EXIF source,tEXtentries and source priority are now carried across retries; zero-copyeXIfranges are preserved while the buffer grows and materialized only before destructive skips, with retained copies bounded at 64 MiB. Thanks @nkgupta-dev. #67
Exif::iter()/ExifEntry—ExifEntryexposespubfields, so it cannot gain anifd_kindaccessor without a breaking change. UseExif::entries()/ExifEntryRefinstead.iter()keeps working and now resolves tag names per namespace, but still cannot tell a GPS entry from an IFD0 entry that shares its code.
ExifTag::from_codeandFrom<u16> for TagOrCodeare unchanged and still resolve contested codes the way they always have (GPS wins).size_of::<ExifTag>()grows from 2 to 4 bytes: namespaces are encoded in the high 16 bits of the discriminant so thatcode()and the pre-existingExifTag::X as u16idiom keep returning the real tag code. Note that clippy'scast_enum_truncationnow fires onas u16for the three namespaced variants — prefer.code().
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.8.0
v3.7.0
- WebP (RIFF/WEBP) image support — detects RIFF/WEBP files and extracts EXIF/GPS from the
EXIFchunk via the unifiedparse_exif/read_exif(sync + async) APIs. The chunk walker skips the image bitstream to reach the trailingEXIFchunk and is bounded by the RIFF size field. Scope is EXIF-only (no XMP). #61
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.7.0
v2.8.1
- ISO 6709 track GPS: fix seconds scaling and recover CRS-less altitude (#66) — for QuickTime/MP4
©xyz/com.apple.quicktime.location.ISO6709locations:- The fraction of a minute was stored unscaled in the seconds slot, a positional error of up to a full minute's worth of scaling (~350 m). It is now multiplied by 60 before storing hundredths, so
+47.7199…decomposes to47° 43' 11.64"instead of47° 43' 0.19". - Apple's default
+lat+lon+alt/form has noCRSsuffix, andiso6709parseonly decodes altitude when aCRStag follows, so the altitude was dropped. It is now recovered, e.g.+522.171→522.171 m.
- The fraction of a minute was stored unscaled in the seconds slot, a positional error of up to a full minute's worth of scaling (~350 m). It is now multiplied by 60 before storing hundredths, so
This is a maintenance backport for users pinned to the 2.8 line. The same fix ships in 3.6.3.
crates.io: nom-exif 2.8.1
v3.6.3
-
Read 4-octet float Matroska/WebM
Durationand stop the cursor desync — aDurationelement stored as a 4-octet (f32) float was decoded from a zero-initialized buffer, so it always came back as0and, because the cursor was never advanced, every element followingDurationinsideInfowas misread (either losing the duration or failing the whole parse). The 4-octet branch now reads the bytes and advances the cursor, matching the 8-octet form. #65 -
Recover altitude from CRS-less ISO 6709 track GPS — Apple's default QuickTime location string (
+lat+lon+alt/, noCRSsuffix) lost its altitude becauseiso6709parseonly decodes the altitude field when aCRStag follows.GPSInfo::from_strnow parses the trailing signed altitude field itself, so+47.7199-117.4931+522.171/decodes to522.171 minstead of dropping it. #66
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.6.3
v3.6.2
- Avoid overflow panic on malformed HEIF
ilocextent offsets — a crafted or corruptilocbox could produce extent/base offsets that overflow when summed, panicking in debug builds (and wrapping in release). Offset arithmetic iniloc/metanow uses checked addition and returnsNonefor out-of-range extents instead of panicking, so Exif extraction fails gracefully on such files. #64
Full changelog: CHANGELOG.md · crates.io: nom-exif 3.6.2
nom-exif v3.6.1
Patch release for nom-exif.
v3.6.0
- Split
tokiofeature intotokioandtokio-fs— thetokiofeature 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 (impliestokio). Users who previously usedfeatures = ["tokio"]withread_exif_asyncetc. should switch tofeatures = ["tokio-fs"]. #53
- 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
- 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