Skip to content

Honor RGBA channel count in Pillow resize goldens - #30

Merged
felirami merged 3 commits into
mainfrom
fable/pillow-cf-resize
Aug 16, 2026
Merged

felirami merged 3 commits into
mainfrom
fable/pillow-cf-resize

Conversation

@felirami

@felirami felirami commented Aug 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The Pillow golden loader treated every non-L mode as 3 channels. Regenerating with eval/gen-pillow-goldens.py writes prod_down_rgba as mode: RGBA and channels: 4, so the length check failed (3145728 vs 2359296) and 4-channel pillowResize was never byte-checked. The browser CF path always resizes getImageData RGBA pixels.

A second issue showed up after the loader fix: Image.resize on RGBA converts to premultiplied RGBa first, so random-alpha goldens cannot match independent-channel pillowResize. The generator now resizes each RGBA band with BICUBIC, which is the extension contract.

Changes

  • goldenChannels() prefers the stored channels field and maps RGBA to 4. Older committed RGB/L entries without channels still load from mode.
  • The generator asserts mode/channel agreement, resizes RGBA per band, and adds a compact RGBA case with an independent RNG so later noise() cases do not shift.
  • The committed fixture now includes compact_rgba (160x120 to 147x110, Pillow 12.3.0).

Evidence

Reproduced against a regenerated prod_down_rgba golden before the fix: input length 1024*768*4 = 3145728, loader expected 1024*768*3 = 2359296.

After the fix:

  • Default committed subset: tests/pixel-resize.test.mjs 19/19 pass, including compact_rgba
  • PIXEL_RESIZE_GOLDENS on the full 21-case regen (Pillow 12.3.0): 35/35 pass, including prod_down_rgba (1024x768x4 to 587x440)
  • npm test: 217/217 pass

Public fixtures are directional only and are not a claim about Kenny's private held-out set.

Open in Web Open in Cursor 

cursoragent and others added 3 commits August 15, 2026 22:20
Golden loading mapped every non-L mode to 3 channels, so regenerated
RGBA cases from eval/gen-pillow-goldens.py failed length checks and
never exercised 4-channel pillowResize. The browser CF path always
resizes getImageData pixels. Prefer the stored channels field, map
RGBA to 4, and add a compact RGBA golden to the committed subset.

Co-authored-by: felirami <felirami@users.noreply.github.com>
Co-authored-by: felirami <felirami@users.noreply.github.com>
Pillow.Image.resize on RGBA premultiplies alpha, so random-alpha
goldens cannot match the independent-channel browser CF path.
Resize each RGBA band with BICUBIC and store a compact 4-channel
golden in the committed subset.

Co-authored-by: felirami <felirami@users.noreply.github.com>
@felirami
felirami marked this pull request as ready for review August 15, 2026 22:22
@felirami
felirami merged commit d26714b into main Aug 16, 2026
3 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.

2 participants