Commit Graph
1092 Commits
Author SHA1 Message Date
Andrew FrahnandClaude Opus 5.5 9181aa0b6c LR-IMP-FORMATS: import and decode Mamiya MEF (uncompressed 12-bit; WB from the RGB preview)
Sources: TIFF 6.0 and own black-box analysis of the CC0 ZD sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 06:27:05 +11:00
Andrew FrahnandClaude Opus 5.5 a6d048be8d LR-IMP-FORMATS: decode Epson ERF (12-bit 16-byte blocks; WB from the preview's neutrals)
Sources: TIFF 6.0 and own black-box analysis of the three CC0 samples;
white-balance estimate from the embedded preview: own design.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 05:43:30 +11:00
Nigel Ihza Firdausy fdccb413cd fix(import): avoid scanning symlink aliases into the library 2026-10-12 01:15:34 +07:00
Andrew FrahnandClaude Opus 5.5 a1d7c488f8 LR-EXP-RENDERDNG: Render to DNG export format (linear float DNG of the rendered photo)
New export format `rendereddng` (export dialog: Format DNG, "DNG of: Rendered
photo"; `app.export`; MCP export tool): the rendered photo, with the edit,
crop, size, output sharpening and watermark baked in, written by the new
`lightcraft_raw::write_rendered_dng` as a LinearRaw DNG of 16-bit float Deflate
tiles in the export colour space. ColorMatrix1 (XYZ -> space), ForwardMatrix1
(space -> XYZ D50), a neutral AsShotNeutral and an identity ProfileToneCurve
make raw converters show it as rendered. HDR edits keep highlights above white.
Bad input (wrong sample count, zero or huge sizes, NaN/inf, out of half-float
range) gives an error or is clamped, never a panic.

Also fixes the Rust 1.99 clippy lint chunks_exact_to_as_chunks in
pipeline/spots.rs that fails `cargo xtask ci` on main.

Sources: Adobe DNG Specification 1.4+ (LinearRaw, ColorMatrix/ForwardMatrix,
ProfileToneCurve); own design.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 04:33:12 +11:00
Andrew FrahnandClaude Opus 5.5 32819d4900 LR-MASK-BRUSH: pen pressure scales brush size and flow
Brush strokes record a pen pressure (0..1) per point from egui touch
force while Brush > Pen Pressure is on (default). Each dab's radius goes
from a tenth to all of the brush, and its flow is proportional to the
pressure, in the committed stroke and the live preview alike. A mouse
stroke stores no pressure, so documents and renders are unchanged. The
GPU mask kernel leaves pressure strokes to the CPU. mask.brushStroke takes
`pressure`; bad lists are refused. Also satisfies clippy 1.99's
chunks_exact_to_as_chunks in spots.rs.

Sources: own design.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 04:04:01 +11:00
goujichengandDeepSeek V3.2 3c7f450137 LR-IMP-PREVIEW-READ: a CR3 or a TIFF raw's preview is read from the plan's ranges
The header-only path added in #755 answers for a Fuji RAF, whose preview pointer sits in the first
bytes. A Canon CR3 keeps its preview in a JPEG track, and a TIFF raw (CR2, ARW, DNG, RW2, 3FR …) can
keep its preview tag in an IFD the prefix cuts short: both fell back to `std::fs::read` of the whole
file — tens of megabytes for a JPEG of a few, on the format of the largest bucket in gaps.md (Canon,
33 % of photographers).

`preview_window` now asks `lightcraft_raw::sparse::preview_plan` — the module #961 added for the
import path, which had no production caller — which ranges `embedded_preview` reads, and reads
exactly those: `planned_preview` fills a buffer of the file's length, reads the ranges the plan names
and asks again until it says `Ready`. The buffer is the file's length, which the memory gate counted
already, and its untouched pages stay zero, so what this path costs is the bytes read — on macOS a
freed buffer of that size may sit in the allocator's cache rather than go back to the OS (measured on
a 38k-photo import, #832). The loop gives up past 60 % of the file, the bound step 2's partial read
uses, and a plan that does not fit, a file past 1 GiB or a window that does not decode all end in the
whole-file fallback.

The quick path hands the JPEG to the decoder alone, so two container facts the whole-file path applies
have to be visible in the bytes it is handed, or the file declines and the whole file keeps the
preview:

- a preview colour space of Adobe RGB (`decode_raw_preview` applies it; a JPEG-only decode has the
  JPEG's own space, else sRGB). A container that says sRGB does not decline — that is what the decode
  assumes anyway, and declining it took the fast path away from a real Sony ARW;
- the file's own EXIF orientation, when the preview JPEG carries none of its own: the plan's header is
  a bounded 64 KiB (the header route grows its prefix to the preview's declared extent instead), and
  an orientation tag it cannot see would show the preview unrotated.

Measured over the whole CC0 corpus (111 raws): 52 files take this route, reading a median 7.8 % of
their bytes (0.9-27.7 %) — RW2 3.3 %, Leica RWL 4.1 %, ARW 7.5 %, CR3 8.4 %, DNG 9.7 %, CR2 14.3 % —
while the 21 RAFs stay on the header route (median 4.5 %). The other 38 read whole: NEF, NRW, ORF, PEF
and SRW because the planner does not describe them (an SRW plans to the whole file, which the 60 %
budget then declines), plus the ARWs, CR2s, CR3s and DNGs that declare Adobe RGB or whose plan wants
more than that budget — the bytes they read are the ones the plan would have read anyway. Across all
111 files the plan handed on the same preview as the whole file, with the skipped bytes zeroed and
again 0xFF. `LIGHTCRAFT_PROFILE=1` prints

    [profile] preview …/arw-sony-a7rm4a-compressed.arw: read 688128 of 61832192 bytes (plan, window 483441)

Tests: a synthetic TIFF/DNG whose preview only its tags locate (identical pixels to the whole-file
path, the CFA strip unread), the same structure without the tag that makes it a raw, a file whose
orientation only the whole file shows, and a file that states Adobe RGB against one that states sRGB;
the opt-in real-file test reports which path answered.

Co-Authored-By: DeepSeek V3.2 <noreply@deepseek.com>
2026-10-12 00:57:30 +08:00
Andrew FrahnandClaude Opus 5.5 c78b457c0d LR-VIEW-ZOOM: soft proofing at 1:1 renders a zoom window; 1:1 pixels tested equal to export
Soft proof is per-pixel, so the After window carries the proof like the
whole-frame render under it (the proof key is part of the tile's look).
New tests: a 1:1 window of a 24 MP photo equals the full-size export to
within one level; soft proofing at 1:1 is a canvas-sized frame plus a
native window. profile_slider_drag gains a soft-proof case. Gap 4 closed,
checklist row to done with measured Linux latencies.

Sources: own design.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 03:37:35 +11:00
OneSlipsandClaude Opus 5.5 0f40a2d2f5 LR-MASK-EFFECTS: manage, group and fully import local adjustment presets (engine)
Mask effects gain groups, stars, partial presets (only some sliders, with or
without Amount), optional brush settings and the settings an imported preset
carries that we can't apply (kept for export). New commands: mask.updateEffect,
renameEffect, duplicateEffect, favoriteEffect, setEffectGroup,
renameEffectGroup, toolEffect; applyEffect takes several masks, all masks, or
the same-named masks on the selected photos in one undo step. A new mask starts
with the effect last applied to a mask of its kind (kept with the library).

Import (mask.importEffects and preset.import): Lightroom Classic local
.lrtemplate, Camera Raw local-correction .xmp, .lceffect and zips of these;
folders and LrC divider presets ("10 ----- DETAIL ----- 10") become groups;
grain / Point Color / toningLuminance reported and kept. Malformed files are
errors, never panics.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:33:25 +10:00
OneSlipsandClaude Opus 5.5 594c046d52 LR-MASK-EFFECTS: mask effect (brush) presets and Lightroom local preset import
Named sets of local adjustment sliders, picked from a new Effect menu
above the mask sliders in the Masking panel (apply sets every slider and
keeps Amount; save current; import; right-click delete; the menu names
the matching effect, else Custom). Saved with the library preferences.

Commands: mask.effects, mask.applyEffect, mask.saveEffect,
mask.deleteEffect, mask.importEffects, mask.exportEffects (.lceffect).

Lightroom local adjustment presets (.lrtemplate with type
LocalizedAdjustmentPreset) are read by mask.importEffects and routed
there by preset.import / File > Import Profiles & Presets, which used to
reject them as having no develop settings. Their lower-camel Local* keys
map through the same table as XMP mask fields (crs_masks::local_values);
sliders without a counterpart (toningLuminance, grain) are reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:32:37 +10:00
OneSlipsandClaude Opus 5.5 b7222213c9 PERF-PRESETS: thousands of presets no longer stall every command and frame
A Lightroom collection imported whole (11 113 presets, a 42 MB presets.json)
made every interaction take seconds:

- Session::persist ran after every command and serialized the whole preset
  list to compare it with the last write: 609 ms per slider tick (release,
  the real collection). Session::presets is now a PresetList whose generation
  changes on mutable access; persist serializes only when it (or the profile
  lists) changed, and skips the write when the bytes hash the same.
  develop.set: 609 ms -> 2.3 ms; preset.apply: 598 ms -> 3.1 ms.
- The Presets panel deep-cloned every preset into a BTreeMap, built a row,
  widget id and (with thumbnails) a variant render job for each of them every
  frame. Grouping is cached per generation and only rows in view are laid
  out: 5041 -> ~20 rows a frame, 2.3 ms with 5000 presets.
- The preset pickers (Import dialog, Settings > Import) build only the rows
  in view.
- add_presets and opening a library compared every preset with every other
  (quadratic); both use hash indexes now. Opening no longer serializes the
  list once just to remember it.

Tests: develop commands don't re-serialize unchanged presets (and a change
is still saved), generation semantics, a 20 000-preset import, and the
panel building only visible rows (fails on the old code: 5041 rows).
An ignored bench (presets_scale_bench, LIGHTCRAFT_BENCH_PRESETS) times a
real presets.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:32:29 +10:00
OneSlipsandClaude Opus 5.5 2da4b36b45 Windows: keep sidecar spellings on case-insensitive volumes; fix rename/sidecar tests
20 engine tests failed on Windows on clean main. Three real bugs on
case-insensitive volumes (Windows, default macOS APFS) caused most of them:

- Renaming a photo probed `a.XMP` before `a.xmp`. On a case-insensitive
  volume the upper-case spelling "exists" when only `a.xmp` is there, so the
  sidecar was moved as `Trip.XMP` (and its retained-packet record was taken
  under the wrong spelling). Upper-case candidates are now used only when the
  folder lists them exactly (new `MoveFs::listed`).
- `RealFs::same_file` on Windows (no file id in std) depended on argument
  order: `same_file("Trip.XMP", "Trip.xmp")` was false when `Trip.xmp` is the
  real entry, so saving after a partial rename reported a phantom collision.
  It is now symmetric, and also requires the names to differ only by case
  (two different files with equal size and mtime were "the same").
- Saving metadata picked the sidecar spelling by `is_file()`, lower case
  first, so the atomic write renamed an existing `Trip.XMP` to `Trip.xmp`.
  The spelling the folder lists now wins.

The rest were fixtures: FakeFs fault paths, catalog paths and expected
paths spelled with `/` while the code joins with the host separator.

Regression tests: case_insensitive_renames_keep_each_sidecars_spelling
(FakeFs, every platform; fails without the fix) and
same_file_spellings_are_symmetric_on_windows. Linux behaviour unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:31:53 +10:00
Andrew FrahnandClaude Opus 5.5 0a6f8d3db8 LR-HDR-EXPORT: HLG HDR AVIF export (hdrTransfer) and a tested SDR/HDR display decision
AVIF HDR export takes hdrTransfer = pq | hlg (export dialog: HDR curve;
MCP export schema lists it). HLG writes CICP transfer 18 and no clli box.
The window logs whether it shows HDR; today always SDR (eframe configures
an 8-bit surface), with the platform / surface format / headroom / opt-out
rules unit-tested. Also satisfies clippy 1.99's chunks_exact_to_as_chunks
in spots.rs.

Part of #868.

Sources: ITU-R BT.2100 (HLG OETF, inverse OOTF with system gamma 1.2),
ITU-R BT.2408 (203 cd/m2 reference white at 75 % HLG); own design for
the display decision.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 03:02:02 +11:00
Robert Woldberg 48c61e80c1 Update progress bar, so large lightroom catalog impots do not appear hung 2026-10-11 09:52:02 -06:00
Andrew FrahnandClaude Opus 5.5 cc3eb1c846 LR-EXP-DNGOPT: lossy DNG export (DNG 1.4 compression 34892)
DNG export gains a "Lossy" compression: the raw data is demosaiced to linear
camera RGB (OpcodeList3 and the default crop applied), scaled to the resize long
edge when one is set, and stored as 8-bit baseline JPEG tiles at the export
quality. The codes follow a 1/2.2 power curve that a LinearizationTable maps
back to linear 16-bit values; colour matrices, white balance and the profile
look are kept. Available in the export dialog, `app.export`
(`dngCompression: "lossy"`) and the MCP export tool.

Also fixes a new clippy lint (chunks_exact_to_as_chunks) in pipeline/spots.rs
that fails `cargo xtask ci` on Rust 1.99.

Sources: Adobe DNG Specification 1.4+ (Compression 34892, LinearizationTable);
own design for the code curve.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 02:40:10 +11:00
Fabio LussiandClaude Opus 5.5 dafa00483a Export: "Same folder as original photo" destination mode
app.export takes destinationMode (specificFolder | sameAsOriginal); the
Export dialog shows it as "Export to". In sameAsOriginal mode each photo
is written into its original's folder plus the optional subfolder, with
the usual conflict policy and original guard per folder. A photo with no
folder on disk or whose folder is missing gets its own error. Saved in
presets and Export with Previous like the other options.

Fixes #956

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:28:40 +02:00
Alfons HoogervorstandClaude Sonnet 5.5 dd1a857d49 Issue #989: the ten sidecar repair tests also pass on a case-insensitive volume (item 3, ten of eleven)
The tests were written for a case-sensitive disk. rename.rs sidecars() offers both
.XMP and .xmp per naming and keeps those that exist; on case-insensitive APFS
a.XMP "exists" for a file stored as a.xmp, so the code renames a.XMP while the
fault injectors (Faults twice, PartialRename) compared exact paths with the
lowercase one: the injected failure never fired and the rename the tests expect
to be refused succeeded.

Fault injectors now match by same_path_or_file (equal path, or the same file by
identity); two assertions that compared an exact spelling use same_path_for_volume
(equal, or equal ignoring ASCII case on a case-insensitive volume), and one that
required the lowercase packet to be absent is skipped there, where both spellings
are one file. Helpers live in tests_xmp.rs. Production code is not touched.

Run with rustc 1.99.0 on macOS: case-insensitive APFS, the ten failed before and
pass now; case-sensitive APFS (a disk image), the original tests pass and so do
these. All 13 sidecar::tests_repair tests pass on both. cargo fmt is clean and
clippy over lightcraft-engine with --all-targets is clean. Not touched: the
.xmp -> .XMP spelling change on rename, and the Lightroom folder test (its own PR).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 17:26:54 +02:00
Fabio LussiandClaude Opus 5.5 15e308c3eb Sort ties by file name, then id
Photos that tie on the sort key (equal ratings, one import batch, a
burst within a second) now sort by file name before id, in
Catalog::query, Recently Added and auto-stack. Split out of #641.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:26:13 +02:00
Alfons HoogervorstandClaude Sonnet 5.5 8760dc4a41 Issue #989: odd_folders_never_fail_the_check skips its non-UTF-8 names where the file system refuses them (item 3, one of eleven)
APFS refuses names that are not valid UTF-8 (EILSEQ, os error 92), so the test's
create_dir_all(...).unwrap() panicked on macOS. The test now probes once with a
\xff folder; where that fails, the non-UTF-8 folder case and the non-UTF-8 entry
are skipped and the catalog-folder and symlink cases still run on a plain-named
folder. Where the probe succeeds (Linux, FreeBSD) the test is unchanged.

Run on macOS (case-insensitive APFS, rustc 1.99.0): the five tests in
tests_lightroom_folder pass, cargo fmt is clean, and clippy over lightcraft-engine
with --all-targets is clean. The ten sidecar tests of item 3 are not touched.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 17:21:31 +02:00
Jason Baldwin 6ec7044ebf Merge slideshow-templates into slideshow-export (origin/main: batch 31; whats-new keeps main's Reliability entry, parity summary refreshed) 2026-10-11 17:18:12 +02:00
Jason Baldwin 54c1048b57 Merge slideshow-titles into slideshow-templates (origin/main: batch 31; open_session keeps both the slide templates dir and main's apple_photos_background, formats locales merged, whats-new keeps main's Reliability entry, parity summary refreshed) 2026-10-11 17:16:36 +02:00
Jason Baldwin d485dc9011 Merge slideshow-overlays into slideshow-titles (origin/main: batch 31; whats-new keeps main's Reliability entry) 2026-10-11 17:14:04 +02:00
Jason Baldwin b2036ba50d Merge slideshow-composer into slideshow-overlays (origin/main: batch 31; whats-new keeps main's Reliability entry) 2026-10-11 17:12:42 +02:00
Jason Baldwin 2138175826 Merge slideshow-playback into slideshow-composer (origin/main: batch 31; locales merged keeping main's values, whats-new keeps main's Reliability entry, parity summary refreshed) 2026-10-11 17:11:12 +02:00
Jason Baldwin d14a44630d Merge origin/main into slideshow-playback (whats-new: batch 31's Reliability entry kept, Slideshow playback after it under 2026-10-11; parity summary refreshed) 2026-10-11 17:09:28 +02:00
Jason Baldwin ccfff38548 Merge slideshow-templates into slideshow-export (origin/main: sidebar and slideshow_export modules side by side; whats-new and tracker summary) 2026-10-11 16:33:00 +02:00
Claude 9e41805a12 M-edit-in: the many-photos test uses distinct files and edits before the second copy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 14:31:29 +00:00
Jason Baldwin b061563383 Merge slideshow-titles into slideshow-templates (origin/main: headless sessions load main's SAM3 model and the slide templates; format-locale keys from both; whats-new and tracker summary) 2026-10-11 16:30:20 +02:00
Jason Baldwin 41c9cd3817 Merge slideshow-overlays into slideshow-titles (origin/main: title-screen RenderResult gains main's gpu_fallback field; tracker summary refreshed) 2026-10-11 16:27:59 +02:00
Jason Baldwin 56d78344c1 Merge slideshow-composer into slideshow-overlays (origin/main: watermark draws through the shared TextLayout with main's quarter-turn rotation, separate insets and preview floor scale; overlay watermark sanitizes insetX/insetY/rotation and maps legacy inset) 2026-10-11 16:26:40 +02:00
Jason Baldwin efaa39b8b5 Merge slideshow-playback into slideshow-composer (origin/main: geocode + slideshow crates side by side in the manifests, locale keys from both, tracker summary refreshed) 2026-10-11 16:22:50 +02:00
Jason Baldwin 7b0fc19ebb Merge origin/main into slideshow-playback (icons: Play/Pause beside grading and appearance icons; settings: Slideshow tab beside appearance cards; render: Slide and CompareRegion slots; tracker summary and whats-new) 2026-10-11 16:19:50 +02:00
dev-null-undefined f4761b459c LR-PROF-CAMERACOLOR: camera-JPEG colour fit accepts previews above 64 MP (ILCE-7RM6 full frame) 2026-10-11 16:09:43 +02:00
Claude 4ebb934c56 Merge PR #677
On merge: the HDR histogram is applied in develop_reporting (#712 split develop), is skipped for
draft renders (a second render per drag tick), and HdrBins::bin clamps a hand-built split so it
can't underflow (test hdr_bins_with_any_split_stay_in_range).
2026-10-11 13:09:34 +00:00
Claude 9cf47c86fe Merge batch 30 fixes 2026-10-11 13:08:50 +00:00
Claude 7fe8f8dbd1 LR-BEHAV-UNDO: each rename-provenance fixture gets its own folder (#874's tests shared one and failed when run in parallel)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 13:08:37 +00:00
Jason Baldwin b0972e4488 Merge slideshow-templates into slideshow-export (origin/main: integration batch 26, #975; no conflicts) 2026-10-11 15:05:18 +02:00
Jason Baldwin 7e4ff5fddf Merge slideshow-titles into slideshow-templates (origin/main: integration batch 26, #975; no conflicts) 2026-10-11 15:05:04 +02:00
Jason Baldwin 857c15f3b3 Merge slideshow-overlays into slideshow-titles (origin/main: integration batch 26, #975; no conflicts) 2026-10-11 15:05:04 +02:00
Jason Baldwin 29203d6eec Merge slideshow-composer into slideshow-overlays (origin/main: integration batch 26, #975; no conflicts) 2026-10-11 15:05:04 +02:00
Jason Baldwin ee8b56f1db Merge slideshow-playback into slideshow-composer (origin/main: integration batch 26, #975; Cargo.lock: lightcraft-slideshow 0.6.0) 2026-10-11 15:05:04 +02:00
Jason Baldwin 8d692ed0a9 Merge origin/main into slideshow-playback (menus.rs ui_enabled: keep main's compare.set and this branch's slideshow.* arm) 2026-10-11 14:51:59 +02:00
Claude 9978dc739d Merge PR #643
# Conflicts:
#	crates/engine/src/export.rs
#	crates/engine/src/tests_export.rs
#	crates/mcp/src/headless.rs
#	crates/mcp/src/tools.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
#	docs/whats-new.md
2026-10-11 12:43:20 +00:00
Claude 6bc25940b8 Merge PR #780 (via claude/integrate-780) 2026-10-11 12:41:50 +00:00
Claude bd3b058a8f M-export: bump RENDER_CACHE_VERSION for the XYB JPEG XL decode fix
PR #780 changes how lossy (XYB) wide-gamut JPEG XL files decode (crates/codecs/src/jxl.rs), so cached renders of those photos are stale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:41:12 +00:00
Claude 255b23816d LR-EXP-PSD: Edit In makes a copy of every selected photo and opens them all (#920)
photo.editExternal takes the selection (or ids, at most 50): each photo gets its own -Edit copy
stacked on its original, the copies are selected and returned in copies (path / id / original
still name the first). Photo ▸ Edit In opens each copy in the editor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:40:58 +00:00
Claude 4a0d04b994 Merge PR #780
JPEG XL export via the pure-Rust jixel crate (robmdunn; fixes #247).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:40:55 +00:00
Claude 4ec3494733 Merge PR #434
On merge: Lightroom's default profiles (Adobe Standard, Adobe Color), named by nearly every sidecar,
give no camera-profile warning; other profiles still do (test default_lightroom_profiles_are_not_reported).
The import help string keeps main's onDeleted wording and gains warnings.
2026-10-11 12:38:16 +00:00
Claude e4a248c91f Merge PR #755
On merge: the quick preview path orients like the whole-file path (preview_orientation with the
raw's header prefix, so a portrait raw whose embedded JPEG carries no orientation is not sideways),
and its doc links point at preview_window.
2026-10-11 12:37:14 +00:00
Claude 44f86dc855 LRC-LIB-FOLDERS: drop an unused import (#947 follow-up)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:33:07 +00:00
Claude 47b5e0ae1b Batch 30: cargo fmt over the merged PRs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:32:03 +00:00