Skip to content

Commit 035dd86

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 035dd86

File tree

1 file changed

+29
-51
lines changed

1 file changed

+29
-51
lines changed

src_c/surface.c

Lines changed: 29 additions & 51 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,65 +1903,60 @@ 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;
1921+
1922+
const Uint32 mask = Rmask | Gmask | Bmask | Amask;
19261923
for (bpp = 0; bpp < 32; ++bpp) {
19271924
if (!(mask >> bpp)) {
19281925
break;
19291926
}
19301927
}
1928+
format_enum = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask,
1929+
Bmask, Amask);
19311930
}
19321931
else {
19331932
pgSurface_Unprep(self);
19341933
return RAISE(
19351934
PyExc_ValueError,
19361935
"invalid argument specifying new format to convert to");
19371936
}
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;
1937+
SDL_PixelFormat *format = SDL_AllocFormat(format_enum);
1938+
if (!format) {
1939+
SDL_FreePalette(palette);
1940+
pgSurface_Unprep(self);
1941+
return RAISE(pgExc_SDLError, SDL_GetError());
19481942
}
1949-
if (SDL_ISPIXELFORMAT_INDEXED(SDL_MasksToPixelFormatEnum(
1950-
PG_FORMAT_BitsPerPixel((&format)), format.Rmask,
1951-
format.Gmask, format.Bmask, format.Amask))) {
1943+
1944+
if (SDL_ISPIXELFORMAT_INDEXED(format_enum)) {
19521945
if (SDL_ISPIXELFORMAT_INDEXED(PG_SURF_FORMATENUM(surf))) {
1953-
SDL_SetPixelFormatPalette(&format, surf->format->palette);
1946+
SDL_SetPixelFormatPalette(format, surf->format->palette);
19541947
}
19551948
else {
19561949
/* Give the surface something other than an all white
19571950
* palette.
19581951
*/
19591952
SDL_SetPaletteColors(palette, default_palette_colors, 0,
19601953
default_palette_size);
1961-
SDL_SetPixelFormatPalette(&format, palette);
1954+
SDL_SetPixelFormatPalette(format, palette);
19621955
}
19631956
}
1964-
newsurf = PG_ConvertSurface(surf, &format);
1957+
newsurf = PG_ConvertSurface(surf, format);
19651958
SDL_SetSurfaceBlendMode(newsurf, SDL_BLENDMODE_NONE);
1959+
SDL_FreeFormat(format);
19661960
SDL_FreePalette(palette);
19671961
}
19681962
}
@@ -4540,29 +4534,13 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45404534
}
45414535
else {
45424536
SDL_PixelFormat *fmt = src->format;
4543-
SDL_PixelFormat newfmt;
4537+
SDL_PixelFormat *newfmt =
4538+
SDL_AllocFormat(SDL_MasksToPixelFormatEnum(
4539+
fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, 0));
45444540

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);
4541+
src = PG_ConvertSurface(src, newfmt);
4542+
4543+
SDL_FreeFormat(newfmt);
45664544
if (src) {
45674545
#if SDL_VERSION_ATLEAST(3, 0, 0)
45684546
result = SDL_BlitSurface(src, srcrect, dst, dstrect) ? 0 : -1;

0 commit comments

Comments
 (0)