-
Notifications
You must be signed in to change notification settings - Fork 50
Description
What doesn't work?
I'm finding that SDL_CreateRGBSurfaceWithFormatFrom
either throws or fails to take in the pixel data (but creates a valid empty SDL_Surface) when passed in a sub-array of a bytes
object directly. But it works if I setup an intermediate python object first.
How To Reproduce
This test case stems from difficulties I ran into when adding support for setting the application's window icon:
#!/usr/bin/env python
import sys
import sdl2
if __name__ == '__main__':
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
window = sdl2.SDL_CreateWindow(
'test'.encode(),
sdl2.SDL_WINDOWPOS_CENTERED,
sdl2.SDL_WINDOWPOS_CENTERED,
640,
480,
0
)
assert sys.byteorder == 'little'
# A dummy 4 bytes header, followed by an little endian ARGB solid green fill
# For instance, say we loaded a TGA file with 18 bytes worth of header
w = h= 256
pixels = b'\xff\xff\xff\xff' b'\x00\xff\x00\xff' * w * h
# Arch Linux, Python 3.11.7: pixels don't get through, yields a blank/fully transparent icon
# Arch Linux, Python 3.12.2 (AUR): pixels don't get through, yields a blank/fully transparent icon
# Windows, Python 3.11.8: OSError: exception: access violation reading [..]
# Windows, Python 3.12.2: works fine!
# (all with PySDL2 0.9.16, current atm and SDL 2.30.0)
icon = sdl2.SDL_CreateRGBSurfaceWithFormatFrom(pixels[4:4+w*h*4], w, h, 32, w*4, sdl2.SDL_PIXELFORMAT_ARGB8888)
assert icon is not None
assert icon.contents.format.contents.format == sdl2.SDL_PIXELFORMAT_ARGB8888
sdl2.SDL_SetWindowIcon(window, icon)
import time
time.sleep(4)
# Workaround: this..
pixels2 = pixels[4:4+w*h*4]
icon = sdl2.SDL_CreateRGBSurfaceWithFormatFrom(pixels2, w, h, 32, w*4, sdl2.SDL_PIXELFORMAT_ARGB8888)
assert icon is not None
assert icon.contents.format.contents.format == sdl2.SDL_PIXELFORMAT_ARGB8888
sdl2.SDL_SetWindowIcon(window, icon)
import time
time.sleep(4)
On Windows with Python 3.12 the first SDL_CreateRGBSurfaceWithFormatFrom
call works. Elsewhere it'll either ignore the pixels and yield a transparent/empty surface, or throw an OSErrror.
The workaround is what bugs me the most .. just .. pixels2 = pixels[4:4+w*h*4]
and all platforms work.
Platform:
- OS: Windows 11 64-bit, Arch Linux (have not tested others)
- Python Version: 3.11.7 3.11.8 3.12.2
- SDL2 Version: 2.0.30
- Using pysdl2-dll: Yes on Windows
Additional context
Add any other context about the problem here.