Skip to content

Fix PICT pixel decoding for 32-bit planar and cicn icons - #14

Open
grub-basket wants to merge 1 commit into
jorio:masterfrom
grub-basket:fix/pict-pixel-decoding
Open

Fix PICT pixel decoding for 32-bit planar and cicn icons#14
grub-basket wants to merge 1 commit into
jorio:masterfrom
grub-basket:fix/pict-pixel-decoding

Conversation

@grub-basket

Copy link
Copy Markdown

Problem

Two decoding bugs in pict.py:

  1. 32-bit planar pixmaps decode scrambled. unpack4() uses a 3-plane row stride (y*w*3) in the 4-plane branch, even though the buffer holds numplanes*w*h == 4*w*h bytes with rows 4*w wide. Any packtype-4 PICT with cmpcount == 4 (32-bit ARGB planar) decodes with rows sliding out of alignment — colors/alpha bleed across rows. 24-bit (3-plane) was already correct.
  2. cicn B&W bitmap read with the wrong height. read_cicn() reads the black-and-white icon bitmap using the mask bitmap's height (maskbm.height) instead of the B&W icon's own (bwiconbm.height). When the two BitMaps have different bounds, the unpacker advances by the wrong byte count and the following read_colortable() reads from the wrong offset, corrupting the palette.

Fix

Use y*w*4 as the row base in the 4-plane branch, and bwiconbm.height for the B&W icon read.


Prepared with Claude Fable 5 (Low effort mode). Automated finding, manually verified — please review before merging.

Two decoding bugs in pict.py:

1. unpack4() used a 3-plane row stride (y*w*3) in the 4-plane (32-bit
   ARGB planar) branch, even though the buffer holds numplanes*w*h ==
   4*w*h bytes with rows 4*w wide. Any packtype-4 PICT with cmpcount==4
   decoded with rows sliding out of alignment (scrambled colors/alpha).
   Use y*w*4 as the row base. 24-bit (3-plane) was already correct.

2. read_cicn() read the black-and-white icon bitmap using the mask
   bitmap's height (maskbm.height) instead of the B&W icon bitmap's own
   height. When the two BitMaps have different bounds, the unpacker
   advanced by the wrong byte count and the following read_colortable()
   read from the wrong offset, corrupting the palette. Use bwiconbm.height.
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