mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-12 21:23:02 +00:00
Imported documents need durable conversion evidence and native pixel operations before XCF conversion can produce editable PhotoCraft data. This adds bounded document/report types, lossless pattern construction and `.pcraft` persistence, plus native HDR, percentile, noise, convolution, Average, coverage and matting kernels and checked Smart-filter mixing. Runtime color models/depths are retained; source attachments remain inert. Native SVG operations retain parsing, lowering, rendering and parser-tree destruction on one bounded worker, including nested resources; WebAssembly reports a controlled error for depths requiring native isolation. Native filter corrections cover matte black points and signed HDR, extent-wide Smart-filter coverage, flat-image identity Auto Levels, opaque FillHoles capability, exact unselected channel preservation, coverage-preserving Average selection and bounded pattern expansion. Checked Smart-filter mixing rejects nonfinite native F32 samples, preserves unchanged Normal pixels without regenerating CMYK separations, and recovers representable alpha mixtures after an overflowing difference. HDR blend overflow retries use cold F64 arithmetic while retaining ordinary finite results and integer-depth behavior. Both opaque and alpha-bearing F32 mask recovery retain signed/HDR colors. Stored pattern declarations remain lossless and inert. Dense PSD/PAT/ASL pattern export now checks dimensions and one shared plane-allocation budget before conversion. PAT/ASL report conversion errors; PSD/PSB report named omission warnings. Matching raw PSD pattern blocks remain verbatim. CMYK offsets retain the established brightness convention. Command registration, XCF decoding and frontend workflows follow in dependent parts. The contributor entry is the author's existing chosen entry. <!-- native-foundations-fixes-20261107:start --> Small noise, convolution and point-operation edits admit their clipped work area on large owners while retaining output/workspace limits and whole-owner FillHoles bounds. HDR toning retains skipped transparent native samples. Normal Smart-filter strength interpolates stored CMYK/Lab/ink planes with premultiplied coverage, preserving unchanged channels. Bitmap Custom Pattern reads compact patterns in bounded row bands and ranks the complete map once. Embedded SVG isolation failures propagate independently of strict mode; ordinary invalid images can still be omitted, and private native parses share the complete-operation worker. The import-report regression now primes the layer blob cache and requires its specific limit diagnostic. <!-- native-foundations-fixes-20261107:end --> <!-- adversarial-5810371597:start --> Import-report accounting uses portable fixed costs. HDR scene means use F64. Bitmap pattern ranking preflights a 256 MiB input/order/output budget, uses fallible allocation and heap-scratch-free sorting. Average uses the supplied image domain and retains one global mean across output tiles. Non-Normal Smart-filter coverage is classified once across the complete mixing extent. A fallible filter dispatcher and engine error conversion preserve checked native diagnostics and cancellation. Smart-filter engine integration remains in part 5 (#11032). <!-- adversarial-5810371597:end --> ## Six-part series Each branch is hosted in Terra854/photocraft, and every PR targets storytold/photocraft:main. Merge in the order below. Later drafts currently show cumulative diffs while prerequisites are unmerged; their descriptions link to isolated comparisons. Rebase each part onto current upstream main after its prerequisites merge, including squash-merge ancestry, and rerun affected checks before requesting review. | Part | Upstream PR | Fork branch | Scope | | --- | --- | --- | --- | | 1 | [#11009](https://github.com/storytold/photocraft/pull/11009) | xcf-support-v2-01-import-data | Document/native-format data and pixel foundations | | 2 | [#11029](https://github.com/storytold/photocraft/pull/11029) | xcf-support-v2-02-decoder | Bounded transport/records, precision, metadata, editable text and paths | | 3 | [#11030](https://github.com/storytold/photocraft/pull/11030) | xcf-support-v2-03-effects-core | Native effect frames and primary tone/color/spatial/resource/transform adapters | | 4 | [#11031](https://github.com/storytold/photocraft/pull/11031) | xcf-support-v2-04-effects-graphs | Remaining adapters, bounded graph lowering, coverage installation and source evidence | | 5 | [#11032](https://github.com/storytold/photocraft/pull/11032) | xcf-support-v2-05-engine | Native commands, import preparation, historical choices, editing and persistence workflows | | 6 | [#11033](https://github.com/storytold/photocraft/pull/11033) | xcf-support-v2-06-frontends | Desktop/web UI, CLI/MCP, translations, GPU diagnostics and qualification/docs | The full integration remains preserved on `xcf-support-v2`; original #7098 remains available for reference. ## Validation <!-- main-catchup-0d08cb7dd:start --> Updated to upstream `main` at `0d08cb7dd` and restacked all six branches. Part 1 is `640a01f43`; full integration is `24cd17301`. The final six-part tree exactly matches the full integration tree. The merge preserves both upstream's new tests/crop translations and the XCF historical-open tests/report labels. The automation adapter now preserves import-source protection across multiple granted read roots: relative source names cover every matching candidate so newly shadowing files cannot expose the original to overwrite, while absolute source names remain precise. Existing ordered reads and implicit-save provenance are retained. Read-only import source identity is kept independently of whether its library root grants an implicit Save target. Focused regressions cover source aliases, removed files, denied candidates, changing root precedence, and read-only library imports; the Windows escape fixture also uses a real junction when symlink privileges are unavailable. The new upstream UI import fixture also uses the native import outcome type. Local validation passed affected host all-target checks, core and native frontend/automation unit and integration suites, forced-Vulkan GPU unit and integration suites, pinned IO corpora, strict all-target Clippy, formatting, layering, panel command dispatch, WASM, adversarial command tests, and the quick CPU performance harness. Offscreen historical-XCF prompt and conversion-report captures were reviewed. The first two PR boundaries also passed independent all-target engine checks. Tests used the pinned craft-fonts input, four Rayon workers, serial tests for large fixtures and opt-level=0 for engine/UI test glue; pixel/format crates retained their repository settings. Quick mode uses small documents and does not enforce full-size budgets. The part 1 push triggered fresh [CI](https://github.com/storytold/photocraft/actions/runs/42885527754) and [SonarCloud](https://github.com/storytold/photocraft/actions/runs/42885527740) runs. After upstream approval, CI passed the Linux gate, Windows unit/integration tests, no-HEIF tests, pinned corpora and web build. SonarCloud's instrumented archive, coverage shards and actual scan remain skipped behind its token guard; its outer green status does not mean coverage ran. Catching up with main therefore retriggered normal tests but did not remove that SonarCloud skip. Older validation below remains evidence for its explicitly named earlier commits. <!-- main-catchup-0d08cb7dd:end --> <!-- average-no-extent-4517477902:start --> Average no-extent follow-up at part 1 `f8ddb626f` (full integration `882def329`), carried through all six branches. The checked Average dispatcher now uses the requested `area` when no owner extent is supplied; an explicit extent retains its existing clipping behavior. Other filters, the Average pixel kernel and resource admission are unchanged. The new regression fails against the preceding revision and passes with the fix. It covers `apply`, one-pixel explicit tiling, and the cancellable tiled API at 8/16/32-bit, signed/HDR colors, hidden RGB, native alpha preservation, unchanged source data and pixels outside the requested area. Validation passed the algorithm unit/integration suite (935 tests; 27 existing ignored), strict all-target algorithm Clippy, formatting, layering, WASM (24 crates plus HEIF), and independent all-target engine checks of the first two PR boundaries. The broader suites below remain evidence for their named earlier commits and were not rerun for this dispatcher-only follow-up. <!-- average-no-extent-4517477902:end --> <!-- review-20261110:start --> Review follow-up at part 1 `a3144d559` (full integration `b5fd3e211`), carried through all six branches. Average admits long thin regions within its existing pixel/workspace budgets, clamps finite selection coverage, and uses owner extents for off-canvas replay. HDR Toning also adapts over the owner extent. Pattern GPU uploads now use bounded bands; the warning-free `document_to_psd` API returns `Result` on pattern export failure and reuses prepared pattern blocks. Warning-enabled exports retain explicit omission warnings. Five filter regressions fail against the previous revision and pass with the fixes. Local validation passed 1,597 algorithm/compositor/GPU tests with Vulkan, all 129 GPU integration tests separately on DX12 with FXC (the app uses FXC when no bundled DXC is present), a separate forced DX12 pattern upload/readback test, 1,144 IO unit and 675 pinned IO integration tests, 10 affected engine tests, strict all-target Clippy, formatting, layering, WASM and quick CPU performance checks. The first two PR boundaries passed independent all-target engine checks. This Intel driver's DX12/DXC configuration rejects the unchanged `fs_adjust` pipeline (`0x80070057`); DX12/FXC and Vulkan both pass. The full workspace suite was not rerun; earlier broad evidence below remains tied to its named commits. Quick performance mode does not enforce full-size budgets. A separate 24 MP signed/HDR RGBA32F public Average-kernel probe retained exact mean RGB and original alpha. Three alternating runs had medians of 1,274.713 ms before and 1,259.885 ms after; this small difference is within run variation and is not a speedup claim. The Minor/Poor-tradeoff report-deserialization finding remains open and documented. Encoded records are capped at 32 MiB and individual arrays are bounded, but compact targets can still amplify transient decoded memory before aggregate validation rejects the report. Early shared-budget deserialization is not implemented in this follow-up. <!-- review-20261110:end --> <!-- main-catchup-7c64653d5:start --> Updated to upstream `main` at `7c64653d5` and restacked all six branches. Part 1 is `cbf068d5f`; full integration is `206f71012`. The full integration tree exactly matches part 6. The merge retains main's alpha-preserving Average behavior with bounded checked processing, and uses it consistently for XCF coverage conversion and native replay. Historical XCF normalization and import preparation now run through main's resumable Place flow and Open as Smart Object; regression tests cover source byte order and native Edit Contents. XCF report/filter labels also cover the seven languages main promoted to menu-complete status. The current tree passed affected host all-target checks, core/IO, GPU, engine and frontend suites, strict all-target Clippy, formatting, layering, panel command dispatch, WASM and the web build, adversarial command tests, pinned IO corpora and the quick CPU performance harness. Offscreen historical-XCF prompt and conversion-report captures were reviewed. The first two PR boundaries also passed independent all-target engine checks. Tests used CI-pinned craft-fonts `b076417b5880bd4154bd22f00695b1d28c6bea83`, four Rayon workers, serial tests for RAM-heavy suites and opt-level=0 for engine/UI test glue; pixel and format crates kept repository settings. Quick performance mode uses smaller documents and does not enforce full-size budgets. Older measurements below remain evidence for their named earlier commits. <!-- main-catchup-7c64653d5:end --> <!-- percentile-owner-4502952267:start --> Percentile owner-bounds follow-up at part 1 `93946db04` (full integration `f7264af14`): nonempty owner bounds now supply edge samples without a dense whole-owner admission check. The unchanged preflight still bounds clipped output, padded halo, workspace and CPU work; dense-image adapter limits remain in place. Two new regressions failed with `InvalidGeometry` before the fix and pass afterward, covering small edits on 81 MP and wider sparse owners, clamped-edge oracles, fractional selections, source preservation, clipped requests, invalid domains, oversized output, work limits and cancellation. This follow-up passed 903 algorithm tests (887 unit + 16 integration; 27 existing ignored), all-target strict algorithm Clippy, formatting, layering and WASM (24 crates plus the HEIF configuration). Only sampling-bound admission changed; percentile processing and resource-preflight code are byte-for-byte unchanged. The broader qualification below remains tied to its explicitly named earlier commits; the full workspace suite was not rerun for this one-file follow-up. <!-- percentile-owner-4502952267:end --> <!-- native-foundations-validation-20261107:start --> The production fixes at part 1 `c16e274b8` (full integration `6f8349cd5`) passed 7,245 affected algorithm/compositor/document/engine/native-format/IO tests across 46 binaries, with 65 existing ignored tests, plus doctests, affected all-target strict Clippy, layering, WASM, adversarial command tests, formatting and the pinned IO corpus (1,107 unit + 661 integration tests, 26 existing ignored). The final diagnostics regressions also passed independently on the foundation and full integration branches. The first PR passed an independent all-target engine check. Tests used four Rayon/test workers and the existing CI font pin; engine test glue used opt-level=0, and the foundation-only diagnostic probe also used opt-level=0 for its algorithm dependency. The full integration tree exactly matches the final sixth branch. Paired 24 MP release probes used three timed repetitions per version after warm-ups, alternating order, matching inlining controls, opaque parameters and a current public-API control, with four Rayon workers. Timings are completed operations on this host. | Probe | Before (ms) | After (ms) | Public API (ms) | | --- | ---: | ---: | ---: | | HDR toning | 830.3 | 834.4 | 791.2 | | Rgb-Normal | 1070.5 | 1069.3 | 1079.7 | | Cmyk-Normal | 683.0 | 669.7 | 691.5 | | Rgb-Multiply | 1103.1 | 1303.3 | 1297.5 | The extent-wide coverage prepass adds 200.2 ms (18.2%) in the alpha-preserving Multiply case. This is the measured cost of applying one consistent coverage rule; the Normal RGB/CMYK controls remain near baseline. The uniform HDR probe's middle-gray output changed from 0.200004 to 0.180000 (target 0.18); the public control agrees. Mixer probes check native colors and alpha at sampled positions. The quick CPU application harness also completed; its saved cross-machine comparison was skipped, and quick mode does not apply full-size budgets. No budgets or baselines changed. <!-- native-foundations-validation-20261107:end --> Earlier validation of full integration `c003e3f50`, before these follow-up fixes, completed the upstream `main` catch-up at `c101cbfb7` on 2026-11-07. The cumulative series passed affected host all-target checks, foundation and IO suites, GPU, engine and frontend suites, strict Clippy, layering, WASM, adversarial command tests, formatting, pinned IO corpora and the quick CPU performance harness. Offscreen historical-XCF prompt and conversion-report captures were reviewed. Local tests used CI-pinned craft-fonts `b076417b5880bd4154bd22f00695b1d28c6bea83`, four Rayon workers and temporary opt-level=0 overrides for engine/UI test glue; pixel and format crates retained repository settings. The full UI library passed 5,330 tests, and the final dialog-dispatch cleanup passed 945 focused dialog tests. The decoder and engine PR boundaries also passed independent all-target checks. The full `xcf-support-v2` integration tree matches the final sixth branch exactly. SVG stack regressions retain their 512 KiB caller, isolated complete native lifecycle and 100 retained group levels. The matched performance figures below were measured before this main integration; the HDR recovery arithmetic and bounded tile implementation are preserved. Forward filter-mask mixing retains its existing four-buffer allocation optimization and arithmetic. Its matched 24 MP RGBA32F probes measured opaque pixels at 392.410→182.842 ms, semitransparent pixels at 383.321→179.916 ms, and signed HDR pixels at 373.696→183.903 ms (five-run medians, 50–53% faster). Inverse filter-mask recovery now processes at most eight native tiles in parallel, with four reusable scratch buffers per slot and ordered surface publication. Small inputs, one-worker operation and WebAssembly use the same serial tile helper. All F64 and integer pixel arithmetic is unchanged. Bitwise regressions compare full/partial/missing tiles, negative coordinates, differing defaults and hidden/zero-alpha outputs across 30 format combinations; an explicit one-worker/two-worker comparison checks both execution paths. Matched 24 MP HDR inverse-recovery public-API probes measured 166.972→90.565 ms (opaque, 45.8% faster), and 433.325→130.707 ms (semitransparent, 69.8% faster). Five-run medians use four Rayon workers on this host; all runs assert recovered HDR samples at three positions. The existing F64 precision and HDR saturation bounds are preserved. Mask recovery retains signed/HDR colors, extreme finite values, subnormals and exact full coverage. The PSD/PSB regression uses a real blur on spatially varying HDR pixels and partial masks; raw exported channels must match the unmasked filter result, and reimported Smart caches must match independently authored masked values. The prior quick CPU application harness completed. Its saved cross-machine baseline comparison was skipped, so the paired public-API measurements above provide the direct before/after evidence. No performance budgets or baselines changed. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **New Features** * Added image adjustments and filters for averaging, channel noise, convolution, percentile effects, alpha and coverage editing, black matte removal, HDR toning, and automatic tone, contrast, and color correction. * Added Smart-filter blending controls for opacity and blend modes. * Import-conversion information is preserved when saving and reopening documents. * **Improvements** * Improved handling of deeply nested SVGs and large patterns, with bounded pattern processing and warnings when pattern export is not possible. * Improved stability when blending extreme HDR values and applying filters to HDR images. * Improved transparency handling for channel-selective filters and added clearer feedback when image processing or export cannot be completed. <!-- end of auto-generated comment: release notes by coderabbit.ai -->