Commit Graph
1422 Commits
Author SHA1 Message Date
dev-null-undefinedandClaude Opus 5.5 5f2f013c8e Perf: a full-size raw decode no longer copies its 64 MP image to "fit" it
`load_bytes_now` ran every development through `resample::fit`, which returns a clone when the
image already fits. At full size (1:1 zoom, export) that cloned the whole picture: 797 MB and
~0.3 s for a 9984 × 6656 Sony ILCE-7RM6 raw. It now fits only when the image is larger, as the
other preview paths in files.rs already do. Output unchanged (same pixels, by construction).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:00:12 +02:00
Marco Arnulfo c10ca4e958 LR-IMP-PREVIEW-READ: a raw whose embedded preview can't be read still gets a thumbnail (fixes #1448)
The grid queues no render behind an unedited raw's quick thumbnail, since the embedded JPEG is
meant to be the thumbnail. But whether that JPEG can be read is only known when the quick job
runs, and `quick_thumb_job` had no fallback: when the preview loader returned nothing the job
failed with "no quick preview", the failure was remembered for that key, and the cell stayed
empty until an edit changed it. The quick job now carries the real thumbnail job as its last
resort, as `quick_view_job` already does for the loupe.
2026-10-13 09:01:48 +02:00
OneSlipsandClaude Opus 5.5 bd50896ca1 LR-MASK-EFFECTS: merge upstream main into pr/mask-effects
Conflicts: the 9 locale *-formats.json catalogs (both sides appended
messages at the end; kept both) and docs/parity-checklist.md (header
change list, regenerated summary via `cargo xtask parity --write`,
revision history rows from both sides).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:54:08 +10:00
Atmik Shetty 63f68f5044 Merge remote-tracking branch 'upstream/main' into feat/print-color
# Conflicts:
#	crates/engine/src/lib.rs
2026-10-13 12:08:59 +05:30
Claude 64f354fca3 LR-MERGE-HDR: merged DNGs declare the white balance their source shows (follow-up to #1123)
#1123 gives HDR and panorama merges of raws without colour matrices the colour they open with, but writes
ColorMatrix1 from the forward matrix, so the as-shot white the DNG declares lands wherever the fitted look and the
generic camera model take it. On real ILCE-7M3 brackets the HDRs opened at As Shot 6113–7307 K / +115 (Duv +0.038)
where the ARWs show 3932–5268 K / +7, and any white-balance edit turned them green (CIEDE2000 11–13 against the ARW
at the same Temp/Tint). The render at As Shot was right (0.4–0.8).

The colour matrices now declare the white balance the source shows, decided by files::WbScaleOf (new dng_white):
the camera's measured matrices when they give the source's scale (lightcraft_raw::spectral; the DNG then reads every
white as the source does), else a matrix under which the as-shot neutral is the white the scale shows (Sony's
presets' reading, 6500 K / 0 on the relative scale, the file's own white otherwise). Forward matrix and neutral are
unchanged, so is the render at As Shot.

Measured on the same brackets with this change on a fork build: As Shot 4813 / 5268 / 3932 K, +8 / +8 / +7 as the
ARWs (declared white Duv +0.003); same Temp/Tint within CIEDE2000 0.8–1.7 of the ARW for most changes, about 5 for
the largest (5268 → 3200 K, 3932 → 6500 K: the ARW adapts its look with Bradford, the DNG rebalances in camera space).

Tests: a merged DNG shows its source's As Shot on all four scales (measured matrices, presets, relative, own); with a
look that tints white the DNG declares the shown white, gives the measured model's multipliers at other whites and
renders at As Shot as the source does. Both fail on main (ILCE-7M3 case: (7342, 115) for (5268, 8)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 06:37:11 +00:00
Jason Baldwin 6477d031fc LRC-LIB-PEOPLE: face pictures come from the embedded preview and are kept in the thumbnail cache (#1440)
An unedited raw's face tile is cut from its largest embedded preview, read
the planned way (header and JPEG, never the sensor data), when the preview
holds at least 3/4 of the tile's pixels across the face; otherwise, and for
edited photos and other files, it is developed as before. Tiles keep going
to the memory + on-disk thumbnail cache, now at 16 px size steps so the
thumbnail slider reuses them. The planned preview path carries an Adobe RGB
preview colour space and applies it instead of declining to the whole-file
read (Sony alpha 1 previews).
2026-10-13 08:31:23 +02:00
Atmik Shetty 6e5cd82ce7 Merge remote-tracking branch 'upstream/main' into feat/print-color
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
2026-10-13 12:00:45 +05:30
Brandon ThomasandClaude Opus 5.5 ae9b09d3c2 Batch 32: rustfmt after merges
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 02:07:07 -04:00
Arekatla Nishanth ChowdaryandClaude Opus 5.5 edc3661680 Issue #1200: portable mode, a portable.txt beside the executable keeps settings in LightCraftData
As in PhotoCraft: when portable.txt (or LightCraft.portable) sits next to the
executable, config_dir() is <exe dir>/LightCraftData, so settings, logs and
models stay with a portable copy instead of %APPDATA%. LIGHTCRAFT_CONFIG_DIR
still wins and is used without probing beside the executable. A portable
folder that can't be written logs a warning and the platform folder is used.
The check runs once per process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 11:34:33 +05:30
Brandon Thomas 8a640dc70b Merge PR #1077 2026-10-13 02:04:06 -04:00
Brandon Thomas 478f20054b Merge PR #1056 2026-10-13 02:02:17 -04:00
Brandon Thomas 643bc7f909 Merge PR #850 2026-10-13 01:57:40 -04:00
Claude 8bb084074c Merge storytold/lightcraft main into LR-MERGE-HDR (lens corrections)
Conflicts: crates/engine/src/tests_merge.rs (#1123's test landed where this branch's is; both kept),
docs/parity-checklist.md (the LR-MERGE-HDR row: both notes) and docs/whats-new.md (both entries).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 05:57:08 +00:00
bflatastic d752076339 Batch 32: fixes for PRs merged together (#984 leap-year lint, #1344 ColorData field, #1187 preset panel builds) 2026-10-13 11:11:02 +07:00
bflatastic 702f90bfc9 Batch 32: close the tests two merges added at one place; cargo fmt 2026-10-13 11:08:16 +07:00
bflatastic 84d6849cf3 Merge PR #1216
# Conflicts:
#	crates/engine/src/files.rs
#	crates/ui-egui/locales/de-formats.json
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es-formats.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr-formats.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja-formats.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br-formats.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru-formats.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk-formats.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans-formats.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant-formats.json
#	crates/ui-egui/locales/zh-hant.json
#	docs/parity-checklist.md
2026-10-13 11:06:28 +07:00
bflatastic 692ab7f7c2 Merge PR #1235
# Conflicts:
#	docs/whats-new.md
2026-10-13 11:05:55 +07:00
bflatastic 32253d862a Merge PR #1017
# Conflicts:
#	crates/pipeline/src/spots.rs
#	docs/gaps.md
#	docs/parity-checklist.md
2026-10-13 11:05:54 +07:00
bflatastic 4e78514948 Merge PR #1324
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/raw-parity.md
#	docs/whats-new.md
2026-10-13 11:05:53 +07:00
bflatastic 97f8b8c87c Merge PR #1024
# Conflicts:
#	crates/ui-egui/locales/es.json
2026-10-13 11:05:45 +07:00
bflatastic 8df468bfc6 Merge PR #1246
# Conflicts:
#	crates/pipeline/src/spots.rs
#	docs/parity-checklist.md
2026-10-13 11:05:44 +07:00
bflatastic d3c024e4df Merge PR #1047
# Conflicts:
#	crates/pipeline/src/spots.rs
#	docs/gaps.md
2026-10-13 11:03:10 +07:00
bflatastic 76fd9b9ae8 Merge PR #805
# Conflicts:
#	docs/camera-preview-colour.md
#	docs/parity-checklist.md
2026-10-13 11:02:58 +07:00
bflatastic 9b4047b1d4 Merge PR #661 2026-10-13 11:02:53 +07:00
bflatastic 9e0f00c557 Merge PR #1222
# Conflicts:
#	docs/parity-checklist.md
2026-10-13 11:02:40 +07:00
bflatastic a0b1da61aa Merge PR #1338 2026-10-13 11:02:38 +07:00
bflatastic 14b111f6f5 Merge PR #1344
# Conflicts:
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-13 11:01:49 +07:00
bflatastic b9b6bf57de Merge PR #1020
# Conflicts:
#	docs/parity-checklist.md
2026-10-13 11:01:43 +07:00
bflatastic 64b3361125 Merge PR #1340
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-13 11:01:42 +07:00
bflatastic 2fc2419fa1 Merge PR #1193
# Conflicts:
#	docs/parity-checklist.md
2026-10-13 11:01:37 +07:00
bflatastic dca358d435 Merge PR #1389 2026-10-13 11:01:01 +07:00
bflatastic ac19325c57 Merge PR #978 2026-10-13 11:01:01 +07:00
bflatastic 5388d20088 Merge PR #1125 2026-10-13 11:00:56 +07:00
bflatastic b2a5997e55 Merge PR #1412 2026-10-13 11:00:53 +07:00
bflatastic a6369c4009 Merge PR #1264 2026-10-13 11:00:47 +07:00
bflatastic 6435019603 Merge PR #1394 2026-10-13 11:00:47 +07:00
bflatastic 3e5439cc94 Merge PR #1177 2026-10-13 11:00:44 +07:00
bflatastic c9e12bd9ff Merge PR #1123 2026-10-13 11:00:41 +07:00
bflatastic cd75e11841 Merge PR #1149 2026-10-13 11:00:41 +07:00
bflatastic 035c378758 Merge PR #1052 2026-10-13 10:39:12 +07:00
bflatastic 9fe9beffbc Merge PR #1007 2026-10-13 10:38:47 +07:00
eliets2 a10bc04b8b smart previews: store proxies at JPEG quality 97 and version the encoding (#709)
The proxy's largest visible error against the original was the JPEG encoder's
quantised 8x8 DCT DC - each block's own mean, luma and chroma - which shows as
block steps across the frame and a small constant colour shift, and grows with
saturation. Quality 92 -> 97 shrinks those quantisers to about a third (block
-mean dE76 0.138 vs 0.202 on the fidelity test's smooth scene), at about twice
the file size; what remains is the 8-bit sRGB quantisation both encoders share,
which only a lossless proxy format can close.

The header gains an `enc` field (encode version 2) and the folder's look marker
becomes "<look> <enc>": a proxy or marker from before the encode version is
rebuilt/rescanned once, so existing libraries pick the new quality up without
any command. Old files still decode bit-identically (the scale mapping is
untouched, decode ignores `enc`), and a new proxy read by an older build is
left alone by its staleness check.

The fidelity test pins the gain with a frozen copy of the old encoder and a
block-mean dE76 metric (per-pixel dE is dominated by the shared 8-bit floor);
the 0.8 bound is the geometric midpoint between the no-op ratio 1.000 and the
0.632 floor cap the 8-bit quantisation sets on this scene.
2026-10-13 04:55:40 +03:00
Claude 4c1dfc5b0f LR-MERGE-HDR: keep the reference frame's lens corrections in HDR merges
Merged HDR DNGs lost the camera's embedded lens correction: load_frame strips the lens opcodes from each
source (frames are merged uncorrected) and write_linear_dng wrote no OpcodeList3, so Optics ▸ Enable Lens
Corrections did nothing on the result (Sony ILCE-7M3/7RM4A, Panasonic/Leica, DNGs with their own opcodes).

Each raw frame now keeps the lens corrections it applies (the DNG 1.6 skip rule already applied),
re-expressed for the default crop develop keeps by the new Opcode::cropped: the centre moves into the crop
and coefficients are rescaled for the crop's farthest corner. HdrResult carries the reference frame's and the
DNG writes them as its OpcodeList3. Frames turned before merging (mixed orientations) and panoramas carry none.

Tests: cropped corrections give the crop of the corrected whole (WarpRectilinear, WarpRectilinear2 with and
without reciprocal, FixVignetteRadial); an HDR merge of cropped, corrected brackets, upright and vertical, gives
the same profile correction as its reference photo (fails without the fix). Real brackets not measured yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 01:05:26 +00:00
Marco Arnulfo 77d8558fc4 LR-CROP-STRAIGHTEN: a crop shrunk to fit by Straighten grows back as the angle returns (fixes #1388) 2026-10-13 02:55:39 +02:00
Marco Arnulfo 0fa8070647 AI Denoise: Install from file says why a model file is refused (fixes #1381) 2026-10-13 02:33:10 +02:00
dev-null-undefinedandClaude dead4367b0 M5.6: the pinned original no longer evicts the photo's other sources (64 MP edits decoded the raw again)
MediaCache::enforce_budget never evicts the original of the photo on screen (set_on_screen), but it still
counted it. A 64 MP original (Sony A7R VI: 9984×6656 linear float, 760 MiB) nearly fills the default cache
share (768 MiB) alone, so the loop evicted everything else instead: the photo's preview and thumbnail sources,
the rendered previews and the prefetched neighbours. Every edit at 1:1 (the whole-frame render and the
thumbnail), every zoom out and every step to the next photo then decoded the raw again.

The pinned original is now left out of what is compared with the budget. The rest still fits the share; the
original sits over it, as the first commit of this PR already allowed.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-13 00:41:09 +02:00
dev-null-undefinedandClaude a99c084805 M5.6: a slider drag no longer decodes the edited photo's thumbnail
Each drag tick changed the edited photo's settings, so the filmstrip asked
for a new thumbnail render every frame. For an unedited raw shown with its
embedded preview, the thumbnail-level source had never been decoded, so each
of those renders decoded the whole raw (a 64 MP ARW: over a second), several
side by side, and the loupe's drafts queued behind them.

- The edited photo's thumbnail is not re-rendered during a slider drag while
  it has one; it follows once the drag ends.
- A thumbnail of a photo whose preview-level source is decoded (the one in
  the loupe) is cut from that source (SourceRef::Fit) instead of decoding the
  file again; not when the photo has a denoised picture.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-13 00:29:45 +02:00
PiMinusMaxandClaude Opus 5.5 d9006c96f6 LR-EDIT-COLOR-TEMP: Kelvin white balance from Sony's white-balance presets
Sony ARWs of cameras without measured colour matrices were edited on the
relative scale (6500 K / 0 = as shot). Their SR2SubIFD stores the
multipliers of the camera's presets at 2500, 3200, 4500, 6000 and 8500 K;
lightcraft_raw::kelvin_presets reads the as-shot multipliers on the curve
through them and they take the spectral matrices' place in the #730
design (as-shot Kelvin and tint only; look, Bradford adaptation and the
pixel-identical legacy upgrade unchanged).

Covered: ILCA-99M2, ILCA-77M2, SLT-A33, DSC-RX10, ILCE-3500, ILCE-7S.
Kelvin-dial shots read back 3400 -> 3396, 5200 -> 5193, 4700 -> 4708,
5600 -> 5594 K; Shade 7493 K. Off-curve constants (isotherm tilt 0.74,
tint spacing 1) measured from the 14 Sony bodies with both spectral
matrices and presets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:37:22 +02:00
Alex ChambersandCodex 1926c9029f LR-PROF-CAMERACOLOR: cover the held-out toe error gate
Add correlated dark holdouts that reject misleading training and accept
matching training. Check finite, monotone curves in both cases. Confirm
the regression fails with the error gate removed and passes when restored.

Qualify the improvement claim when no original curve can be fitted, and
explain the source-look process policy and offline smart preview refresh.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-12 22:27:31 +02:00
Alex ChambersandCodex c11764a12a LR-PROF-CAMERACOLOR: fit the camera toe from dark JPEG tones
Use separate luminance pairs for tone fitting so the camera look follows
its JPEG into deep shadows. Keep colour pairs and holdouts unchanged.
Require enough correlated shadow samples and lower held-out error, with
noise and compression floors and the existing median curve fit.

Add synthetic regressions, bump look and render cache versions, and
record the public multi-make and private numeric validation in the docs.

Fixes #1307

Co-Authored-By: Codex <noreply@openai.com>
2026-10-12 21:50:24 +02:00