Skip to content

fix(export): write complete, valid EXIF for RAW sources - #1897

Merged
CyberTimon merged 2 commits into
CyberTimon:mainfrom
lalibertemarc:fix/raw-export-exif
Oct 11, 2026
Merged

CyberTimon merged 2 commits into
CyberTimon:mainfrom
lalibertemarc:fix/raw-export-exif

Conversation

@lalibertemarc

@lalibertemarc lalibertemarc commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes #1808 and #1612.

Exports from RAW files wrote incomplete and partly invalid EXIF. For RAW sources, the export took its values from RapidRAW's metadata cache, which stores display strings. It only read the RAW's own typed values when that cache was missing, which almost never happens once a folder has been browsed. As a result:

  • DateTimeOriginal / CreateDate were written as 2026-09-12 13:41:33. EXIF requires 2026:09:12 13:41:33, so Windows Explorer's "Date taken" and Immich ignored the date (exiftool -validate flags it).
  • White balance, flash, metering mode, exposure program and exposure bias were dropped, even though RapidRAW shows them in the metadata panel. Missing some EXIF in exported JPEG: Windows 11 #1612 is the same root cause on a DxO DNG.
  • ExifVersion, FlashpixVersion and ComponentsConfiguration were missing, though the spec requires them.

Now the RAW's typed EXIF is always read first. The cache then overrides only the fields it already handled, so things like the Nikon lens name recovered from the MakerNote (#1823) are kept. Its dates are converted to EXIF format.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Performance improvement
  • Code refactoring
  • Documentation update
  • UI/UX improvement
  • Build/CI or Dependency update

Changes Made

  • exif_processing.rs:
    • apply_exif_from_rawler (the former inline fallback block) now runs for every RAW source, before the cache values are applied. It also writes ShutterSpeedValue, ApertureValue and LensInfo (lens specification).
    • Cache dates go through format_creation_datetime(.., EXIF_DATETIME_FORMAT), which shares the parsing with the existing fmt_date_str.
    • ExifVersion (0232) and FlashpixVersion (0100) are always written, and ComponentsConfiguration is written for JPEG.
    • The RAW metadata is read once per export and shared by the EXIF and GPS steps. Before, GPS parsed the file a second time. read_raw_metadata, read_raw_metadata_from_path and both rawler apply functions now share one loader (raw_metadata_from_source) and two rational helpers (rawler_to_ur64 / rawler_to_ir64, next to the existing to_ur64 / to_ir64).

Screenshots/Videos

image

This one was already present, just showing no regression :

image image

Testing

  • These changes were tested locally by a human and confirmed to work.
  • I haven't added any automated tests to the code because the codebase currently lacks a test suite.

Checked on NEF (Nikon D810), ARW (three Sony files, one with GPS), CR3, CR2, RAF and DNG:

  • The capture date is in EXIF format.
  • Make/model, lens, f-number, exposure time, ISO, focal length, exposure bias, program, metering, flash and white balance are present, along with shutter speed/aperture value and lens specification where the camera records them.
  • GPS is still written for the ARW that has it.

Test Configuration:

  • OS: Windows 10 Home (19045)
  • Hardware: AMD Ryzen 5 3600X, NVIDIA GeForce RTX 2070

Checklist

  • My code follows the project's code style
  • I haven't added unnecessary AI-generated code comments
  • My changes generate no new warnings or errors

Additional Notes

AI Disclaimer:

Please state the involvement of AI in this PR:

  • This PR is created by an AI agent
  • This PR is mostly AI-generated but edited/merged together by a human
  • This PR was handwritten with AI assistance (spell check, logic suggestions, error resolving)
  • This PR contains only blood, sweat, and coffee (AI-free)

🤖 Generated with Claude Code

lalibertemarc and others added 2 commits October 11, 2026 01:17
RAW exports took their EXIF from RapidRAW's metadata cache, which holds
display strings, and only read the RAW's typed values when that cache
was missing. Capture dates were written as "2026-09-12 13:41:33", which
is not valid EXIF, so Explorer and Immich showed no date taken, and
white balance, flash, metering mode, exposure program and exposure bias
were dropped (CyberTimon#1808, CyberTimon#1612).

Always read the typed EXIF from the RAW first, also writing shutter
speed, aperture value and lens specification, then let the cache
override the fields it carries, with its dates converted to EXIF
format. Add the ExifVersion, FlashpixVersion and (for JPEG)
ComponentsConfiguration tags the spec requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CyberTimon

Copy link
Copy Markdown
Owner

LGTM, thanks so much!!

@CyberTimon
CyberTimon merged commit 2534f67 into CyberTimon:main Oct 11, 2026
16 checks passed
FabianWeiss90 added a commit to FabianWeiss90/RapidRAW that referenced this pull request Oct 11, 2026
CyberTimon#1897 split write_image_with_metadata into write_exif_metadata and
embed_xmp, while this branch had split the same function differently to
get at the gathered metadata before encoding. Resolved in favour of the
upstream structure: the gathering step is extracted out of
write_exif_metadata into collect_metadata_from_source again, which the
TIFF encoder calls before writing any pixels.

ExifVersion and FlashpixVersion, which CyberTimon#1897 adds, sit in that shared
step now, so TIFF carries them as well and exiftool -validate passes
without warnings.
@mlc

mlc commented Oct 14, 2026

Copy link
Copy Markdown

thank you for this! I was in the process of writing up a bug for this and was delighted to find that not only was there a bug filed but a fix has already been merged!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: exports from RAW write an invalid capture date and drop most shooting metadata

3 participants