Commit Graph
2648 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 82566817e6 LR-IMP-FORMATS: drop references to analysis files that aren't in the repo
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:08:10 -04:00
Brandon Thomas b6f6a979e5 Merge PR #608 (updated head) 2026-10-10 01:02:10 -04:00
Brandon ThomasandClaude Opus 5.5 4a3f9e9b6d Apply #580's updated head (drops the DSC-R1 SR2 refusal)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:02:09 -04:00
akvaithiandClaude Opus 5.5 7828f93c32 LR-HDR-EXPORT: HDR AVIF (10-bit Rec. 2020 PQ)
`encode_avif_pq`: linear Rec. 2020 with SDR white at 1.0 → PQ (SDR white at
203 cd/m², BT.2408), BT.2020 NCL YCbCr 4:4:4, 10-bit, with CICP nclx
(9/16/9, full range) and a clli box. ravif fixes the sRGB curve, so this
drives the rav1e + avif-serialize it already uses (no new crates).

Export: AVIF with `hdr` renders the HDR edit in Rec. 2020 and writes PQ.
Photos without an HDR edit export as before, in every format. CoreImage
decodes the file as HDR (same 3.1 % of the frame above SDR white as the gain
map JPEG of the same edit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:37 -05:00
akvaithiandClaude Opus 5.5 af06f2dbc1 LR-HDR-VISUALIZE: HDR controls in the Light panel, Visualize HDR, export option
- Light panel: HDR switch, headroom limit and an SDR Rendition flyout
  (shown with HDR on); Visualize HDR beside the switch.
- `Overlay::HdrRange` / `view.visualizeHdr`: the SDR render dimmed to grey,
  with pixels the HDR rendition puts above SDR white painted in four bands by
  stops above it. Rendered on the CPU from the float HDR render.
- Export dialog: "HDR output" for JPEG (gain map) and 32-bit TIFF.
- Parity (Q. HDR 2 ✅ 3 🟡, LR-EDIT-HDR-MODE ✅, LR-EXP-HDR 🟡), README, ROADMAP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:37 -05:00
akvaithiandClaude Opus 5.5 34d9c8f2d2 LR-EXP-HDR: HDR export (gain map JPEG, float TIFF) and develop.hdr
- `ExportOptions.hdr` (`hdr` param): photos edited in HDR export as ISO
  21496-1 gain map JPEGs (the SDR rendition as the base, the gain map measured
  against it as written) or 32-bit float TIFF with highlights above 1.
  Other formats and SDR edits export as before.
- Output sharpening and watermarks apply to both renditions.
- `develop.hdr {enabled?, maxEv?}` turns HDR editing on/off and sets the
  headroom limit.

Checked on macOS: ImageIO reports both the ISO and the Apple gain map, and
CoreImage's HDR decode of a 3 EV edit reaches 2.95 EV.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:37 -05:00
akvaithiandClaude Opus 5.5 e11db8fea0 LR-HDR-EXPORT: ISO 21496-1 gain map JPEG codec
`lightcraft_codecs::gainmap`:
- `compute` measures a gain map (luminance or RGB, log2, block-averaged)
  from an SDR and an HDR rendition; `apply` rebuilds the HDR rendition.
- ISO 21496-1 metadata: writer (fixed denominator) and reader (also the
  common-denominator form; refuses unknown versions, backward maps and zero
  denominators). Adobe `hdrgm` XMP reader and writer, per-channel values as
  rdf:Seq; Apple's HDRGainMap/HDRToneMap description of the same map.
- `encode_jpeg`: base with CIPA DC-007 MPF index (gain map typed 0x050000),
  the ISO marker and Container XMP merged into the user's packet, followed by
  the gain map JPEG. `read_jpeg` / `is_gain_map_jpeg` find and decode the map.

Also: gain map images are no longer picked as embedded thumbnails (an Ultra
HDR JPEG could show its greyscale gain map in the grid). The JPEG APP-segment
building is shared with `encode_jpeg`. Fuzzed with the other decoders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:01:35 -05:00
akvaithiandClaude Opus 5.5 791526aa8c LR-HDR-EDIT: HDR settings, HDR tone map and the float HDR render
- `DevelopSettings.hdr`: enabled, headroom limit (`max_ev`) and SDR-rendition
  offsets (brightness, contrast, highlights, shadows, whites, clarity), with
  control specs (`hdr.maxEv`, `hdr.sdr*`) and copied with the Light group.
- `ToneMap::hdr` / `display_hdr`: the SDR curve through the midtones, with
  highlights lifted up to `2^max_ev`; identical to the SDR tables at peak 1.
- `OutputDepth::F32Hdr`: unclamped linear output up to the peak. The finish
  stage carries the peak through highlight desaturation, gamut mapping,
  encoding, curves, grain and LUT profiles; with HDR off every branch is the
  SDR code path, bit for bit.
- `settings_for`: every non-HDR render (CPU and GPU) uses the SDR rendition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:00:54 -05:00
radialmonster d138236291 LR-IMP-FORMATS: Sony DSC-R1 .SR2 decodes (big-endian 16-bit words in a little-endian TIFF)
Uncompressed 16-bit words are read in the other byte order only when the
file's order leaves more than 1% of sampled words at or above
1 << max(bits, 14) and the other order leaves none. Measured on the CC0
DSC-R1 (raw.pixls.us 3221). Crop and white balance (SR2SubIFD) are not
addressed. RENDER_CACHE_VERSION 31 (adjust at merge).
2026-10-09 22:01:36 -04:00
sanyamsingh001andCodex 41e95fa78e LR-IMP-ADD-DIALOG: settle Copy layout before locating Tags
Preserve the existing tag assertions and deadlines after editing the rename template.

Co-authored-by: Codex <codex@openai.com>
2026-10-10 11:46:07 +10:00
radialmonster 44b126274d LR-IMP-FORMATS: decode 12.8 bpp block-packed ORF (E-300, E-500, E-330, high-res E-M5 II / PEN-F)
Single-strip ORFs at 12.8 bits per pixel are 16-byte blocks: ten little-endian
12-bit samples in bytes 0..14 plus a zero pad byte. Main routed them through the
XZ-2 12-bit word path (stripes, magenta cast). New branch before it; the exactly
12.0 bpp XZ-2 branch is unchanged. Layout measured on CC0 files (log and scripts in
data/testing/retry-olympus-e300 and tools/retry-olympus-e300).

RENDER_CACHE_VERSION bumped to 30 (open PRs use up to 29; adjust at merge).
2026-10-09 21:42:15 -04:00
Brandon ThomasandClaude Opus 5.5 b4ed033c2d Integrate batch 22: fix cross-PR breaks
- #540's crs::Target replaces the raw flag: #597/#604's folder sync and sidecar_op and #533's
  process tests pass the photo's target instead of a bool.
- #568's DRO test fits through #528's fit_look (proxies now return the clipped mask).
- #541 (French) and #564 (Ukrainian) gain the 15 keyword format strings #578-#592 added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:04:48 -04:00
Brandon Thomas 987a572512 Merge PR #612
# Conflicts:
#	crates/pipeline/src/finish.rs
#	docs/parity.md
#	docs/whats-new.md
2026-10-09 20:56:58 -04:00
Brandon Thomas 89753f5d67 Merge PR #563
# Conflicts:
#	docs/parity.md
2026-10-09 20:56:57 -04:00
Brandon Thomas 53c056daf3 Merge PR #564
# Conflicts:
#	README.md
#	crates/ui-egui/src/i18n.rs
#	docs/localization.md
#	docs/parity.md
2026-10-09 20:56:56 -04:00
Brandon Thomas 0fc81747cb Merge PR #541 2026-10-09 20:56:55 -04:00
Brandon Thomas 2f35949678 Merge PR #604
# Conflicts:
#	crates/engine/src/sidecar.rs
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/panels/dialogs.rs
#	docs/whats-new.md
2026-10-09 20:56:55 -04:00
Brandon Thomas b785023073 Merge PR #597
# Conflicts:
#	crates/catalog/src/journal.rs
#	crates/catalog/src/lib.rs
#	crates/catalog/src/local.rs
#	crates/catalog/src/tests_format_version.rs
#	crates/catalog/src/tests_journal.rs
#	crates/ui-egui/src/panels/left.rs
#	docs/whats-new.md
2026-10-09 20:56:33 -04:00
Brandon Thomas 2421f2223b Merge PR #592
# Conflicts:
#	crates/ui-egui/src/tests_panels.rs
#	docs/whats-new.md
2026-10-09 20:55:50 -04:00
Brandon Thomas bf0656fa95 Merge PR #588
# Conflicts:
#	docs/whats-new.md
2026-10-09 20:55:49 -04:00
Brandon Thomas 4372750986 Merge PR #585
# Conflicts:
#	docs/whats-new.md
2026-10-09 20:55:49 -04:00
Brandon Thomas d0f042c269 Merge PR #578
# Conflicts:
#	crates/catalog/src/journal.rs
#	crates/catalog/src/tests_format_version.rs
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	docs/whats-new.md
2026-10-09 20:55:40 -04:00
Brandon Thomas c2142540fe Merge PR #561
# Conflicts:
#	docs/parity.md
#	docs/whats-new.md
2026-10-09 20:54:56 -04:00
Brandon Thomas 244d279091 Merge PR #536
# Conflicts:
#	crates/catalog/src/tests.rs
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/lib.rs
#	docs/parity.md
2026-10-09 20:54:53 -04:00
Brandon Thomas a891c62eb9 Merge PR #550
# Conflicts:
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
2026-10-09 20:54:47 -04:00
Brandon Thomas 771882ae52 Merge PR #570 2026-10-09 20:53:53 -04:00
Brandon Thomas 15850a55b2 Merge PR #580
# Conflicts:
#	crates/engine/src/media.rs
#	crates/raw/src/vendor/arw.rs
#	crates/raw/tests/corpus.rs
#	docs/parity.md
#	xtask/src/main.rs
2026-10-09 20:53:21 -04:00
Brandon Thomas 4a8241dde4 Merge PR #575
# Conflicts:
#	crates/engine/src/media.rs
#	crates/raw/tests/corpus.rs
#	docs/parity.md
#	xtask/src/main.rs
2026-10-09 20:51:50 -04:00
Brandon Thomas f4f7d5c401 Merge PR #616
# Conflicts:
#	crates/catalog/src/model.rs
#	crates/engine/src/media.rs
#	docs/parity.md
2026-10-09 20:51:49 -04:00
Brandon Thomas 2c5121ae3b Merge PR #568
# Conflicts:
#	crates/engine/src/camera_preview.rs
#	crates/engine/src/media.rs
#	docs/camera-preview-colour.md
#	docs/parity.md
2026-10-09 20:51:08 -04:00
Brandon Thomas d9f63f0b7b Merge PR #583
# Conflicts:
#	crates/engine/src/media.rs
2026-10-09 20:51:08 -04:00
Brandon Thomas db03b4a586 Merge PR #528
# Conflicts:
#	crates/engine/src/camera_preview.rs
#	crates/engine/src/media.rs
2026-10-09 20:51:07 -04:00
Brandon Thomas 6f323e01d9 Merge PR #533
# Conflicts:
#	docs/parity.md
2026-10-09 20:50:41 -04:00
Brandon Thomas 6bf2722209 Merge PR #607
# Conflicts:
#	crates/engine/src/media.rs
#	xtask/src/main.rs
2026-10-09 20:50:23 -04:00
Brandon Thomas 41cdec5daf Merge PR #586
# Conflicts:
#	crates/engine/src/media.rs
#	docs/parity.md
2026-10-09 20:50:08 -04:00
Brandon Thomas 630e2edc47 Merge PR #522 2026-10-09 20:50:06 -04:00
Brandon ThomasandClaude Opus 5.5 835dcf6657 Keep the UI-zoom tests: set the interface scale with ui.zoomFactor now that Cmd+Plus zooms the photo (#566)
The CLI snapshot test and the headless resize test sent Cmd+Plus to change egui's
interface scale; with the keys handed to View > Zoom they no longer did. A
ui.zoomFactor control request (0.5-3, documented) sets the scale explicitly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:49:00 -04:00
Brandon ThomasandClaude Opus 5.5 93e48f8be7 LR-BEHAV-LOCALIZE: Ukrainian coverage gaps are reported, not failed; Compare keeps Lightroom's "Select" label
A label added by another PR (Decrease Rating, Display Profile, …) no longer fails the
Ukrainian test; it shows in English until translated, as for the other languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:44:04 -04:00
Alex ChambersandClaude Opus 5.5 8b9a020084 LR-EDIT-AUTO: Lightroom-like Auto, calibrated on Lightroom's Auto results (#318, #209)
Auto was a percentile rule that set Exposure about 1.4 EV higher than
Lightroom's Auto on the same photos (mean +1.81 against +0.44 EV) and
barely used Shadows: on 24 Sony raw photos its results were further from
Lightroom's Auto results (median dE76 22.0) than leaving the photo
unedited (7.9), about 18 L* too bright.

Auto is now Lightroom's shape of rule with values chosen for our results:
- Exposure = -0.58 - 0.41 * the scene's log-average luminance (EV from
  middle grey, scene-linear, under the photo's white balance, so it does
  not depend on the base tone curve), clamped to -2..3 EV. The slope is
  Lightroom's: its Auto's chosen Exposure against our log average, r -0.92;
- Highlights -66 and Shadows +52: Lightroom's own average Auto values;
- Contrast +68 and Vibrance +30 (our scales; our base tone is flatter);
  Whites, Blacks and Saturation 0.
The exposure offset, Contrast and Vibrance were fitted jointly so our
renders match Lightroom's Auto exports on the 16 photos whose starting
look Sony's DRO doesn't brighten (#568 changes the other 8). Held out one
photo at a time, each fold fitted from its own training photos only:
median dE76 6.38 on those 16 (8.28 unedited, 18.81 with the old rule),
12 of 16 closer than unedited; 7.70 on all 24 (7.92 unedited); on the 8
DRO photos 9.39 (7.00 unedited), their brighter start showing through.
Freeing Highlights and Shadows too (5 fitted values) did no better held
out (6.51) and left them poorly determined across folds.

The log average skips pixels that aren't finite (a damaged decode) through
the proxy's resampling and white balance; with no valid pixel, Exposure 0.

Values are black-box observations of Lightroom (the settings its Auto
chose and its exports), as in #514. Auto only applies when asked for, so
existing edits keep their look; HDR merges with Auto Settings use the
same rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:43:11 +02:00
Brandon ThomasandClaude Opus 5.5 010d9bb5da LR-IMP-FORMATS: saturation-point search refuses NaN, negative or inverted levels and overflowing active areas (underflowed on a negative black level)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:43:04 -04:00
Brandon Thomas 4c4e9b154f Merge origin/main into #522 (keep both new masking tests) 2026-10-09 20:38:01 -04:00
Brandon Thomas 6fcc1e5e28 Merge PR #571 2026-10-09 20:36:41 -04:00
Brandon Thomas c5551783d2 Merge PR #527 2026-10-09 20:36:41 -04:00
Brandon Thomas 214f1a6af5 Merge PR #581
# Conflicts:
#	crates/engine/src/crs.rs
2026-10-09 20:36:40 -04:00
Brandon Thomas 8329b7be0a Merge PR #608 2026-10-09 20:36:11 -04:00
Brandon Thomas 21b58f4653 Merge PR #562 2026-10-09 20:36:11 -04:00
Brandon Thomas 9a694a4d41 Merge PR #572 2026-10-09 20:36:10 -04:00
Brandon Thomas 6203fa36a1 Merge PR #557 2026-10-09 20:36:10 -04:00
Brandon Thomas 514e828508 Merge PR #540 2026-10-09 20:36:10 -04:00
Brandon Thomas bde7ff911e Merge PR #530 2026-10-09 20:36:10 -04:00