fix: preserve the full EXIF block in exports instead of the sidecar subset (#1165)#1373
Open
Serraniel wants to merge 3 commits into
Open
fix: preserve the full EXIF block in exports instead of the sidecar subset (#1165)#1373Serraniel wants to merge 3 commits into
Serraniel wants to merge 3 commits into
Conversation
…CyberTimon#1165) Once an image has been opened, its .rrdata sidecar exists and write_image_with_metadata reconstructed the export EXIF from the sidecar's display-formatted subset, silently dropping most tags (GPS, MakerNote, OffsetTime*, serials, ...). Copy the complete EXIF block from non-RAW source files instead, keep the sidecar as the source of truth for the panel-editable fields, strip the whole GPS IFD when requested, and stamp the real export dimensions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
little_exif converts simple-format WebP (both the lossy VP8 output of the export pipeline and lossless VP8L) to the extended format and attaches an EXIF chunk, so WebP only needed a file-type mapping. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
|
Thanks for the PR! |
Requested by the maintainer before review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
I think this feature is important for JPEGXL and other formats, since currently they do not support metadata in the file... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Exporting with Save with Metadata enabled silently drops most of the EXIF data. From a Fujifilm X-T50 JPEG with 78 EXIF tags, only 15 survive the export: the whole GPS block,
DateTime/OffsetTime*/SubSecTime*,Flash,ExposureBiasValue,ApertureValue,ShutterSpeedValue, the MakerNote, body/lens serial numbers,LensSpecification, the Interop IFD and more are gone.Root cause:
write_image_with_metadatasources tags from three branches (.rrdatasidecar → kamadak-exif → rawler). Opening an image triggerspersist_exif_if_missing, which creates the sidecar — so from then on the sidecar branch always wins. The sidecar only stores a display-formatted subset of the tags (e.g."ApertureValue": "7.4 EV", MakerNote as a truncated hex dump), so it cannot reconstruct the original EXIF, and the kamadak/rawler branches (including their GPS handling) are never reached.Fix: for non-RAW sources, copy the complete EXIF block (IFD0 + Exif/GPS/Interop sub-IFDs, including MakerNote and unknown tags) from the source file via
little_exif, instead of reconstructing a subset:Artist,Copyright,ImageDescription,UserComment) — user edits override the source values, and a cleared field stays cleared in the export.strip_gps=truestill removes the entire GPS IFD (allGPS*tags, not just lat/lon/alt).Orientationis reset to 1 as before (rotation is baked into the exported pixels), andExifImageWidth/ExifImageHeightare now set to the actual export dimensions instead of carrying the stale source values.little_exifcannot parse RAW containers).Fixes #1165 (the GPS part of it as a side effect, see below). The closed duplicates #503, #427 and #401 report the same symptom.
Relationship to other PRs:
exif_processing.rs. The regression tests here follow the pattern introduced in fix gps metadata being stripped from exports (#1165) #1207.OffsetTime*to JPEG exports; the export half of that PR is covered by the full-block copy for non-RAW sources (itsget_creation_date_from_pathtimezone fix is independent and still valuable).Type of Change
Changes Made
exif_processing::write_image_with_metadata: copy the full EXIF block from non-RAW source files (newcopy_full_exif_from_source), skipping the GPS IFD whenstrip_gpsis set and skipping IFD1; fall back to the previous sidecar/kamadak/rawler branches when the source has no parseable EXIF or is a RAW file.apply_sidecar_field_overrides: the four panel-editable fields are applied from the sidecar on top of the copied block.ExifImageWidth/ExifImageHeightto the actual dimensions of the exported image.strip_gps=true, sidecar edits overriding/clearing source values, orientation reset + dimension tag update.little_exifconverts the exporter's simple-format WebP to the extended format and attaches an EXIF chunk, so WebP EXIF only needed a file-type mapping (tested with both the lossy VP8 output of the export pipeline and lossless VP8L).Screenshots/Videos
Before/after on a real Fujifilm X-T50 JPEG, exported with Save with Metadata ON and Remove GPS Data OFF after the image had been opened once (sidecar present). Tag counts from
exiftool -a -G1 -s, excluding the ExifTool/System/File/Composite/JFIF pseudo-groups:A tag-by-tag value diff of original vs. new export shows exactly the intended differences:
Orientation(reset, rotation baked in),Software(RapidRAW),ExifImageWidth/Height(now the real export dimensions). With Remove GPS Data ON the export contains zeroGPS*tags. exiftool parses the copied Fujifilm MakerNote in the export without errors, so the offsets survive the copy.Testing
cargo fmt --check,cargo clippy --lib --tests --no-depsandcargo testpass. Verified against a real Fujifilm X-T50 JPEG (see table above): tag-by-tagexiftooldiff of original vs. export matches except for the intentional differences (Orientation, pixel dimensions,Software, thumbnail).Test Configuration:
Checklist
Additional Notes
exiftool -validatereports "entries out of order" notices on the exports becauselittle_exifappends the ExifOffset/GPSInfo/InteropOffset pointer tags after the (otherwise sorted) IFD entries at encode time. That's a pre-existing quirk of thelittle_exifencoder (it just wasn't visible before because so few tags survived), readers are unaffected, and it would be fixed upstream, not here.AI Disclaimer:
Please state the involvement of AI in this PR: