Commit Graph
262 Commits
Author SHA1 Message Date
David Mann 673bfb4d9c Merge remote-tracking branch 'origin/main' into integration-batch-12
# Conflicts:
#	docs/file-format-parity.md
2026-11-02 20:15:23 +01:00
9034223c4b TIFF: open YCbCr images as RGB (#10316) (#10319)
* TIFF: open YCbCr images as RGB (#10316)

Scanners often write JPEG-compressed YCbCr TIFFs with 2x2 chroma
subsampling. The tiff crate decodes and upsamples them but returns raw
YCbCr samples, which the decoder rejected with "colour type YCbCr(8)".

The new tiff/ycbcr.rs converts them to RGB after decoding: JPEG data
uses the JFIF full-range BT.601 conversion (as libtiff does), other
compressions honour ReferenceBlackWhite and YCbCrCoefficients with the
TIFF defaults as fallback. 8 and 16-bit. YCbCr with extra samples, or
in other sample formats, fails with a clear unsupported error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: add Yuki-init's display name

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* TIFF YCbCr: test that YCbCrCoefficients set the luma weights

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* TIFF: YCbCr tags with the wrong value count use the defaults

tag_f64s now returns None unless the tag holds exactly n values, so a
YCbCrCoefficients or ReferenceBlackWhite tag with extra values falls
back to the TIFF defaults instead of being truncated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn

* TIFF YCbCr: tests for tiled JPEG with ICC, big-endian 16-bit and planar

Covers the layouts the review asked for: a tiled 4:2:0 JPEG file with an
embedded profile (checked against an independent JPEG decoder), a
big-endian 16-bit file, and planar data in both byte orders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn

* TIFF YCbCr: cite the formula sources and pin the green-channel choice

Documents where the conversion comes from: TIFF 6.0 Section 21
(YCbCrCoefficients, pp. 90-91) and libtiff's tif_color.c
(TIFFYCbCrToRGBInit, TIFFYCbCrtoRGB). Red and blue follow the spec;
green follows libtiff and adds Y unscaled, which matches the spec only
when the luma weights sum to 1. The module doc records this as a
deliberate compatibility choice, and a new test pins it: with weights
0.25/0.25/0.25, mid gray stays (128, 128, 128).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn

* Codecs README: YCbCr TIFFs with three 8- or 16-bit samples decode to RGB

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn

* Format tiff_ycbcr tests with rustfmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(tiff): compare grouped YCbCr decoding and update support notes

* style(tiff): align grouped decode call with test formatting

* style(tiff): apply repository rustfmt to grouped YCbCr regression

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
2026-11-02 19:31:22 +01:00
David MannandClaude Opus 5.5 f79a169651 Integration: one Actions row and the batch's event total in the file format parity page
The doc merge left five Actions rows that disagreed (version 12 unsupported vs read; 120 vs
127 events). Found by CodeRabbit on #10776.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:42:36 +01:00
David Mann 79a2a4e15f Merge PR #10632: Actions: map all 47 Filter Gallery effects (#10592)
With our fix-up 023e2662d7 on top of the author's head. Conflicts resolved item by item (Rust), docs as unions.
2026-11-02 03:18:45 +01:00
David Mann 520a996b30 Merge PR #10630: Actions: map Photoshop's Split Channels, Merge Spot Channel, Trap and Match Color steps (#10609)
With our fix-up a299bf9f6c on top of the author's head. Conflicts resolved item by item (Rust), docs as unions.
2026-11-02 03:15:28 +01:00
David Mann 496d9f3623 Merge PR #10618: Map Stylize and Pixelate action events
With our fix-up 52cc86351b on top of the author's head. Conflicts resolved item by item (Rust), docs as unions; docs/atn.md regenerated at the end.
2026-11-02 03:10:21 +01:00
David Mann 5d6041c1cd Merge PR #10628: Map selection, clipboard and layer-operation ATN events
With our fix-up 0e41091687 on top of the author's head. Conflicts resolved item by item (Rust), docs as unions; docs/atn.md regenerated at the end.
2026-11-02 02:55:08 +01:00
David Mann 4f899196cb Merge PR #10702: Actions: preserve settings in mapped ATN events
With our fix-up 78cf0cf91f on top of the author's head. Conflicts resolved item by item (Rust), docs as unions; docs/atn.md regenerated at the end.
2026-11-02 02:55:02 +01:00
David Mann d570b77abb Merge PR #10753: Support recorded layer, document and layer comp references
With our fix-up ea4112a4ce on top of the author's head 686f08c884. docs/atn.md kept from the batch (regenerated at the end); development.md and parity doc rows as unions.
2026-11-02 02:40:55 +01:00
David Mann 48b0e221cd Merge PR #10627: Actions: map Photoshop's newer-feature steps (Oil Paint, Smart Sharpen, Focus Area, Sky, Remove Background) (#10610)
With our fix-up 6ab24508d8 on top of the author's head 8988b6bfd0. Conflicts resolved: import lists as unions (bare_from/bare_to taken from steps_other, #10631), event table, tests and parity doc rows as unions.
2026-11-02 02:16:45 +01:00
David Mann 5bc852379a Merge PR #10743: Read Photoshop Actions version 12 descriptors
With our fix-up 1f524c378b on top of the author's head 713aa92ba5. Resolved with main: the version check sits in main's parse_layout (it merged cleanly); doc comments combined; atn_contract no longer expects version 12 to be refused and pins that an empty version 12 set parses; one ATTRIBUTION row for all ATN fixtures; the fixture README states which files were encoded how; development.md no longer counts the fixtures.
2026-11-02 02:13:56 +01:00
6ab24508d8 Integration: .atn Oil Paint/Smart Sharpen clamp on import, Smart Sharpen maps the Gaussian form (#10627)
Out-of-range Oil Paint and Smart Sharpen settings kept the step as a
Photoshop step; the reference application clamps them when the step
plays, so the import now clamps (stylization 10.5 -> 10, Amnt 500.5 % ->
500, Rds 0.05 px -> 0.1). Export still refuses out-of-range params.

Oil Paint's light direction (LghD) had no range: LghD 500 mapped and
saved back as 500. It now clamps to the command's -180..180 on import
(500 -> 180) and export refuses {"angle": 181}.

Smart Sharpen mapped the legacy Lens Blur form, which the command's
Gaussian sharpen does not play, and wrote every step as legacy Lens
Blur. It now follows the PSD smart-filter mapping (photocraft-io
smart_map): only useLegacy false + blur GsnB maps (noiseReduction ->
reduceNoise); the reference default (useLegacy true, lensBlur), Motion
Blur and legacy steps stay Photoshop steps; export writes useLegacy
false, Amnt, Rds, noiseReduction, blur GsnB.

Co-authored-by: hectorviov <1501713+hectorviov@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 02:13:01 +01:00
David Mann cafaabcf04 Merge PR #10631: Actions: map Photoshop's De-Interlace, NTSC, HSB/HSL, Custom, Average and matting steps (#10607)
With our fix-up 632a62b554 on top of the author's head 4ed3f5b591. Conflicts resolved as unions (module list, event table, tests, parity doc rows).
2026-11-02 02:03:24 +01:00
David Mann 2d332d3ba5 Merge PR #10629: Actions: map Photoshop's Distort filter steps (Pinch, Polar Coordinates, Spherize, Twirl, Wave, ZigZag) (#10605)
With our fix-up 363e0f5e89 on top of the author's head 244082fb2c. Conflicts with main resolved as unions (new tests next to main's; parity doc revision rows).
2026-11-02 02:02:03 +01:00
yoriswind 35850ca7db Merge original ATN reference documentation from #10603 2026-11-01 13:23:37 -08:00
yoriswind 21b6546907 Resolve recorded Action reference forms at playback 2026-11-01 12:55:02 -08:00
yoriswind 7ca16e9eba Read Photoshop Actions version 12 descriptors 2026-11-01 11:45:32 -08:00
yoriswind 2703d88a35 Document preserved settings in mapped ATN events
Build on davidmann4's ATN reference in #10603 and move the 22 repaired settings out of its gap table.
2026-11-01 09:08:58 -08:00
yoriswind 036d37f90d Clarify current and historical ATN documentation counts 2026-10-31 23:07:10 -07:00
yoriswind 0a605880dd Separate disabled ATN steps from supported Render counts 2026-10-31 21:11:28 -07:00
yoriswind d55830de94 Preserve noncanonical Group F descriptor headers 2026-10-31 20:57:09 -07:00
Hector VillarrealandClaude Opus 5.5 5a4bd379d0 Actions: map all 47 Filter Gallery effects (#10592)
Filter Gallery steps (GEfc with the effect in GEfk, or the effect's own
event) map every effect to filter.gallery.<effect>, not only Spatter:
each key in recorded order, out-of-range values clamped and missing
keys given Photoshop's defaults, enumerations, Invert and Neon Glow's
colour mapped both ways. The table is generated from the event
reference's Group A; every integer range and default matches the
effects'. Glass maps the Frosted and Canvas textures the reference
gives codes for. A setting the event cannot hold refuses the step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 21:44:27 -06:00
yoriswind 815f5bdad0 Preserve measured Trace levels through playback and save 2026-10-31 20:41:15 -07:00
Hector VillarrealandClaude Opus 5.5 4a6883eede Actions: map Photoshop's Video, Other, Average and matting steps (#10607)
De-Interlace (Dntr), NTSC Colors (NTSC), HSB/HSL (HsbP), Custom (Cstm),
Average (Avrg) and Remove Black / White Matte (RmvB/RmvW) load as their
commands, play, and save back with the same keys. Missing keys take
Photoshop's defaults; a Custom matrix that is not 5 x 5 keeps the
Photoshop step. Replace Color and the direct Gradient Map (GrMp) are
still kept verbatim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 21:29:26 -06:00
Hector VillarrealandClaude Opus 5.5 36c90925e9 Actions: map Photoshop's channel and colour steps (#10609)
Split Channels (SplC), Merge Spot Channel (MSpt), Trap (Trap) and Match
Color without a source (matchColor, noReference) load as channel.split,
channel.mergeSpot, image.trap and image.adjustments.matchColor and save
back with the keys Photoshop records. The split's recorded documentIDs
belong to its run and are neither replayed nor written; Trap's width is
clamped to 32767 px; Match Color takes Photoshop's defaults. Steps the
events cannot carry (a split keeping its original, a named spot
channel, a Match Color source or option) are refused on export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 21:15:26 -06:00
Hector VillarrealandClaude Opus 5.5 a03120e8b4 Actions: map Photoshop's Distort filter steps (#10605)
Pinch, Polar Coordinates, Spherize, Twirl, Wave and ZigZag steps load
as filter.distort.*, play, and save back with every key in recorded
order. Out-of-range values are clamped as Photoshop clamps them and
missing keys take Photoshop's defaults (Wave's undefined areas are
Repeat Edge Pixels). A Wave scaled below 100 % stays a Photoshop step,
as the command has no scale. Shear is still kept verbatim: its curve
points need a step recorded through its dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 21:04:42 -06:00
yoriswind ec44d1711f Map ATN selection and layer-operation events 2026-10-31 19:59:52 -07:00
yoriswind 34ba5d0122 Preserve duplicate Render descriptor keys and correct ATN docs 2026-10-31 19:56:58 -07:00
Hector VillarrealandClaude Opus 5.5 1d22ffc1ff Actions: map Photoshop's newer-feature steps (#10610)
Oil Paint (oilPaint), Smart Sharpen (smartSharpen), Focus Area
(focusMask), Select Sky (selectSky) and Remove Background
(removeBackground), recorded by string ID, load as their commands and
save back with the keys and defaults Photoshop records. Oil Paint's and
Select Sky's Photoshop defaults are written out where they differ from
the commands'. Smart Sharpen maps the legacy Lens Blur form with no
noise reduction; other forms stay Photoshop steps. Settings the events
cannot carry refuse the step on export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 20:51:05 -06:00
yoriswind 53098879c0 Correct ATN mapping table and current parity notes 2026-10-31 19:42:20 -07:00
David MannandClaude Opus 5.5 b408d4166d Docs: .atn event reference with the supported events and measured specs of unmapped ones
docs/atn.md lists the 117 events PhotoCraft maps today and, for 101 events it does
not map yet, every key the step carries in recorded order, with type, unit, factory
default, exact range and accepted enum values, measured in the reference application.
An implementation needs no further checks there. Linked from file-format-parity.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 02:17:06 +01:00
David Mann b2db24400e Merge main at b1cfff9d3 into integration batch 10
Conflicts resolved as unions of both sides: codecs re-exports (PngRows + TiffBands), smart_cmds source imports
(main's source_surface_from_buffer and cache API with #8571's svg_source_image_in/convert_svg_source; main's
duplicate rendering import dropped), io flat.rs test modules (#8536's banded TIFF tests and main's PNG ones),
menus/invoke.rs (#8571's smart SVG intercept and main's layer.selectUnderCursor), state.rs (#8311's
type_box_overflow and main's type_insertion_style), the canvas_geom test keeps the is_finite guard, docs
status lines keep both change lists, i18n catalogs keep both sides' rows (hi.tsv: main's wording where both
added the same string).
2026-10-30 14:28:02 +01:00
FredApps 63637c4d80 Merge current main into trimmed integration, preserving exclusions and interpolation behavior 2026-10-29 21:31:18 +01:00
David Mann a3f8ef4816 Merge PR #8536: TIFF: images over 2^30 px open, decoded a group of rows at a time into the layer (#8169)
# Conflicts:
#	docs/file-format-parity.md
2026-10-29 21:06:41 +01:00
David MannandClaude Opus 5.5 fefd90d576 Merge remote-tracking branch 'fork/integration-batch-10' into HEAD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:16:12 +01:00
FredApps 255ecc81d0 Remove 21 requested PR contributions from the 108-PR integration
Retain 87 PRs. Reconcile overlapping integration fixes and update testing scope.
Removed: #7153 #7742 #5493 #9282 #3455 #9172 #3139 #3967 #4783 #5453 #8347 #1991 #3345 #4042 #4305 #4883 #4890 #5090 #6621 #5870 #5939.

Combined CI pending for this source; historical portable artifact is not applicable.
2026-10-29 18:49:17 +01:00
Khawar Zamman Wani a24e155a6f Merge upstream main into large TIFF fix 2026-10-29 22:39:27 +05:30
David Mann afacb057f7 Merge origin/main into pr-8571-fixup
Conflicts: svg.rs (main's bufread inflate and shared render helper, kept
with the PR's bounded raster path), psd_import.rs (the PR's vector
preview moved into main's smart_content), menus/invoke.rs (the SVG
intercept moved into main's split invoke_unguarded), rendering.rs and
the ui-egui import lists (main's explicit imports), Cargo.lock, docs
status lines (unions).
2026-10-29 16:38:24 +01:00
FredApps fd3a12dfde Merge approved PhotoCraft PR #3142: Read applied Sony RAW metadata and crop ILCE-6000 images
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Integrate bounded Sony SR2 metadata decoding and ILCE-6000 image area; preserve newer bit-depth-aware camera profile application and explicit file crop precedence. Keep current parity counts and original metadata/crop tests.
2026-10-29 06:38:44 +01:00
FredApps c81347aaa8 Merge approved PhotoCraft PR #5493: Import Photoshop custom shape sets into the Shapes panel
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Integrated bounded atomic CSH set parsing, unique shape/group naming and native Shapes panel import with inline-data authorization guards; preserved duplicate-name, inner-hole, malformed-second-record and preferences-reload regressions. Combined independent catalog additions and retained current parity metadata.
2026-10-29 05:47:45 +01:00
Khawar Zamman Wani 64422e7ef1 Merge main into save-for-web-webp 2026-10-28 21:09:35 +05:30
Khawar Zamman Wani 0ce7991aaa Merge origin/main into fix/8169-huge-tiff-open 2026-10-28 09:22:54 +05:30
David Mann 63e2c7d100 Merge PR #9031: fix(io): preserve Halftone Pattern smart filters in PSD/PSB
# Conflicts:
#	docs/file-format-parity.md
#	docs/gaps.md
2026-10-27 02:23:29 +01:00
714b8f304d Integration: the reference application's Halftone Pattern keys HlSz/ScrT (#9031)
The PR read and wrote Halftone Pattern as `Sz  ` and `Ptrn` (enum `HlfT`:
`Dt  `/`Crc `/`Ln  `). The reference application's Filter Gallery uses `HlSz`
for the size and a `ScrT` enum (`ScrD` dot, `ScrC` circle, `ScrL` line), so a
Halftone Pattern saved there still opened as an opaque filter, and one we saved
lost its size and pattern there without a warning. The tests built their fixture
with the same keys as the code, so they passed either way.

Now the keys match, a default Halftone Pattern (HlSz 1, Cntr 5, ScrD) opens as
{size 1, contrast 5, dot} (fails before this commit), and descriptors with the
old keys stay verbatim. The docs no longer claim reopen checks in the reference
application.

Co-authored-by: denstu473 <63150090+denstu473@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 02:20:49 +01:00
Don Omondi c129dd50e0 Merge main and preserve original-format embedded vector save-back 2026-10-27 00:45:48 +03:00
jonathanwxh-cell 059940c993 Merge upstream main into the CSH shape import branch
Keep the custom-shape translations and the CSH import notes with main's newer format and gap status.
2026-10-26 09:50:13 +00:00
Khawar Zamman Wani 6fc599dea9 Merge origin/main into save-for-web-webp 2026-10-26 10:20:32 +05:30
Khawar Zamman Wani cdc3bdbd2f Merge origin/main into fix/8169-huge-tiff-open 2026-10-26 10:20:12 +05:30
Khawar Zamman Wani 08909ac143 Merge origin/main into save-for-web-webp 2026-10-25 21:25:58 +05:30
David MannandClaude Opus 5.5 38609e5615 Merge PR #8885: PSD: spot channels in Photoshop's polarity; PSDs from earlier PhotoCraft versions keep their ink
Merged with our fix-up branch pr-8885-fixup (8f6863f53) on the author's head 996b55eb4.

Conflicts resolved:
- crates/io/src/tiff_layers.rs: #9148's tiff_source (an empty LMsk gets Photoshop's 14 bytes)
  gives way to #8885's tiff_image_source, which writes the same bytes for an empty or short
  LMsk; #9148's test stays.
- crates/io/src/flat.rs: #8776's DDS alpha step and #8885's TIFF channel stamp both run.
- crates/io/Cargo.toml, Cargo.lock: #8402's zune dev-deps and #8885's tiff dev-dep.
- crates/io/tests/it/tiff_layers.rs, docs: unions; docs/scorecard.md kept as is, regenerated at
  the batch gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 16:28:00 +01:00