Resolutions: CLI usage, flag lists and flag parsing carry both --tiff-compression (t15) and
--jpeg-format (t16); file.saveACopy, batch, imageProcessor and layersToFiles param specs carry
both tiffCompression and jpegFormat; file_cmds keeps tiff_compression_param and
jpeg_format_param; atn_cmds keeps flag_set/applies_at_canvas_bounds (t15) and UNHOLDABLE (t16),
edit.transform uses the pixel_target guard (t15) with layer_ref(p)? (t16); ui-egui open paths
build ImportOptions (t16) and apply raw_defaults (t15); docs headers/rows unioned; atn tests keep
both sides; tr.tsv "Keep Using CPU" kept once.
crates/ui-egui/src/lib.rs: replay_save doc comment names both Export As and JPEG; replay_save uses the PR's FormatChoices::from_step, after main's export_dialog::replay branch.
docs/file-format-parity.md: header keeps main's text plus the JPEG Options item (last updated 2026-10-19); TIFF row is main's, JPEG row is the PR's; change-log rows once each, newest first.
docs/gaps.md: header keeps main's text plus the G10 item (last updated 2026-10-19).
apps/photocraft/src/services.rs: SAVE_FILTERS keeps the DDS entry from main and the PR's Cineon entry.
crates/codecs/README.md: Cineon table row from the PR (read and write), then main's DICOM and Amiga IFF rows.
crates/codecs/src/format.rs: caps keep the PR's Cineon (read and write) and main's Dicom and Iff rows.
crates/codecs/src/lib.rs: encode keeps the PR's Cineon arm and main's Dicom and Iff arms.
docs/file-format-parity.md: header kept from main with the Cineon write item added; Cineon / DPX row from the PR, DICOM row from main; the PR's change-log line added once at the top.
docs/gaps.md: header kept from main with the Cineon write item added; Missing list without 'Cineon write'; the PR's Cineon progress line replaces main's read-only one; the PR's change-log line added once at the top.
apps/photocraft-web/src/web.rs: OPEN_EXTS kept main's list (with the DICOM extensions) and added iff, lbm, ilbm.
apps/photocraft/src/services.rs: OPEN_EXTS kept main's list (with the DICOM extensions) and added iff, lbm, ilbm.
crates/codecs/README.md: kept both the DICOM and the Amiga IFF table row and section.
crates/codecs/src/format.rs: kept both the Dicom and the Iff variants in every match, detect runs the DICOM check then the IFF check, Format::ALL length re-counted (22).
crates/codecs/src/lib.rs: one use line importing dicom and iff; both decode and encode arms kept.
docs/gaps.md: header line kept from main, with the PR's 'Cineon and Amiga IFF read' wording.
crates/engine/src/file_cmds/tests.rs: both sides' appended tests kept whole.
docs/file-format-parity.md: header line keeps ours plus the PR's change item, date 2026-10-18; TIFF row has both notes; change-log rows kept both, newest first.
apps/photocraft-web/src/web.rs: OPEN_EXTS kept main's list and added dcm, dicom, dc3 after cin.
apps/photocraft/src/services.rs: OPEN_EXTS kept main's list and added dcm, dicom, dc3 after cin.
PhotoCraft reads GIMP's .xcf (and .xcf.gz) files, read only, through a new
reader in photocraft-io written from the public XCF specification: versions
0 to 26, uncompressed, RLE and zlib tiles, 8/16/32-bit integer and
16/32/64-bit float precisions (linear precisions get a linear profile),
pixel layers at any position, groups by item path with pass-through,
layer masks applied or disabled, opacity, visibility, locks, colour tags,
the 2.10 and legacy blend modes mapped to Photoshop's (modes without an
equivalent open as Normal with a note), the ICC profile, resolution,
guides, the comment, extra channels and the saved selection; indexed
images open as RGB. Text, vector and link layers open as their pixels;
layer effects, paths and floating selections are reported.
Fixtures are written by GIMP 3.2 itself (scripts/xcf_fixtures.py), each
with GIMP's merged rendering as a PNG. In gamma-encoded blend and
composite spaces our composite matches GIMP within 0.5/255; GIMP's
linear-light default, its Clip to backdrop and its clamp-after-alpha
for unbounded modes are documented and measured in docs/xcf.md.
docs/scorecard.md regenerated with cargo xtask scorecard (24 of 172); the
Preferences test keeps main's Enhanced Controls rows and the demosaic row;
catalog tails keep both sides.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts only in the parity docs: status lines take main's text with the
JPEG Options entry (FILE-215-19) on top; scorecard takes main's rows with
FILE-215-19 done and File compatibility 10 / 12 / 5.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run_pairs_params_with_the_preceding_cmd counted the named layers, which
a naive zip of params[i] to cmd[i] also passes. Assert which layer
carries each name, so only pairing each --params with the --cmd before
it passes.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
`commands --help` also exits 0 with output and empty stderr when it
runs, so the help test could not tell help from execution; assert the
command list (`file.new`) is absent from help output.
Pin that a `--cmd` without `--params` gets its own default: `First` and
`Third` must each appear exactly once, so a neighbour's params leaking
onto the middle command fails. Also assert exit 0 in the reversed-order
repeated-flag case and explain the layer count.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Add in-process tests for the current hand-written parser so the module
split and the clap port can prove they keep behaviour: top-level
help/version/no-args dispatch, `<sub> --help`/`-h` for all eight
subcommands (returns on stdout, nothing runs), unknown flags on every
subcommand (exit 2, flag named on stderr), `--flag=value`, bare flag
given a value, value flag missing its value, last-wins for repeated
value flags, and `run` pairing each `--params` with its preceding
`--cmd`.
Assertions use exit codes, which stream got output and the offending
flag name, not full help or error wording, so they survive clap's
different messages.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
The OS clipboard read (arboard, plus decoding a copied file with
photocraft-codecs) and write now run under crash_guard::guard, like Open
and Export. A panic there becomes the paste's error in the status bar and
the app keeps its documents, instead of closing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>