Skip to content

core: image diff, RGBA8 pixels to the rects that differ - #667

Merged
foxnne merged 4 commits into
mainfrom
core/diff-image-uc6tby
Oct 19, 2026
Merged

foxnne merged 4 commits into
mainfrom
core/diff-image-uc6tby

Conversation

@foxnne

@foxnne foxnne commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Part of fizzyedit/plans plans/DIFF_PLAN.md step 3 (2.4, 3). Independent of step 1 (text): core/diff.zig is the namespace and only names Image/TileGrid; step 1 adds its files beside them.

What

  • core.diff.Image: stride-aware RGBA8 diff. Identical rows cost one 64-byte-vector compare (firstDiff); differing rows are compared per 32x32 (or 16x16) tile segment from the first differing byte. Changed tiles merge into rects (runs along a row, joined to an identical run above), each shrunk to its exact changed pixels (exact, default) with a pixel count. Optional per-channel tolerance, max_rects coalescing into a bounding box, size_changed for different sizes (overlap diffed). Shared storage and identical buffers return early. Reusable state: no allocation after the first diff of a size.
  • core.diff.TileGrid: 8 bytes per tile (63 KB for 4K), keepable per step; diff compares two grids into tile rects.
  • bench-diff + unit tests (including a property test that the rects cover every differing pixel and the pixel count is exact), root fizzy-diff-tests.

Bench (zig build bench-diff -Doptimize=ReleaseFast, Linux cloud box)

Case Target Measured
4K RGBA identical < 4 ms 2.5 ms
4K, one small stroke < 8 ms 3.6 ms
4K, every tile touched n/a 2.9 ms
4K grid vs kept grid < 1 ms 0.011 ms
4K grid compute n/a 3.9 ms
2048x2048 x 50 layers, one touched (49 share storage) < 10 ms 2.6 ms
same, one layer from a distinct copy n/a 1.2 ms

std.mem.indexOfDiff/eql were ~4-6x slower than the vector loop here, hence firstDiff. Tile size default (32 vs 16) and tolerance stay open questions in the plan.

SDK / UI

No SDK or plugin boundary change, no UI.


Generated by Claude Code

core.diff.Image walks two images a row at a time (identical rows cost one
vectorized compare), compares differing rows per 32x32 (or 16x16) tile
segment, merges changed tiles into rects and shrinks each to its exact
changed pixels, with an optional per-channel tolerance and a max_rects
coalesce. core.diff.TileGrid keeps 8 bytes per tile to diff a past step.
std-only; bench-diff measures the DIFF_PLAN section 3 budget.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYmfUKnG4kP4sBA4jTt5CX
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYmfUKnG4kP4sBA4jTt5CX
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYmfUKnG4kP4sBA4jTt5CX
…change, bench)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYmfUKnG4kP4sBA4jTt5CX
@foxnne
foxnne marked this pull request as ready for review October 19, 2026 20:44
@foxnne
foxnne added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit a2a65e0 Oct 19, 2026
11 checks passed
@foxnne
foxnne deleted the core/diff-image-uc6tby branch October 19, 2026 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants