Skip to content

GIF: compress changed-frame rectangles with disposal-safe deltas (TDD + Pillow) - #32

Merged
mikasoukhov merged 3 commits into
masterfrom
fix/gif-delta-frames-20261011
Oct 10, 2026
Merged

mikasoukhov merged 3 commits into
masterfrom
fix/gif-delta-frames-20261011

Conversation

@mikasoukhov

@mikasoukhov mikasoukhov commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

GIF delta-frame compression on fresh master

Base: master @ a67e45929dc5fbd53b7a25f68bd81f39ccdce4e4. New branch: fix/gif-delta-frames-20261011. Exactly three commits: tests (RED), implementation, documentation/Pillow validation.

Fix

  • GifCodec.Encode looks ahead at one decoded frame (streaming, not materializing all frames).
  • Default: write the smallest rectangle of changed visible pixels, mark unchanged internal pixels transparent, use GIF disposal method 1.
  • When the following frame requires opaque → transparent, write a whole-canvas frame using disposal method 2 to clear the screen. Handle the last → first transition for looping animations.
  • Unchanged consecutive frames emit a 1×1 transparent frame while retaining their delay.
  • Keep frame ordering, local palettes, LZW compression, GIF loop count, transparent pixels and timing; runtime remains pure managed C# with no new dependencies.

TDD

  • Red tests on master-backed test-only commit 3d164340: 4 expected GIF delta test failures on both .NET 6 and .NET 10.
  • Regression tests inspect actual GIF block rectangles, transparent pixel indices, disposal flags, loop boundaries, all frame timings, LZW and independent test-side frame compositing.
  • Existing test Reencoded_MoreColorsThanATableHolds_StayCloseToTheSource updated to compare composed frames instead of assuming a full-screen raw block.
  • Independent Pillow 12.3.0 CI verification checks input vs re-encoded GIF with a different decoder, pixel-by-pixel on each frame, delay, frame count, logical screen and loop metadata. A third 61-frame synthetic screen-capture fixture is included in the final commit.
  • The complete .NET 6/10 matrix on Windows, Ubuntu and macOS, plus DB and Azurite, runs for the final commit.

Benchmarks and scope

Pillow-confirmed intermediate examples: 4-frame 198→161 bytes, 3-frame 1021→818 bytes. The two local, unpushed originals mentioned in the report (423086 and 143274 bytes) are not accessible here, so their target sizes cannot be claimed without those exact fixtures. No changes to JPEG, PNG, color profiles or unrelated encoders.

All changes are restricted to the new branch until CI checks pass; merge into master via squash to keep master history to one commit.

@mikasoukhov mikasoukhov changed the title Optimize GIF encoding with delta rectangles and independent animation verification GIF: compress changed-frame rectangles with disposal-safe deltas (TDD + Pillow) Oct 10, 2026
@mikasoukhov
mikasoukhov marked this pull request as ready for review October 10, 2026 23:29
@mikasoukhov
mikasoukhov merged commit 03e2f61 into master Oct 10, 2026
5 checks passed
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.

1 participant