Skip to content

Add From metadata lens correction for Sony ARW and DNG - #1058

Draft
hsnilsson wants to merge 4 commits into
marcinz606:mainfrom
hsnilsson:codex/metadata-lens-correction
Draft

Add From metadata lens correction for Sony ARW and DNG#1058
hsnilsson wants to merge 4 commits into
marcinz606:mainfrom
hsnilsson:codex/metadata-lens-correction

Conversation

@hsnilsson

@hsnilsson hsnilsson commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Camera scans can contain lens-correction coefficients, but the Geometry panel only offers a manual radial coefficient. This adds From metadata beside Distortion Correction and shows the source and available distortion/lateral CA correction. Missing, identity, malformed, or unsupported data leave correction unavailable.

Only the mode is saved with the edit. Each source supplies its own coefficients, so copied settings and mixed batches cannot apply another file's lens profile. Enabling the mode replaces manual distortion; disabling it restores the manual slider.

Implementation

  • LensWarp defines has_distortion, has_ca, and remap(...). Frozen RectilinearWarp and SonyWarp classes own their coordinate calculations. Metadata and rendering use the protocol without vendor-specific branches.
  • One extension-to-reader table selects a file reader. Sony and DNG share bounded TIFF traversal; other containers can supply their own reader. Adding a model requires a warp class, a reader, and one registration.
  • Preview and export share the same inverse warp, after flat-field and before sensor unmix, user geometry, and crop. Row blocks bound map memory. Flat-field is not applied again downstream.
  • EXIF orientation, DNG ActiveArea, and decoder/DefaultCrop offsets are respected, including the existing DNG 1.7 JPEG XL fallback.
  • The mode and flat-field content are part of source/cache identity. Positive Source remains independent in the decode paths and preview cache.
  • Existing sidebar controls and shortcut registration are reused. The in-app guide, pipeline documentation, and architecture notes are updated.

Supported scope

Sony ARW distortion and red/blue CA tables, plus DNG WarpRectilinear (opcode 1, one or three planes). DNG 1.7 is supported when it carries this correction model. Lens identification and camera on/off flags alone do not enable correction; inherited Sony tags in converted DNG files are not applied.

WarpRectilinear2, fisheye, other/mixed opcode lists, composites, and RGB+IR sources remain unsupported. Choose the correction before crop/retouch. Edge sampling replicates boundary pixels. No Lensfun lookup is added.

Validation

  • Full suite: 5,496 passed, 1 failed, 26 skipped, 14 deselected on Windows / Python 3.13.
  • The failure was test_saving_again_keeps_the_profile_in_its_own_file: a same-mtime/size TOML cache collision in code unchanged from upstream/main. It was reproduced separately; all 17 crosstalk profile tests passed on rerun.
  • 61 metadata tests cover validation, TIFF byte orders, per-channel CA, all EXIF orientations, per-file coefficients, preview/export parity, and independent Positive Source/lens cache entries.
  • A third structural warp and a non-TIFF test reader exercise registration, capability reporting, caching, orientation, channel mapping, and row blocks without changing shared code.
  • 32 image comparisons are pixel-identical to the implementation before the protocol refactor, covering Sony, DNG, sequential warps, crop offsets, and all EXIF orientations.
  • Ruff formatting/lint and the repository's ty checks pass; the protocol and warp modules also pass ty without diagnostic exclusions. Makefile recipes were run through uv because GNU Make is unavailable on this host.

The user's Sony A7R V files have not been tested directly.

Implements the initial supported-format subset of #1057. Related to #1033 (external Lensfun profiles).

@hsnilsson
hsnilsson marked this pull request as draft September 6, 2026 18:17
@marcinz606

Copy link
Copy Markdown
Owner

nice, I had quick scrollthrough and I have one suggestion:

right now adding a new vendor (eg Fuji or Nikon) means touching few places. Consider giving RectilinearWarp/SonyWarp a common tiny protocol (has_distortion, has_ca, a remap(...) method) so a future CanonWarp is one new class + one new reader function, not three edited call sites.

@hsnilsson

Copy link
Copy Markdown
Contributor Author

Hi, my agent pushed this without my permission and before I had time to actually work on it. Sorry for that, and thanks for great feedback - definitely makes sense to have a protocol. I hope to get some time tomorrow or at least within a few days to finish this.

Keep Positive Source and embedded lens settings in the preview, cache and export paths. Add regression coverage for independent cache entries and worker forwarding.

Validation: ruff format/check, ty check, and full pytest suite: 5479 passed, 26 skipped, 14 deselected.
Keep model capabilities and inverse maps in frozen warp classes. Use one file-reader registry, with shared TIFF traversal for Sony and DNG, so additional formats do not change metadata aggregation or rendering.

Validation: 61 metadata tests passed; 32 image cases are pixel-identical to the previous implementation. Ruff and repository ty checks passed, with strict ty checks on the lens modules.

Full suite: 5496 passed, 1 failed, 26 skipped, 14 deselected. The unchanged crosstalk profile test hit a same-mtime/size cache collision; reproduced separately, and all 17 profile tests passed on rerun.
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.

2 participants