Commit Graph
8 Commits
Author SHA1 Message Date
FredApps 094c4f30e4 CMS tests: validate profile-specific CMYK black endpoints (#3890)
Retain the relative paper-white requirement and round-trip checks while validating finite, bounded endpoints and darker full-K ink.

Add an encoded and reparsed AToB1 regression with an independently calculated 100/87/74/61/48 lightness ramp, plus invalid endpoint cases.

Signed-off-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-10-12 09:43:34 -04:00
bfbc9903d5 cms: accept ICC DeviceLinks whose output isn't a 3-channel PCS (#2348)
A DeviceLink's header PCS field holds its output colour space
(ICC.1:2010 §7.2.7), so a CMYK→CMYK link has a 4→4 AToB0. The LUT
channel check hard-coded 3 outputs and rejected such files as invalid,
so users were told a well-formed profile was corrupt and never reached
the "DeviceLink profiles cannot be used" error.

Check DeviceLink LUTs against the header's output space instead, and
only let a Lab DeviceLink through link_stages when its tables end in
3 channels, so a Lab→CMYK link gets the unsupported error rather than
building a mismatched transform.

Fixes #2337


Claude-Session: https://claude.ai/code/session_01X5k8jSoLtGswanmHBipHER

Co-authored-by: Leel Wasanatha <260480244+kavishkashehan726-sudo@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 13:16:32 -04:00
4860cef703 Absolute colorimetric refuses a zero or non-finite media white (#972) (#1125)
connection() scaled the PCS by src.media_white() / dst.media_white() with
no check on the divisor, so a v4 profile whose wtpt tag holds zeros (parsed
and stored verbatim) gave a NaN scale, and every colour through a direct
absolute transform or a paper-simulating proof came out NaN. The transform
is now refused with CmsError::Invalid when either white has a zero,
negative or non-finite component; the other intents never divide by it and
are unchanged.

Co-authored-by: wstock <1394687+wstock@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 15:41:32 -04:00
ljkxandClaude Opus 5.5 d2576b27eb Profile mismatch: compare profiles by colour, not bytes (#394)
Opening any file Photoshop tagged with sRGB IEC61966-2.1 asked
"Embedded Profile Mismatch: sRGB IEC61966-2.1 vs sRGB IEC61966-2.1":
open_policy compared a hash of the ICC bytes, and Photoshop's v2 profile
(1024-entry tables) and the built-in v4 sRGB (parametric curves) are the
same colours in different bytes. 32-bit documents in Photoshop's linear
sRGB missed the stay-linear exception for the same reason.

Add Profile::same_colors: same colour space and every sample of a device
grid within dE76 0.5 through both (re-encoding costs 0.025; moving the
red primary 2% costs 1.0). Colours are compared rather than round-tripped
because CMYK -> PCS -> CMYK is not an identity even for one profile.

Of the 75 profile-tagged PSDs in the test corpora, all 75 prompted on
open; now 6 do (Adobe RGB, Gray Gamma 2.2, SWOP), each a real mismatch.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:43:18 +07:00
Brandon ThomasandClaude Opus 5.5 48d1a4f9e5 Never crash: cms is panic-free (Rule 9) (#36)
- Real crash: a gray ICC profile whose A2B0 tag is stored as "mBA "
  parsed fine, but re-encoding its RGB view (gray_as_rgb, used for gray
  documents' composites) hit panic!("unsupported lutAtoB stage layout").
  The ICC writer now leaves out a LUT its tag type can't store, and
  gray_as_rgb drops the gray LUTs (one input channel) so the RGB view is
  the matrix/TRC model it builds. Regression test
  gray_profile_with_reversed_lut_type_reencodes.
- math::rgb_to_xyz_matrix returns None for dependent primaries.
- Builtin::profile indexes its cache by discriminant (tested); the shipped
  CMYK profile falls back to synth::coated_cmyk() instead of expect.
- Two constant-only expects (Bradford inverse, built-in primaries) use the
  documented narrow allow.
- cms denies unwrap/expect/panic/unimplemented/todo/unreachable.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:25:31 -04:00
Brandon ThomasandClaude Opus 5.5 f7eb6ea9e7 Format: adopt the craft-family rustfmt.toml and format the workspace
CI's `cargo fmt --all -- --check` has failed on every run because the
repo had no rustfmt config and was never formatted. Use the same settings
as EffectCraft/FilmCraft (max_width 160, use_small_heuristics Max), which
also keeps the churn small. Formatting only; no code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:31:17 -04:00
7cb26e4f7f cms tests: system_profiles skips malformed named-colour profiles (#24)
On Debian/Ubuntu with colord installed, system_profiles panics on
/usr/share/color/icc/colord/x11-colors.icc ("unsupported ICC feature:
curve type \0\1\0\0"). That profile is a named-colour (nmcl) profile
whose B2A0 lutBToAType is spec-invalid: inputs=3, but the M-curve
offset (32) leaves room for one curve before the matrix offset (48),
and the 48-byte matrix overlaps the B curves at 64. The parser reads
the second M curve at offset 48 and correctly rejects it. Named-colour
profiles are never used for conversions (the test already skips them
after parsing), so skip them when they fail to parse instead of failing
the suite on a host file.

Co-authored-by: storybored379 <storybored379@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 10:13:14 -04:00
Brandon Thomas 536a7346fb more algorithms, progress 2026-10-01 08:25:06 -04:00