-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Open
Description
Bug
When loading raw DIB (device-independent bitmap) data embedded in Windows PE resource sections (e.g. cards.dll), Pillow misreads bitmaps that use the old OS/2 BITMAPCOREHEADER format (12-byte header, bcSize=12).
Two bugs
1. 4-bit paletted images
Color table is read as RGBQUAD (4 bytes/entry) instead of RGBTRIPLE (3 bytes/entry), shifting the pixel data offset by 16 bytes and producing wrong colors.
2. 1-bit monochrome images
Row stride calculation is wrong, producing a solid black stripe ~17px wide on the left of every decoded image.
Repro
Extract any bitmap resource from Windows XP cards.dll using pefile, write the raw bytes (without a BITMAPFILEHEADER) and open with:
from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
img = Image.open("raw_dib_resource.bmp")Workaround
Manually parse the BITMAPCOREHEADER with struct and decode pixel data directly:
import struct
from PIL import Image
def decode_bitmapcoreheader(raw):
bc_size, = struct.unpack_from("<I", raw, 0)
assert bc_size == 12
width, height, planes, bitcount = struct.unpack_from("<HHHH", raw, 4)
num_colors = 2 ** bitcount if bitcount <= 8 else 0
# RGBTRIPLE: 3 bytes each (NOT RGBQUAD)
colors = []
for i in range(num_colors):
b, g, r = struct.unpack_from("<BBB", raw, 12 + i * 3)
colors.append((r, g, b))
px_offset = 12 + num_colors * 3
row_stride = ((width * bitcount + 31) // 32) * 4
px_data = raw[px_offset:]
img = Image.new("RGB", (width, abs(height)))
pixels = img.load()
for row_idx in range(abs(height)):
y = abs(height) - 1 - row_idx if height > 0 else row_idx
for col in range(width):
if bitcount == 1:
byte_idx = row_idx * row_stride + col // 8
bit = (px_data[byte_idx] >> (7 - col % 8)) & 1
pixels[col, y] = colors[bit]
elif bitcount == 4:
byte_idx = row_idx * row_stride + col // 2
nibble = (px_data[byte_idx] >> 4) & 0xF if col % 2 == 0 else px_data[byte_idx] & 0xF
pixels[col, y] = colors[nibble]
return imgEnvironment
- Pillow 11.x
- Python 3.14
- Linux x86_64
- Source: Windows XP
cards.dllPE bitmap resources
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels