Commit Graph

969 Commits

Author SHA1 Message Date
Daniel Voshart fd4019300a LR-EDIT-DETAIL-DENOISE: address installation and model-policy review
Generated with Codex.
2026-10-08 22:07:23 -04:00
Daniel Voshart 7935999d94 LR-EDIT-DETAIL-DENOISE: non-destructive AI RAW denoise with pure-Rust CPU/GPU
Recover the unpublished denoise work against current upstream. Preserve later opt-in model setup, shared Rust HTTPS downloads, pending-photo resume and an Amount-independent switch. Keep original RAWs unchanged and share the current color finish between ordinary and denoised sources.

Bound public tiling inputs, refuse corrupt-cache exports, and retain synthetic/real-model coverage. Include two Windows path spelling fixes in existing tests. No model weights, face code, media or Tract runtime are included.

Validation: cargo xtask ci (all seven gates); installed RawNIND CPU/GPU agreement 1.38e-6; native CPU preview/export on a public 24 MP Sony RAW, unchanged original SHA-256.

Co-authored-by: Codex <noreply@openai.com>

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>

Generated with Codex.
2026-10-08 22:07:20 -04:00
Exalted5373 3c3b527b7f Web: the window wire test allows the CPU/GPU difference
a_window_job_crosses_the_wire_and_renders_the_same_window compared the worker's
CPU render with the engine job's render bit for bit. On a machine with a GPU the
engine job renders there, so the test failed by 1 LSB (on main too); without a
GPU (CI) both run on the CPU. It now checks both sizes and a maximum channel
difference of 3, the bound docs/gpu-pipeline.md documents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 18:33:43 -07:00
BFlat b1883231bd
Merge pull request #424 from storytold/claude/integrate-batch-13
Integrate #403, #411, #412, #414, #415, #416
2026-10-09 08:15:07 +07:00
Claude 12188161f9
Merge remote-tracking branch 'origin/main' into integ-b13 2026-10-09 00:46:05 +00:00
BFlat de79310ae0
Merge pull request #419 from storytold/claude/integrate-batch-12
Integrate #351 (sharp zoomed Detail view, #323) with follow-ups
2026-10-09 07:45:11 +07:00
Claude 373efc280e
Merge PR #416 2026-10-09 00:20:27 +00:00
Claude c75389dda1
Merge PR #415 2026-10-09 00:20:27 +00:00
Claude 8ee6d63d41
Merge PR #414 2026-10-09 00:20:27 +00:00
Claude f578b27273
Merge PR #412 2026-10-09 00:20:26 +00:00
Claude 43419dcfb8
Merge PR #411 2026-10-09 00:20:26 +00:00
Claude 83ea5e14df
Merge PR #403 2026-10-09 00:20:26 +00:00
Claude eab88ea30c
Follow-up to #351: drag drafts without a window stay canvas-sized; de/es/ru hint
- With no window (a mask or point-colour overlay, Visualize Spots, soft
  proofing, a window refused for a far read) the loupe renders the whole
  frame at the size it is drawn. While a slider drags that meant the
  photo's every pixel each draft frame at 1:1 and beyond (24 MP per tick
  where 2.5 MP was rendered before #351; mask overlays are on by
  default). A drag now drafts at most the canvas size, as the windowed
  path does; at rest the zoomed frame is rendered as before.
- The Preview size hint in German, Spanish and Russian; the replaced
  'Largest long edge…' text removed from those catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8
2026-10-09 00:16:01 +00:00
Claude 3e88a60dd6
Merge PR #351 2026-10-09 00:14:03 +00:00
ragtux 0cf3ceb438 Part of #260: Help ▸ Open Log Folder shows the log file in the file manager
The desktop app keeps logs/lightcraft.log in its settings folder (#286)
and a failed start names it (#370), but a user still had to find the
folder by hand. The host now hands the UI its log file (Services
.log_file) and Help ▸ Open Log Folder (app.openLogFolder) reveals it
through the existing reveal service: Finder and Explorer select the
file, Linux opens the folder. Off where no log is kept (the web,
--memory, LIGHTCRAFT_NO_PREFS). Translated in de, es, ja, pt-br, ru,
zh-hans and zh-hant; parity row MENU-HELP-LOGFOLDER; What's New and
README note it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 19:13:35 -05:00
BFlat bba4172f83
Merge pull request #413 from storytold/claude/integrate-batch-11
Integrate #407 (file dialogs off the UI thread) and #408 (macOS top-bar drag and zoom)
2026-10-09 07:06:20 +07:00
midasdf 93b900f8d7 M16: keep grapheme clusters intact in vertical watermarks 2026-10-09 09:02:24 +09:00
midasdf 0cb78071de M16: use paintable separators in localized UI text 2026-10-09 08:55:21 +09:00
Claude fec379db46
Russian for two strings the catalog lacked (colour label cleared, slideshow hint)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8
2026-10-08 23:47:41 +00:00
Claude 4d2f34fb35
Merge PR #408 2026-10-08 23:47:24 +00:00
Claude b306305472
Merge PR #407 2026-10-08 23:47:24 +00:00
BFlat 832b8ada51
Merge pull request #409 from storytold/claude/docs-374-nvidia-cache
Fix #374: troubleshooting for the NVIDIA shader-cache startup hang
2026-10-09 06:46:22 +07:00
Claude bf97105cf7
Fix #374: troubleshooting for the NVIDIA shader-cache startup hang
With Shader Cache Size disabled in NVIDIA Control Panel, the driver walks
the whole system drive inside D3D12CreateDevice (traced by the reporter
to NvMemMapStoragex.dll!TotalDiskUsage), before the window's first
frame; Driver Default fixes it (confirmed in #374, PhotoCraft too). The
launch-argument walk found on the way was fixed in #394.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8
2026-10-08 23:46:07 +00:00
Nathaniel Ledford eaaf859853
Parity: title-bar drag and zoom confirmed on a real macOS window
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:44:23 -04:00
Nathaniel Ledford 2bd13c1500
Parity: note the stale zoomed-state limitation of the title-bar toggle
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:42:52 -04:00
Nathaniel Ledford cc8d617459
Top bar: a press that starts on a button or the search field never drags the window
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:42:52 -04:00
ragtux d3ceaf0e79 Fix #191: commands' file dialogs run off the UI thread
The desktop showed rfd's synchronous dialogs on the UI thread, so the
window stopped answering the compositor while one was up: GNOME marked
LightCraft "not responding", the File menu stayed drawn and the control
channel went quiet. Services.picker lets the host start a dialog
elsewhere and answer through a channel; a command that needs a path
asks for one and returns, and runs again with the answer when the
dialog closes (pick.rs). Import Photos, Import from Folder, Open
Library, Import Lightroom Catalog, Find Missing Photos, the preset and
curve-preset imports and exports, Auto-Tag from Tracklog and Locate
Missing File use it; hosts without a picker (the web, tests) keep the
synchronous dialogs. ui.inspect lists the waiting commands as
fileDialogs. Same cause as storytold/photocraft#574.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 18:42:19 -05:00
BFlat 32cedb3153
Merge pull request #405 from storytold/claude/integrate-batch-10
Fix #310 (CR2/PEF starting look) and integrate #402 (menus stay below the menu bar)
2026-10-09 06:39:08 +07:00
Nathaniel Ledford 86d88de2ee
Parity: track title-bar drag and double-click zoom
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:37:55 -04:00
Nathaniel Ledford d01ebd7953
Top bar: drag to move and double-click to zoom the window (integrated title bar)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:37:05 -04:00
Nathaniel Ledford 54b037a90a
Headless host: record window commands and report the zoomed state back
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:37:05 -04:00
Nathaniel Ledford 1e27991cf1
Title bar: window-gesture policy (drag, double-click zoom, full-screen exempt)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 19:35:36 -04:00
Exalted5373 7173242ab5 LR-IMP-FORMATS: no overflow deciding whether to scale a full-size JPEG decode
A full-size load asks the decoder for the largest box (`SourceLevel::Full` is
`usize::MAX`, cast to `u32::MAX`). `jpeg::decode` then computed `2 * u32::MAX` to
decide on DCT scaling: an overflow panic in debug builds (caught, so every
full-size JPEG load failed with "decoder panicked"), and a wrap that happened to
give the right answer in release. The comparison saturates now, and the engine
converts its `usize` edge with `u32::try_from` instead of a truncating `as`.

Found decoding camera JPEGs (no JFIF/EXIF header) at full size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:26:29 -07:00
Exalted5373 31aa638383 LR-IMP-PROFILES: red / green / blue curves only with the master curve; neutral test values
Lightroom Classic reads `ToneCurvePV2012Red/Green/Blue` only together with
`ToneCurvePV2012`: a packet with a channel curve and no master curve leaves the
photo unchanged there (rendered on a chart: the channel curve alone has no
effect, with an identity master curve it applies). Imports now do the same.

The preset-packet test helper uses made-up as-shot values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:25:25 -07:00
Exalted5373 09d5284e5a LR-EDIT-OPTICS-PROFILE: a preset's LensProfileEnable=0 keeps embedded lens corrections
XMP presets usually say LensProfileEnable=0, which turned optics.lens_profile
off and with it the DNG-embedded WarpRectilinear / FixVignetteRadial
corrections (iPhone ProRAW and other files that carry them). Lightroom
applies a file's built-in corrections whatever that switch says (our
inference), and LightCraft's profile corrections are only those embedded
ones, so crs import now carries over only an enabling switch. The Enable
Lens Corrections checkbox and the amount sliders keep working as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:25:25 -07:00
Exalted5373 7e0250e11e LR-IMP-PROFILES: don't report preset bookkeeping fields as unmapped
XMP presets carry fields that describe the preset or the photo rather than
an adjustment (Cluster, SupportsAmount2, RequiresRGBTables, SortName,
Description, CropConstrainToWarp, OverrideLookVignette, AsShotTemperature /
AsShotTint). preset.import listed them as settings that couldn't be carried
over; so did an HDREditMode of 0 and PointColors slots that are all -1.
They are now treated as bookkeeping; an HDR edit, a used Point Color slot and
unknown adjustments are still reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:25:25 -07:00
Exalted5373 9087d3ad7f PSD: as_chunks for the palette and 16/32-bit plane loops (clippy 1.98)
clippy 1.98's manual_chunks lint fails `cargo xtask ci` on main at psd.rs:170/191/201
(chunks_exact with a constant size). The fixed-size chunks also drop the per-sample
indexing. No behaviour change; the codecs tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:25:17 -07:00
Claude a1e99fad9e
Follow-up to #402: the menu scroll arrows' accessibility labels are translated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8
2026-10-08 23:13:39 +00:00
Claude ff9d74f4e5
Merge PR #402 2026-10-08 23:13:27 +00:00
Claude 55ecd900ae
Fix #310: CR2 and PEF raws get the starting look fitted to their camera JPEG
CR2 and PEF decode without a camera colour matrix, like ARW, NEF, RW2,
RAF and CR3, but camera_preview::file_local_look (and the catalog's
relative white balance) left them out, so they rendered with the neutral
fallback matrix: the camera preview showed first, then a flat,
desaturated render replaced it. They now use the same guarded fit and
relative WB; a fit that fails the gates keeps the fallback, so a file can
only stay as it was or move closer to its camera JPEG. Not measured on
the corpus here (raw.pixls.us is blocked from this environment).
RENDER_CACHE_VERSION 15 re-renders cached CR2/PEF thumbnails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8
2026-10-08 23:13:16 +00:00
ragtux 2d47ba3207 Fix #189: in-window menus and submenus stay below the menu bar
egui keeps a popup inside the window, so a menu taller than the room
under the bar (Photo, on a short window) was slid up over the bar: the
titles vanished under it, and the pointer left on the title rested on
the first row and opened its submenu by itself. Every level now gets
the room it has below the bar (a submenu: from its row down, or up to
the bar when egui opens it upward) and scrolls inside it, with wheel,
drag and ▲/▼ strips that scroll while the pointer rests on them, as in
PhotoCraft's menu bar (storytold/photocraft#337). Menu levels and
submenu rows are registered for the control channel and tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 17:50:18 -05:00
BFlat 7b47ba7894
Merge pull request #401 from storytold/claude/integrate-batch-9
Header-only import probes (part of #367), PSD RLE allocation bounds, and #397 (CR3 C-RAW clipped highlights)
2026-10-09 05:48:39 +07:00
Nathaniel Ledford 826ba91075
#323: docs: measured drag times, the Before/After memory, what stays canvas-sized
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:48:20 -04:00
Nathaniel Ledford 22b7ba09b9
#323: stage budget: the open photo's views are cut only in a runaway; the shared source is reported
A review measured 1 GB of GPU stages for a Before/After at 1:1 on a 2800 px
canvas against a 400 MB budget, with nothing bounding it. The open photo's window
and before caches are now cut (the before side first) past four times the budget,
the whole-frame view's never; idle caches still go at the budget. The one shared
device copy of a big original is reported (sharedSourceBytes in the renderer's
memory report) and a misleading comment about it is corrected.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:48:19 -04:00
Nathaniel Ledford 057a8d308e
#323: the Before window waits for the original the After is decoding
At first open of Before/After the two window jobs were asked for together, each
decoded its own 24 MP copy of the original (a review saw two decodes and three
uploads for one photo) and the shared device copy was swapped between them. The
Before's window now waits until the After's job has handed the original to the
session (region::defer_before_window, Session media has_source); later windows
of both share the one copy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:38:39 -04:00
Claude 1b5ba5eba7
Merge PR #397 2026-10-08 22:34:54 +00:00
Nathaniel Ledford ddaea580a1
#323: test: holding \ in a wipe is tested with the key held, and the mutation fails it
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:34:02 -04:00
Nathaniel Ledford 03249f4619
#323: holding \ in a wipe shows the Before window everywhere
The window of the Before view alone was clipped to the wipe's left half while the
picture drawn was the Before on the whole canvas, leaving the right half the
low-resolution stand-in. The clip follows the effective mode.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:32:45 -04:00
Nathaniel Ledford 495b1ac9fb
#323: tests: the wipe layering and pane clipping are checked on the painted shapes
A review showed the wipe test asserted on a hand-written list of labels (deleting
the stand-in draw calls still passed) and nothing tested the clip at the call
site (replacing it with the canvas still passed). The tests now read the meshes
the frame painted: the Before window comes after the stand-in and stays inside
its side of the line, and side by side each window is painted inside its pane.
Both mutations of the code now fail them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:31:45 -04:00
Nathaniel Ledford f1a513ffe2
#323: docs: drag timings on two canvases, what a fit view decodes, the shared source
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 18:28:45 -04:00