Commit Graph
332 Commits
Author SHA1 Message Date
aiongg 4d1b922ddf Integration: track t02
# Conflicts:
#	contributors/people.toml
#	crates/engine/src/file_cmds/tests.rs
#	crates/engine/src/print_cmds/tests.rs
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
2026-10-22 15:38:14 +00:00
aiongg 82cf3c828c Integration: track t01
# Conflicts:
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	docs/file-format-parity.md
#	docs/gaps.md
2026-10-22 15:38:14 +00:00
aiongg 0e80156397 Integration: track t16
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.
2026-10-22 15:38:13 +00:00
aiongg 3d1a4d6679 Integration: track t15
# Conflicts:
#	crates/engine/src/atn_cmds/tests.rs
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	docs/file-format-parity.md
#	docs/ui-parity.md
2026-10-22 15:38:12 +00:00
aiongg 1033aab750 Integration: cargo fmt 2026-10-22 02:56:39 +00:00
aiongg 882cbe1c2c Merge PR #7240: Save As on Linux: the one file type offered gives the name its extension 2026-10-22 02:36:51 +00:00
aiongg dfde38919e Merge PR #7883: Save As JPEG: JPEG Options dialog (quality 0–12, Baseline / Optimized / Progressive) (FILE-215-19)
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).
2026-10-22 02:27:46 +00:00
aiongg 7a25b3f38b Merge PR #7099: test(cli): pin photocraft-cli argument parsing before the clap port (#7071) 2026-10-22 02:27:40 +00:00
aiongg a77b078589 Merge PR #7417: Camera Raw: choose the demosaic method when a raw opens
crates/io/src/lib.rs: kept main's import_psd (and its call in import_stages); import_stages takes the PR's ImportOptions argument.
crates/io/src/raw.rs: the PR's demosaic summary on main's developed_document(name, bytes, ...) call.
docs/scorecard.md: ours (regenerated at combine).
2026-10-22 02:25:41 +00:00
aiongg 28a1ee7b6e Merge PR #6468: fix(photocraft): --control 0 logs the port actually bound (#6427) 2026-10-22 02:24:53 +00:00
aiongg f271b0e07d Merge PR #7051: Save: ask before replacing a file that an added or lowercased extension names 2026-10-22 02:24:07 +00:00
aiongg 3db9314ca2 Merge PR #6265: Codecs: save Cineon (.cin) film frames
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.
2026-10-22 02:24:03 +00:00
aiongg 1398aaadff Merge PR #8107: Open/Save: refuse file names that aren't valid Unicode instead of rewriting them (#6601) 2026-10-22 02:23:25 +00:00
aiongg 96cce9b2f9 Merge PR #4713: Codecs: open Amiga IFF/ILBM bitmaps read-only
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.
2026-10-22 02:22:54 +00:00
aiongg 2bf3e4e0be Merge PR #5470: feat(tiff): a tiffCompression option for scripted TIFF saves
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.
2026-10-22 02:22:15 +00:00
aiongg 7b50fbd796 Merge PR #4315: Codecs: open uncompressed DICOM single-frame images (#1048)
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.
2026-10-22 02:21:52 +00:00
aiongg f32f882f3a Merge main into integration-10
# Conflicts:
#	apps/photocraft-web/src/web.rs
#	apps/photocraft/src/services.rs
#	crates/engine/src/file_cmds/tests.rs
#	crates/engine/src/float_cmds.rs
#	crates/engine/src/float_cmds/tests.rs
#	xtask/src/corpus.rs
#	xtask/src/corpus_pins.rs
#	xtask/src/main.rs
2026-10-21 21:56:26 +00:00
aiongg e4a413241a Merge PR #8004: Windows on ARM: auto picks DirectX 12 for Qualcomm graphics (#7537) 2026-10-21 21:56:21 +00:00
aiongg 7b81efddcb Merge PR #5436: IO: open .psd through the PSD reader, not codecs (#5258) 2026-10-21 21:56:21 +00:00
aiongg f3c20b9242 Merge PR #7626: Flatpak: a second launch hands its files to the running PhotoCraft over a Unix socket (#1540) 2026-10-21 21:56:10 +00:00
aiongg 419f6ef4c7 Merge PR #6910: Web: one press per tap, so menus open again on touch (#2095) 2026-10-21 21:55:49 +00:00
skylar taylor-barrick 6d8cbac7dc Merge pull request #2945 from diegochagas/feat/xcf-read
Open GIMP XCF files: layers, groups, masks, blend modes, channels and selection
2026-10-21 14:35:32 -06:00
Diego Chagas ca18689304 Open GIMP XCF files: layers, groups, masks, modes, channels and selection (#1076)
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.
2026-10-21 16:57:22 -03:00
UnemarsandClaude Opus 5.5 eca10449ce Merge origin/main into raw-demosaic-choice
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>
2026-10-21 20:18:37 +02:00
aiongg 54229918c9 Merge PR #7271: macOS: keep the bundle's Dock icon after the window opens 2026-10-21 18:15:07 +00:00
aiongg 94d28535d3 Merge PR #6464: Survive a lost window GPU device: draw nothing, save unsaved work for recovery, close (#3438, #1215) 2026-10-21 18:15:02 +00:00
Higgs32584andClaude Opus 5.5 f916c98536 Merge upstream/main into revive/4330-jpeg-options
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>
2026-10-21 12:56:32 -04:00
IvanandClaude Opus 5.5 8d6cc319b8 test(cli): pin --params order against positional pairing (#7071)
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>
2026-10-21 19:08:51 +03:00
IvanandClaude Sonnet 5.5 2e119be390 test(cli): tighten help and --cmd/--params pinning (#7071)
`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>
2026-10-21 19:08:51 +03:00
IvanandClaude Sonnet 5.5 2ab2de8efa test(cli): pin argument-parsing behaviour before the clap port (#7071)
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>
2026-10-21 19:08:41 +03:00
aiongg 77557d75f1 Merge PR #8229: Integration batch: 8 PRs on main
# Conflicts:
#	crates/engine/src/layer_style.rs
#	crates/io/src/psd_export.rs
#	crates/io/src/smart_map.rs
#	docs/file-format-parity.md
2026-10-21 15:45:07 +00:00
Branch Sync 960d927a37 Merge remote-tracking branch 'refs/remotes/upstream/main' into HEAD 2026-10-21 11:18:25 -04:00
Branch Sync 643c9b7044 Merge remote-tracking branch 'refs/remotes/upstream/main' into HEAD 2026-10-21 11:15:30 -04:00
f5543e85fc Integration: merge main, resolve conflicts (#5407)
main added the GPU adapter strings (#1885) at the end of every
translation table, where this PR adds the Color Table strings. Both
blocks are kept.

Co-authored-by: abdul-karim-mia <97598943+abdul-karim-mia@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:23:09 +02:00
aiongg de03dd43f1 Merge PR #6861: CLI batch: skip shell-only Save and view steps inside played action sets (#6860) 2026-10-21 05:04:01 +00:00
zuujiscom 32a2faa7c3 Open/Save: refuse file names that aren't valid Unicode instead of rewriting them (#6601) 2026-10-21 07:30:42 +05:30
Higgs32584andClaude Opus 5.5 576b7cdfcb Merge upstream main into fix/2095-android-menus
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:19:22 -04:00
Higgs32584andClaude Opus 5.5 c00045d7d9 Merge upstream/main into fix/7537-windows-arm-dx12
Resolve conflicts with #4's "Auto on Windows leaves Vulkan out when an
Intel adapter is present" (3c9c93ed) and #7813's adapter choice
(`configure` gained `wanted`):

- gpu_startup.rs: `intel_dx12_applied(.., vulkan_left_out)` from main and
  the patch's `dx12_default_applied` become one
  `dx12_default_applied(adapters, chosen, os, vulkan_left_out)` that
  returns the maker's name (Intel or Qualcomm). `vulkan_left_out` counts
  only for Intel, since only an Intel DXGI adapter makes
  `windows_auto_backends` drop Vulkan. `configure` keeps main's `wanted`
  parameter and Vulkan-free instance; the System Info note names the maker.
- Tests: keep both main's Intel instance test and the Qualcomm test,
  updated to the merged signature, plus one assertion that Vulkan being
  left out doesn't make a Qualcomm DX12 pick "the default".
- Module docs and docs/development.md: main's wording, with Qualcomm
  (Windows on ARM) added to the DX12 default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:55:06 -04:00
Higgs32584andClaude Opus 5.5 5eac93bf23 Merge upstream/main into revive/4330-jpeg-options
Main moved on (integration batch #8095 and others). Two conflicts:
- docs/gaps.md revision history: both rows kept, newest first.
- docs/scorecard.md (generated): main's version taken. It needs
  `cargo xtask scorecard` again: with FILE-215-19 done, File
  compatibility reads 8 done / 5 missing rather than main's 7 / 6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:47:00 -04:00
Higgs32584andClaude Opus 5.5 92d1ff42f9 Merge upstream/main into revive/4330-jpeg-options
Main added DDS saving (#5993): DDS Options, and FormatChoices carrying the
Targa and DDS answers through every save path (this branch's SaveChoices
carried Targa and JPEG). Resolved by keeping main's name and making it
the one struct for all three answers.

- lib.rs: FormatChoices { tga_bits, dds, jpeg } with from_params (strict),
  from_step (lenient JPEG read of a recorded step), apply and record;
  main's separate block is folded in. Both prompts (dds_options and
  jpeg_options) are kept everywhere: save_to asks Targa, then DDS, then
  JPEG Options; save_options_open covers all four. save_in_place takes
  main's (path, choices) signature and records the plain-Save step with
  plain_save_step for JPEG plus the Targa/DDS answers (save_in_place_with
  folded into it). journal_as_plain_save relabels a parked Targa, DDS or
  JPEG prompt and keeps tgaBits/dds*/quality/jpegFormat when dropping the
  path. replay_save reads choices with from_step.
- SAVE_OPTIONS_OPEN names all four prompts; DDS Options uses it too.
- targa_options_ui: main's plain-Save step (no path) through this
  branch's write_answered_save. JPEG Options gets main's Enter-on-a-
  focused-Cancel fix.
- view_cmds Save a Copy asks Targa, DDS, then JPEG Options; write_copy
  takes FormatChoices.
- control.rs: both app.save tests (JPEG and DDS) kept.
- engine file_cmds: SaveOpts keeps jpeg_format and dds; param docs list
  both jpegFormat and ddsCompression/ddsMipmaps. CLI: both --jpeg-format
  and --dds-compression/--dds-mipmaps. codecs re-exports JpegFormat and
  DdsCompression/DdsOptions.
- docs/book: both entries kept (control-protocol app.save lists both).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:43:26 -04:00
b484f45429 Integration: merge main, resolve conflicts (#5407)
apps/photocraft{,-web}: main added "cin" to OPEN_EXTS; kept it and the PR's
"act". apps/photocraft/src/services.rs: main gave File > Open one filter per
format (#6337) and checks with every_open_format_has_its_own_filter that the
filters cover OPEN_EXTS exactly, so "act" joins the Swatches filter.
i18n: both sides appended sections at the end of every catalog; kept both.

Co-authored-by: Abdul karim mia <97598943+abdul-karim-mia@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 01:49:54 +02:00
aiongg 92513627da Merge PR #5587: Preserve editable clipboard contents when native reads fail 2026-10-20 22:07:10 +00:00
aiongg 3a8ea8d9ad Integration: barrel check reads only the pen, not the global right button, for #6195
GetAsyncKeyState(VK_RBUTTON) reads the physical button system-wide: with swapped buttons a primary click read as right-down, and a right button held over another window counted too.
2026-10-20 22:07:10 +00:00
aiongg 77cd7118ee Merge PR #6195: fix(tablet): support stylus barrel button and brush resize on Windows (#5905, #5364) 2026-10-20 22:07:10 +00:00
Vikram Bhaskaran ff61346024 Open mislabeled .psd files from their raster signature.
PNG/JPEG/TIFF bytes named .psd still go through codecs, as on main and
in Photoshop. Only an unrecognized .psd keeps the PSD parse error.
2026-10-21 08:57:47 +11:00
Vikram Bhaskaran c41ca8b9f1 Merge origin/main into feat/iff-read.
Keep Amiga IFF in the gaps changelog and add an Open dialog filter for
iff/lbm/ilbm so named types still cover OPEN_EXTS.
2026-10-21 08:01:33 +11:00
Vikram Bhaskaran c0eb60dc84 Merge origin/main into fix/5258-psd-open.
Keep PSD routing in io. Use main's per-format Open filters, which
already include Photoshop.
2026-10-21 07:31:19 +11:00
aiongg db56aeb10a Merge PR #7813: Choose the graphics adapter on multi-GPU Linux machines (#1885)
# Conflicts:
#	apps/photocraft/src/gpu_startup.rs
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	crates/ui-egui/src/prefs_ui.rs
2026-10-20 18:41:25 +00:00
aiongg ad2d420be2 Merge PR #7683: Web: start when the server already inflated the app's gzip part (Apache mod_mime_magic) (#7639) 2026-10-20 18:39:30 +00:00
aiongg 9ddc2805f0 Merge PR #6878: Windows: maximized window lets an auto-hidden taskbar show (#4845) 2026-10-20 18:39:29 +00:00