Skip to content

Fix converting I and I;16 images with transparency to LA or RGBA - #10338

Merged
radarhere merged 4 commits into
python-pillow:mainfrom
laozidabo:fix/16bit-grayscale-transparency
Oct 31, 2026
Merged

radarhere merged 4 commits into
python-pillow:mainfrom
laozidabo:fix/16bit-grayscale-transparency

Conversation

@laozidabo

Copy link
Copy Markdown
Contributor

Refs #10330 (grayscale portion).

Converting an I;16 image with pixels [0x1234, 0x0034] and transparency key 0x1234 currently produces alpha [255, 0] instead of [0, 255]. The integer samples are clipped to 8 bits before matching, and the transparency key is truncated to its low byte. I images have the same problem, including false matches between negative values and zero or between distinct values clipped to 255.

This change matches I and I;16 transparency against the original source samples and only changes the matching pixels' alpha. It preserves the existing color clipping and the conversion paths for other modes. Tests cover low-byte collisions, clipped values, two image rows, signed 32-bit boundaries, and a real 16-bit grayscale PNG round trip to both LA and RGBA. A release note is included.

The 16-bit RGB case in #10330 remains unresolved: decoding has already discarded the low bytes, so simply shifting the transparency key would also match other source colors with the same high bytes. This PR does not close the whole issue.

Validation on Linux x86_64 / Python 3.14.7, with freshly built native extensions:

  • New conversion regressions before the change: 26 failed, 6 passed.
  • selftest.py: 59 passed.
  • Conversion, PNG and APNG tests: 188 passed, including all 34 added cases.
  • Full pytest Tests/ -n 4: 5,751 passed, 92 skipped, 3 expected failures.
  • Full prek run --all-files and the manual Pyroma hook: passed.
  • tox -e mypy: passed (303 source files).

Windows and macOS have not been tested locally. The full-suite skips include unavailable Ghostscript, some missing test images, and platform-specific cases.

AI disclosure: this contribution was developed, tested, and reviewed with OpenAI Codex. The account owner has not manually reviewed the code.

@radarhere
radarhere force-pushed the fix/16bit-grayscale-transparency branch from 5a23c9d to 4340a24 Compare October 31, 2026 08:12
@radarhere radarhere changed the title Match integer transparency against original pixel values Fix converting I and I;16 images with transparency to LA or RGBA Oct 31, 2026
@radarhere
radarhere force-pushed the fix/16bit-grayscale-transparency branch from 4340a24 to 2750223 Compare October 31, 2026 08:20
@radarhere
radarhere enabled auto-merge (squash) October 31, 2026 08:24
@radarhere
radarhere merged commit a11bd1d into python-pillow:main Oct 31, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants