Skip to content

Commit 3e3fbdc

Browse files
committed
Use SDL_AllocFormat instead of creating it manually
According to the docs, `SDL_PixelFormat` is a read-only structure. Creating it manually leaves out some important fields like `format` and `next` pointer to be undefined. Signed-off-by: Marcin Serwin <marcin@serwin.dev>
1 parent a966d54 commit 3e3fbdc

File tree

1 file changed

+23
-57
lines changed

1 file changed

+23
-57
lines changed

src_c/surface.c

Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,9 +1844,8 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
18441844
*/
18451845
int bpp = 0;
18461846
SDL_Palette *palette = SDL_AllocPalette(default_palette_size);
1847-
SDL_PixelFormat format;
1847+
Uint32 format_enum = 0;
18481848

1849-
memcpy(&format, surf->format, sizeof(format));
18501849
if (pg_IntFromObj(argobject, &bpp)) {
18511850
Uint32 Rmask, Gmask, Bmask, Amask;
18521851

@@ -1904,66 +1903,49 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
19041903
"nonstandard bit depth given");
19051904
}
19061905
}
1907-
format.Rmask = Rmask;
1908-
format.Gmask = Gmask;
1909-
format.Bmask = Bmask;
1910-
format.Amask = Amask;
1906+
format_enum = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask,
1907+
Bmask, Amask);
19111908
}
19121909
else if (PySequence_Check(argobject) &&
19131910
PySequence_Size(argobject) == 4) {
1914-
Uint32 mask;
1911+
Uint32 Rmask, Gmask, Bmask, Amask;
19151912

1916-
if (!pg_UintFromObjIndex(argobject, 0, &format.Rmask) ||
1917-
!pg_UintFromObjIndex(argobject, 1, &format.Gmask) ||
1918-
!pg_UintFromObjIndex(argobject, 2, &format.Bmask) ||
1919-
!pg_UintFromObjIndex(argobject, 3, &format.Amask)) {
1913+
if (!pg_UintFromObjIndex(argobject, 0, &Rmask) ||
1914+
!pg_UintFromObjIndex(argobject, 1, &Gmask) ||
1915+
!pg_UintFromObjIndex(argobject, 2, &Bmask) ||
1916+
!pg_UintFromObjIndex(argobject, 3, &Amask)) {
19201917
pgSurface_Unprep(self);
19211918
return RAISE(PyExc_ValueError,
19221919
"invalid color masks given");
19231920
}
1924-
mask =
1925-
format.Rmask | format.Gmask | format.Bmask | format.Amask;
1926-
for (bpp = 0; bpp < 32; ++bpp) {
1927-
if (!(mask >> bpp)) {
1928-
break;
1929-
}
1930-
}
1921+
format_enum = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask,
1922+
Bmask, Amask);
19311923
}
19321924
else {
19331925
pgSurface_Unprep(self);
19341926
return RAISE(
19351927
PyExc_ValueError,
19361928
"invalid argument specifying new format to convert to");
19371929
}
1938-
format.BitsPerPixel = (Uint8)bpp;
1939-
format.BytesPerPixel = (bpp + 7) / 8;
1940-
if (PG_FORMAT_BitsPerPixel((&format)) > 8) {
1941-
/* Allow a 8 bit source surface with an empty palette to be
1942-
* converted to a format without a palette (pygame-ce issue
1943-
* #146). If the target format has a non-NULL palette pointer
1944-
* then SDL_ConvertSurface checks that the palette is not
1945-
* empty-- that at least one entry is not black.
1946-
*/
1947-
format.palette = NULL;
1948-
}
1949-
if (SDL_ISPIXELFORMAT_INDEXED(SDL_MasksToPixelFormatEnum(
1950-
PG_FORMAT_BitsPerPixel((&format)), format.Rmask,
1951-
format.Gmask, format.Bmask, format.Amask))) {
1930+
SDL_PixelFormat *format = SDL_AllocFormat(format_enum);
1931+
1932+
if (SDL_ISPIXELFORMAT_INDEXED(format_enum)) {
19521933
if (SDL_ISPIXELFORMAT_INDEXED(PG_SURF_FORMATENUM(surf))) {
1953-
SDL_SetPixelFormatPalette(&format, surf->format->palette);
1934+
SDL_SetPixelFormatPalette(format, surf->format->palette);
19541935
}
19551936
else {
19561937
/* Give the surface something other than an all white
19571938
* palette.
19581939
*/
19591940
SDL_SetPaletteColors(palette, default_palette_colors, 0,
19601941
default_palette_size);
1961-
SDL_SetPixelFormatPalette(&format, palette);
1942+
SDL_SetPixelFormatPalette(format, palette);
19621943
}
19631944
}
1964-
newsurf = PG_ConvertSurface(surf, &format);
1945+
newsurf = PG_ConvertSurface(surf, format);
19651946
SDL_SetSurfaceBlendMode(newsurf, SDL_BLENDMODE_NONE);
19661947
SDL_FreePalette(palette);
1948+
SDL_FreeFormat(format);
19671949
}
19681950
}
19691951
else {
@@ -4540,29 +4522,13 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45404522
}
45414523
else {
45424524
SDL_PixelFormat *fmt = src->format;
4543-
SDL_PixelFormat newfmt;
4525+
SDL_PixelFormat *newfmt =
4526+
SDL_AllocFormat(SDL_MasksToPixelFormatEnum(
4527+
fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, 0));
45444528

4545-
newfmt.palette = 0; /* Set NULL (or SDL gets confused) */
4546-
#if SDL_VERSION_ATLEAST(3, 0, 0)
4547-
newfmt.bits_per_pixel = fmt->bits_per_pixel;
4548-
newfmt.bytes_per_pixel = fmt->bytes_per_pixel;
4549-
#else
4550-
newfmt.BitsPerPixel = fmt->BitsPerPixel;
4551-
newfmt.BytesPerPixel = fmt->BytesPerPixel;
4552-
#endif
4553-
newfmt.Amask = 0;
4554-
newfmt.Rmask = fmt->Rmask;
4555-
newfmt.Gmask = fmt->Gmask;
4556-
newfmt.Bmask = fmt->Bmask;
4557-
newfmt.Ashift = 0;
4558-
newfmt.Rshift = fmt->Rshift;
4559-
newfmt.Gshift = fmt->Gshift;
4560-
newfmt.Bshift = fmt->Bshift;
4561-
newfmt.Aloss = 0;
4562-
newfmt.Rloss = fmt->Rloss;
4563-
newfmt.Gloss = fmt->Gloss;
4564-
newfmt.Bloss = fmt->Bloss;
4565-
src = PG_ConvertSurface(src, &newfmt);
4529+
src = PG_ConvertSurface(src, newfmt);
4530+
4531+
SDL_FreeFormat(newfmt);
45664532
if (src) {
45674533
#if SDL_VERSION_ATLEAST(3, 0, 0)
45684534
result = SDL_BlitSurface(src, srcrect, dst, dstrect) ? 0 : -1;

0 commit comments

Comments
 (0)