Commit Graph
8 Commits
Author SHA1 Message Date
aiongg a44a2eeb1d Merge track r1-ui into next
docs/whats-new.md: kept both tracks' entries, newest first, one 2026-10-18 heading.
2026-10-21 14:54:06 +00:00
aiongg 1a4d81fd5a Merge PR #2180: raw, codecs: checked dimension products so wasm32 cannot wrap the size gates (#2138) 2026-10-21 14:49:01 +00:00
aiongg a4cbdb4937 Merge PR #2012: Detail: Fit is as sharp as the photo 2026-10-21 14:48:42 +00:00
Alex Chambers 43a47e5a3b Issue #1952: clip non-finite float image samples safely (#2071) 2026-10-17 18:40:14 -06:00
eliets2 36d22a2745 raw, codecs: checked dimension products so wasm32 cannot wrap the size gates (#2138)
On wasm32 usize is 32-bit, so 65536 x 65536 wraps to 0 and products like w * h,
w * h * cpp, fw * fh * nc and row_bytes * ch wrapped past their own validation and let
later true-dimension indexing panic (profile.web sets panic = abort). All the enumerated
sites now validate through a checked u64 gate:

- lightcraft-raw gains checked_pixel_count(width, height) (u64, capped at MAX_SAMPLES),
  used by the ARW decode head (the strip-length equality now compares the true sample
  count, not a wrapped one) and by RawImage::check's data-length validation;
- the CR2 lossless-JPEG frame size is checked in u64 on both the Full and Header paths
  (it used to be clamped AFTER wrapping), and the no-slices width fallback is checked;
- the TIFF DEFLATE chunk's inflate length is checked and capped before the cast;
- lightcraft-codecs gains checked_sample_buf_len for the finish() buffer bound, compared
  in u64 via try_from so no cast truncates on 32-bit.

Tests pin the gate arithmetic with values that would wrap 32-bit usize (65536 x 65536,
u32::MAX x 2, 2^30 x 4). cargo check --target wasm32-unknown-unknown passes for both
crates. The issue's suggested wasm32 arithmetic-side-effects clippy pass is a follow-up.
2026-10-17 22:20:48 +03:00
ubergenericandClaude Opus 5.5 7db0a64d7e Detail: Fit is as sharp as the photo (display fit, whole-pixel draw, Lanczos decode)
At Fit the loupe was softer than a good downscale of the same file. Four
resamples stacked up between the source and the screen:

- the render edge is rounded up to a 64 px step, so the texture was drawn up
  to ~6 % smaller than its size and the GPU shrank it with 2-tap bilinear
  sampling;
- the fitted texture sat on a fractional pixel position, so even at the right
  size every screen pixel was averaged with its neighbour (#1831 fixed the
  same for 100 %);
- the render box truncated its short side (2560 x 1706 for a 2560 x 1707
  source), a slightly anisotropic resample that blurred one axis only;
- the codec's decode-time shrink at 2:1 and more, and SourceRef::Fit, used a
  box filter, which halves the contrast of detail near the output's limit.

RenderJob::display_fit shrinks a full-quality render that is larger than its
drawn size to exactly that size with Lanczos-3 on the worker (after the caches
have the full render; drafts untouched; part of the key). The Detail view sets
it for the After and Before renders at rest, and snap_fit_rect draws a texture
that is its drawn size on whole physical pixels. The render boxes round their
short side, and the 2:1-and-more shrinks use Lanczos-3.

Refs #1472, #1042.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:28:12 +11:00
Brandon ThomasandClaude Opus 5.5 a8c3f01e1e CI: clean under clippy 1.99 (as_chunks for constant chunk sizes, ? in export resize parsing)
Rust 1.99 (stable since 2026-09-28) adds clippy::chunks_exact_to_as_chunks and widens
clippy::question_mark, which failed `cargo xtask ci` on main. Same behaviour: the
remainder that chunks_exact skipped is the remainder as_chunks returns separately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:53:43 -04:00
Brandon ThomasandClaude Opus 5.5 304180a500 M1.1: lightcraft-codecs decode/encode, ICC, sniffing
Decoders (JPEG via zune-jpeg + jpeg-decoder for DCT scaling/CMYK, PNG,
TIFF, WebP, GIF, BMP, PSD composite, JPEG XL via jxl-oxide) produce linear
Rgb32f in source primaries with SourceSpace; ICC matrix/TRC applied exactly,
LUT/CMYK profiles through moxcms; to_working() to linear Rec.2020 D65.
Encoders: JPEG, PNG 8/16, TIFF 8/16/32f, lossless WebP, AVIF (native).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:30:26 -04:00