From 857ffcd41c1994faf2c090c863e691a88754d647 Mon Sep 17 00:00:00 2001 From: dev-null-undefined Date: Wed, 14 Oct 2026 13:37:20 +0200 Subject: [PATCH] =?UTF-8?q?LR-MERGE-HDR:=20=F0=9F=9F=A1=20after=20testing?= =?UTF-8?q?=20on=20real=20brackets;=20gap=2029?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested on real Sony A7R VI brackets (67 MP): the merged radiance agrees with every frame within ~1 % in all three channels and the measured exposure steps match EXIF within 0.03 EV, and the black-hole stars and the merge memory are fixed. What keeps the row 🟑 goes to gap 29: AI Denoise doesn't run on merged (linear) DNGs as Lightroom's does, JPEG brackets have no camera response curve, and every frame is held as 32-bit float (~0.86 GB per 67 MP frame). Merge area 100 % β†’ 88 % in target-app-parity.md. Co-Authored-By: Claude Opus 5.5 --- docs/gaps.md | 6 ++++-- docs/merge.md | 1 + docs/parity-checklist.md | 12 ++++++------ docs/target-app-parity.md | 5 +++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/gaps.md b/docs/gaps.md index ee6e58d1c..11125a67c 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -1,6 +1,6 @@ # Gaps: where LightCraft falls short of Lightroom -> **Last reviewed:** 2026-10-11 Β· **Last updated:** 2026-10-13 Β· **Change:** patch (gap 8: Nikon Z 6II / Z 8 / Z f in-file distortion; gaps 10, 22 and 23 listed once again: merges had left two copies of each, and `cargo xtask parity` now fails on a gap listed twice) +> **Last reviewed:** 2026-10-11 Β· **Last updated:** 2026-10-14 Β· **Change:** minor (gap 29 added: HDR merge on real brackets β€” AI Denoise on merged DNGs, JPEG response curves, per-frame memory) Every known shortfall, one entry each, ranked by user impact (how many Lightroom users hit it, and how hard it blocks them), then by effort. **Agents pick work from the top** (the first entry nobody is @@ -42,6 +42,7 @@ Hours are Opus 5.5 agent wall-clock hours (see [target-app-parity.md](target-app | 25 | **File writes**: lossy DNG; AVIF import; Render to DNG as a catalog command (the export format landed) (PSD export landed with Edit in PhotoCraft, #953) | file-format-parity.md | interchange edge cases | 19–34 | [file-format-parity](file-format-parity.md) | | 26 | **Performance at scale**: 85k-photo library opens in 1.7–4.7 s; 100k grid test pending; colour NR at half resolution | ROADMAP log, gpu-pipeline.md | large-catalog users | 15–30 | [target-app-parity](target-app-parity.md#by-dimension) | | 27 | **Windows / Linux runtime coverage**: Windows installer UI unverified on Windows (#79); GPU path proven on Apple and on one AMD GPU on Linux (Radeon 8060S, Vulkan); NVIDIA, Intel and DX12 unverified; the Linux riscv64 tarball (new in 0.6.0, #844) is cross-compiled and never run beyond a QEMU smoke test | ROADMAP, issues, `release.yml` | non-Mac users find bugs first | 13–27 | [hardware-parity](hardware-parity.md) | +| 29 | **HDR merge leftovers** (LR-MERGE-HDR): AI Denoise doesn't run on merged (linear) DNGs; JPEG brackets are treated as linear (no camera response curve); every frame is held as 32-bit float, ~0.86 GB per 67 MP frame (half-float frames would halve it) | tested on Sony A7R VI brackets 2026-10-14 ([merge.md](merge.md)); Lightroom's Denoise supports HDR DNGs | HDR shooters who denoise their merges, merge JPEGs, or merge 7+ frames of high-resolution raws on 16 GB machines | 10–20 (+ denoise linear-RGB contract, gap 11) | [merge](merge.md) | | 28 | **Small Classic shortcuts and keys**: rating `[` `]`, flag cycling, filter-bar keys, F1 help, panel keys (Tab, F5–F8) | [ui-parity](ui-parity.md#shortcuts) | Classic muscle memory | 4–8 | [ui-parity](ui-parity.md) | Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform work they need around them, @@ -49,7 +50,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w ## Gaps by kind -- **Feature:** 5, 8, 11, 12, 13, 15, 16, 18, 19 +- **Feature:** 5, 8, 11, 12, 13, 15, 16, 18, 19, 29 - **UI / UX:** 4, 23, 24, 28 - **File format:** 2, 6, 7, 10, 13, 20, 25 (raw ones in [raw-parity.md](raw-parity.md)) - **Hardware:** 14, 17, 22, 27 @@ -72,6 +73,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w | Date | Change | Summary | |---|---|---| +| 2026-10-14 | minor | Gap 29 added: the HDR merge, tested on real 67 MP brackets, keeps moving clipped highlights and merges in batches now; AI Denoise on merged DNGs, JPEG response curves and per-frame memory remain | | 2026-10-13 | patch | Gaps 10, 22 and 23 each had two rows (two branches edited them; the merges kept both): the older copies are removed, and `cargo xtask parity` (in `ci`) now fails when a gap number is listed twice | | 2026-10-11 | minor | Gap 10 shrinks: Leica Q3 verified by a recorded check of 38 private DNGs (236 models verified; Leica 14); gap not closed | | 2026-10-12 | minor | Camera-look deep shadows follow the JPEG toe (#1307); camera calibration remains partial | diff --git a/docs/merge.md b/docs/merge.md index 8a2622aba..3485e02d1 100644 --- a/docs/merge.md +++ b/docs/merge.md @@ -74,6 +74,7 @@ scale in `BaselineExposure`; raw sources keep their DNG colour tags (camera RGB) panoramas carry no lens corrections, nor does an HDR whose frames don't share an orientation (they are turned before merging). - No camera response calibration for JPEG brackets (sRGB decoding is taken as linear light). +- AI Denoise doesn't run on merged DNGs (they are linear RGB; the denoiser takes Bayer raws), unlike Lightroom's. - Boundary Warp is a separable stretch, not a content-preserving mesh warp; Fill Edges is diffusion, not patch synthesis. - *Create Stack*: the result goes on top of a collapsed stack of its sources (`Catalog::stack_with_ops`); its diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index 2dfc22064..67ab83c53 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -1,6 +1,6 @@ # Lightroom parity checklist -> **Last reviewed:** 2026-10-10 Β· **Last updated:** 2026-10-14 Β· **Change:** minor (LR-MERGE-HEADLESS, MENU-PHOTO-MERGE: HDR for Each Bracket Set) Β· **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 +> **Last reviewed:** 2026-10-10 Β· **Last updated:** 2026-10-14 Β· **Change:** minor (LR-MERGE-HDR βœ… β†’ 🟑 after testing on real 67 MP brackets: moving clipped highlights fixed, gaps remain; LR-MERGE-HEADLESS: HDR for Each Bracket Set) Β· **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 The measured, row-by-row checklist: one row per Lightroom feature, menu item and shortcut, what we have and what is missing. It answers *does the feature exist?* (feature breadth). Whether it is good @@ -40,7 +40,7 @@ cited here still exists. Formerly docs/parity.md. | L. Presets (PRE) | 6 | 0 | 1 | 1 | 2/2 (100%) | 2/2 (100%) | | M. Versions & history (VER) | 5 | 0 | 0 | 0 | 1/1 (100%) | 3/3 (100%) | | N. Copy / paste / sync (SYNC) | 5 | 0 | 0 | 0 | 3/3 (100%) | 1/1 (100%) | -| O. Merge (MERGE) | 4 | 0 | 0 | 0 | β€” | β€” | +| O. Merge (MERGE) | 3 | 1 | 0 | 0 | β€” | β€” | | P. Enhance (ENH) | 0 | 0 | 2 | 0 | β€” | β€” | | Q. HDR (HDR) | 2 | 3 | 0 | 0 | β€” | β€” | | R. Video (VID) | 0 | 0 | 5 | 1 | β€” | 0/2 (0%) | @@ -53,9 +53,9 @@ cited here still exists. Formerly docs/parity.md. | Y. Menus | 84 | 0 | 4 | 8 | 47/47 (100%) | 23/23 (100%) | | Z. Keyboard shortcuts (desktop) | 76 | 4 | 3 | 1 | 49/52 (94%) | 23/25 (92%) | | Lightroom Classic extras | 34 | 16 | 35 | 8 | β€” | 24/26 (92%) | -| **Total** | 409 | 53 | 72 | 35 | 193/201 (96%) | 146/159 (92%) | +| **Total** | 408 | 54 | 72 | 35 | 193/201 (96%) | 146/159 (92%) | -Weighted completion (βœ… = 1, 🟑 = Β½, 🚫 left out): **81.6%** of 534 in-scope rows β€” P0 98.0% of 201 Β· P1 95.0% of 159 Β· P2 50.0% of 173. +Weighted completion (βœ… = 1, 🟑 = Β½, 🚫 left out): **81.5%** of 534 in-scope rows β€” P0 98.0% of 201 Β· P1 95.0% of 159 Β· P2 49.7% of 173. ## Top gaps and shortcut notes @@ -347,7 +347,7 @@ differences and missing bindings are in [ui-parity.md](ui-parity.md#shortcuts). | Id | Feature | Tier | Status | Evidence | Missing / notes | |---|---|---|---|---|---| -| LR-MERGE-HDR | HDR merge | P2 | βœ… | `cmd:merge.hdr`, `cmd:dialog.mergeHdr`, `crates/merge/src/frame.rs` (`Frame::lens`) | auto align, deghost None–High + overlay, auto settings, float DNG, Create Stack; the DNG keeps the reference frame's embedded lens corrections (tested by `hdr_merge_keeps_the_reference_frames_lens_corrections`); JPEG brackets treated as linear; raws without colour matrices of their own (CR2, NEF, ARW…) keep the colour they open with, written as DNG tags (`starting_colour_tags`; the look's chroma curve has no tag; panoramas too), issue #965 | +| LR-MERGE-HDR | HDR merge | P2 | 🟑 | `cmd:merge.hdr`, `cmd:dialog.mergeHdr`, `crates/merge/src/frame.rs` (`Frame::lens`), `crates/merge/src/hdr.rs` | auto align, deghost None–High + overlay, auto settings, float DNG, Create Stack; the DNG keeps the reference frame's embedded lens corrections (tested by `hdr_merge_keeps_the_reference_frames_lens_corrections`); raws without colour matrices of their own (CR2, NEF, ARW…) keep the colour they open with, written as DNG tags (`starting_colour_tags`; the look's chroma curve has no tag; panoramas too), issue #965. Tested on real Sony A7R VI brackets (67 MP, 2026-10-14): frames agree with the merged radiance within ~1 % in all channels, exposure steps match EXIF within 0.03 EV. A clipped highlight of the reference that moved in other frames (a star at 200 mm) stays instead of becoming a black hole, and deghost (≀ 2048 px maps) catches a brighter frame's ghost in a dark sky (`a_clipped_star_of_the_reference_is_not_erased_by_frames_where_it_moved`, `deghost_removes_a_bright_frames_ghost_in_a_dark_sky`). 🟑 because: AI Denoise doesn't run on merged DNGs (Bayer only; Lightroom's does), JPEG brackets are treated as linear (no camera response curve), and every frame is held as 32-bit float (~0.86 GB per 67 MP frame, so 7 frames need ~7 GB); gap 29 | | LR-MERGE-PANO | Panorama | P2 | βœ… | `cmd:merge.panorama`, `cmd:dialog.mergePanorama` | spherical/cylindrical/perspective + auto, boundary warp, auto crop, fill edges (diffusion), DNG; no lens model / 360Β° wrap | | LR-MERGE-HDRPANO | HDR panorama | P2 | βœ… | `cmd:merge.hdrPanorama`, `cmd:dialog.mergeHdrPanorama` | brackets grouped by EXIF | | LR-MERGE-HEADLESS | Merge with last settings | P2 | βœ… | `cmd:merge.hdrLast`, `cmd:merge.panoramaLast`, `cmd:merge.hdrPanoramaLast`, `cmd:merge.hdrBatch`, `crates/catalog/src/stacks.rs` (`bracket_sets`) | no dialog; the options of the last merge of that kind (defaults the first time). HDR for Each Bracket Set merges a batch like Lightroom's merge of stacks: one HDR per stack among the photos, then per bracket (photos taken less than a second apart, after the shutter time, at exposures β‰₯ Β½ EV apart; bursts at one exposure are skipped), one after the other in the activity stack (cancelling one stops the rest; a failed set doesn't); CLI `merge hdr-batch FILES…` | @@ -790,7 +790,7 @@ Latin stays upright. Advanced Japanese composition remains open. Regression cove | Date | Change | Summary | |---|---|---| -| 2026-10-14 | minor | LR-MERGE-HEADLESS, MENU-PHOTO-MERGE: HDR for Each Bracket Set (`merge.hdrBatch`): one HDR per stack or bracket among the photos, one after the other | +| 2026-10-14 | minor | LR-MERGE-HDR βœ… β†’ 🟑: tested on real 67 MP Sony brackets; moving clipped highlights (black-hole stars) and dark-sky ghosts fixed, merge memory cut ~25 %; AI Denoise on merged DNGs, JPEG response curves and per-frame memory remain (gap 29). LR-MERGE-HEADLESS, MENU-PHOTO-MERGE: HDR for Each Bracket Set (`merge.hdrBatch`) | | 2026-10-13 | patch | LR-VIEW-COMPARE, LRC-LIB-COMPARE: ⌘/Ctrl- and Shift-clicks on the filmstrip in Compare change the selection as in the grid; the two photos shown stay selected and the active photo is unchanged (#187); statuses unchanged | | 2026-10-13 | minor | KEYC-SELECTONLYACTIVE: Edit β†’ Select Only Active Photo (βŒ˜β‡§D) lands as a new row; status 🟑 (headless-tested, native macOS menu path unverified) | | 2026-10-13 | patch | LRC-LIB-CATALOG-IMPORT: a catalog whose tables are all still in its `-wal` file (main file schema format 0) opens instead of failing as an unsupported schema format; status unchanged | diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index ba62abb40..21e732c98 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -1,6 +1,6 @@ # Target-app parity: LightCraft vs Adobe Lightroom -> **Last reviewed:** 2026-10-10 Β· **Last updated:** 2026-10-12 Β· **Change:** minor (UI/UX remaining 40–70 h β†’ 34–58 h after the accessibility audit) Β· **Target:** Adobe Lightroom Classic 15.5 (August 2026) and Lightroom 9.6 (desktop) +> **Last reviewed:** 2026-10-10 Β· **Last updated:** 2026-10-14 Β· **Change:** minor (merge 100% β†’ 88%: LR-MERGE-HDR 🟑 after testing on real brackets) Β· **Target:** Adobe Lightroom Classic 15.5 (August 2026) and Lightroom 9.6 (desktop) The authoritative assessment of how close LightCraft is to Lightroom. The row-by-row checklist is [parity-checklist.md](parity-checklist.md); the ranked work list is [gaps.md](gaps.md); deep areas @@ -75,7 +75,7 @@ from the checklist sections and the deep-dive documents. | Remove, heal, Enhance (denoise, Raw Details, Super Resolution, Lens Blur) | 7% | 45% | 30% | 70–130 h | checklist I 75%, P 0% | | Presets, profiles, versions, history, sync | 5% | 95% | 85% | 8–15 h | | | Export | 6% | 89% | 75% | 15–30 h | checklist S 88.9% | -| Merge and HDR | 3% | 85% | 60% | 20–35 h | merge 100%, HDR 70% (no HDR display) | +| Merge and HDR | 3% | 85% | 60% | 20–35 h | merge 88% (HDR merge 🟑: AI Denoise on merged DNGs, JPEG response, memory; gap 29), HDR 70% (no HDR display) | | Views, compare, zoom, culling | 5% | 90% | 70% | 15–30 h | zoom detail P0 gap | | Classic output modules (Map, Book, Slideshow, Print, Web, publish, tethering) | 4% | 15% | 10% | 90–150 h | Classic extras 48% counts many small keys; the modules themselves are mostly ⬜ | | Video | 1% | 0% | 0% | 25–45 h | catalogued only | @@ -297,6 +297,7 @@ P2 items 12–25 h; look tuning, performance, packaging, hardening 25–45 h. | Date | Change | Summary | |---|---|---| +| 2026-10-14 | minor | Merge and HDR: merge 100% β†’ 88% (LR-MERGE-HDR βœ… β†’ 🟑 after testing on real 67 MP brackets; gap 29); area percentages unchanged | | 2026-10-12 | minor | UI/UX remaining 40–70 h β†’ 34–58 h (accessibility audit landed, ui-parity.md); percentages unchanged | | 2026-10-11 | minor | EOS R5 Mark II CR3 verified (raw-parity.md): use-weighted share whose camera decodes 84% β†’ 85%, RAW decoding 76% β†’ 77%; full 60.6% β†’ 60.7%, mainstream depth 71.8% β†’ 72.1%, essentials depth 77.4% β†’ 77.5%; the rounded numbers (~61%, ~49%, ~64%) are unchanged | | 2026-10-10 | minor | RAW measured model by model (raw-parity.md): RAW decoding (76%) and colour (35%) are explicit rows of the full sum (59% β†’ 61%); mainstream uses the use-weighted 84% plus a Γ—0.85 colour discount (51% β†’ 49%); essentials uses 84% Γ— colour 0.75 (63% β†’ 64%); beta ~14 points |