Skip to content

Commit 49755eb

Browse files
authored
Merge pull request #3308 from Starbuck5/pixelcopy-sdl3
Pixelcopy SDL3
2 parents cc1d859 + 6516a4b commit 49755eb

File tree

2 files changed

+57
-24
lines changed

2 files changed

+57
-24
lines changed

src_c/meson.build

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,6 @@ math = py.extension_module(
270270
subdir: pg,
271271
)
272272

273-
# TODO: support SDL3
274-
if sdl_api != 3
275273
pixelcopy = py.extension_module(
276274
'pixelcopy',
277275
'pixelcopy.c',
@@ -280,7 +278,6 @@ pixelcopy = py.extension_module(
280278
install: true,
281279
subdir: pg,
282280
)
283-
endif
284281

285282
newbuffer = py.extension_module(
286283
'newbuffer',

src_c/pixelcopy.c

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828

2929
#include "doc/pixelcopy_doc.h"
3030

31-
#include <SDL_endian.h>
32-
3331
typedef enum {
3432
PXC_VIEWKIND_RED,
3533
PXC_VIEWKIND_GREEN,
@@ -256,7 +254,6 @@ static int
256254
_copy_colorplane(Py_buffer *view_p, SDL_Surface *surf,
257255
_pc_view_kind_t view_kind, Uint8 opaque, Uint8 clear)
258256
{
259-
SDL_PixelFormat *format = surf->format;
260257
int pixelsize = PG_SURF_BytesPerPixel(surf);
261258
SDL_BlendMode mode;
262259
int intsize = (int)view_p->itemsize;
@@ -275,6 +272,8 @@ _copy_colorplane(Py_buffer *view_p, SDL_Surface *surf,
275272
Uint8 *element = 0;
276273
_pc_pixel_t pixel = {0};
277274
Uint32 colorkey;
275+
PG_PixelFormat *format;
276+
SDL_Palette *palette;
278277

279278
if (view_p->shape[0] != w || view_p->shape[1] != h) {
280279
PyErr_Format(PyExc_ValueError,
@@ -288,10 +287,21 @@ _copy_colorplane(Py_buffer *view_p, SDL_Surface *surf,
288287
intsize);
289288
return -1;
290289
}
291-
if (SDL_GetSurfaceBlendMode(surf, &mode) < 0) {
290+
#if SDL_VERSION_ATLEAST(3, 0, 0)
291+
if (!SDL_GetSurfaceBlendMode(surf, &mode))
292+
#else
293+
if (SDL_GetSurfaceBlendMode(surf, &mode) < 0)
294+
#endif
295+
{
296+
PyErr_SetString(pgExc_SDLError, SDL_GetError());
297+
return -1;
298+
}
299+
300+
if (!PG_GetSurfaceDetails(surf, &format, &palette)) {
292301
PyErr_SetString(pgExc_SDLError, SDL_GetError());
293302
return -1;
294303
}
304+
295305
/* Select appropriate color plane element within the pixel */
296306
switch (view_kind) {
297307
case PXC_VIEWKIND_RED:
@@ -344,7 +354,7 @@ _copy_colorplane(Py_buffer *view_p, SDL_Surface *surf,
344354
for (z = 0; z < pixelsize; ++z) {
345355
pixel.bytes[dz_pix + z] = src[dx_src * x + dy_src * y + z];
346356
}
347-
SDL_GetRGBA(pixel.value, format, &r, &g, &b, &a);
357+
PG_GetRGBA(pixel.value, format, palette, &r, &g, &b, &a);
348358
dst[dx_dst * x + dy_dst * y] = *element;
349359
for (z = 1; z < intsize; ++z) {
350360
dst[dx_dst * x + dy_dst * y + dz_dst * z] = 0;
@@ -369,7 +379,6 @@ _copy_colorplane(Py_buffer *view_p, SDL_Surface *surf,
369379
static int
370380
_copy_unmapped(Py_buffer *view_p, SDL_Surface *surf)
371381
{
372-
SDL_PixelFormat *format = surf->format;
373382
int pixelsize = PG_SURF_BytesPerPixel(surf);
374383
int intsize = (int)view_p->itemsize;
375384
char *src = (char *)surf->pixels;
@@ -414,12 +423,21 @@ _copy_unmapped(Py_buffer *view_p, SDL_Surface *surf)
414423
dz_dst = -1;
415424
}
416425
#endif
426+
427+
PG_PixelFormat *format;
428+
SDL_Palette *palette;
429+
430+
if (!PG_GetSurfaceDetails(surf, &format, &palette)) {
431+
PyErr_SetString(pgExc_SDLError, SDL_GetError());
432+
return -1;
433+
}
434+
417435
for (x = 0; x < w; ++x) {
418436
for (y = 0; y < h; ++y) {
419437
for (z = 0; z < pixelsize; ++z) {
420438
pixel.bytes[dz_pix + z] = src[dx_src * x + dy_src * y + z];
421439
}
422-
SDL_GetRGB(pixel.value, format, &r, &g, &b);
440+
PG_GetRGB(pixel.value, format, palette, &r, &g, &b);
423441
dst[dx_dst * x + dy_dst * y] = r;
424442
for (z = 1; z < intsize; ++z) {
425443
dst[dx_dst * x + dy_dst * y + dz_dst * z] = 0;
@@ -469,16 +487,14 @@ array_to_surface(PyObject *self, PyObject *arg)
469487
Py_buffer *view_p = (Py_buffer *)&pg_view;
470488
char *array_data;
471489
SDL_Surface *surf;
472-
SDL_PixelFormat *format;
473490
int loopx, loopy;
474491
Py_ssize_t stridex, stridey, stridez = 0, stridez2 = 0, sizex, sizey;
475-
int Rloss, Gloss, Bloss, Rshift, Gshift, Bshift;
492+
int Rloss, Gloss, Bloss, Aloss, Rshift, Gshift, Bshift, Ashift;
476493

477494
if (!PyArg_ParseTuple(arg, "O!O", &pgSurface_Type, &surfobj, &arrayobj)) {
478495
return NULL;
479496
}
480497
surf = pgSurface_AsSurface(surfobj);
481-
format = surf->format;
482498

483499
if (pgObject_GetBuffer(arrayobj, &pg_view, PyBUF_RECORDS_RO)) {
484500
return 0;
@@ -507,12 +523,21 @@ array_to_surface(PyObject *self, PyObject *arg)
507523
}
508524
sizex = view_p->shape[0];
509525
sizey = view_p->shape[1];
510-
Rloss = format->Rloss;
511-
Gloss = format->Gloss;
512-
Bloss = format->Bloss;
526+
527+
PG_PixelFormat *format;
528+
SDL_Palette *palette;
529+
if (!PG_GetSurfaceDetails(surf, &format, &palette)) {
530+
return RAISE(pgExc_SDLError, SDL_GetError());
531+
}
532+
513533
Rshift = format->Rshift;
514534
Gshift = format->Gshift;
515535
Bshift = format->Bshift;
536+
Ashift = format->Ashift;
537+
Rloss = PG_FORMAT_R_LOSS(format);
538+
Gloss = PG_FORMAT_G_LOSS(format);
539+
Bloss = PG_FORMAT_B_LOSS(format);
540+
Aloss = PG_FORMAT_A_LOSS(format);
516541

517542
/* Do any required broadcasting. */
518543
if (sizex == 1) {
@@ -593,7 +618,7 @@ array_to_surface(PyObject *self, PyObject *arg)
593618
else {
594619
Uint16 alpha = 0;
595620
if (format->Amask) {
596-
alpha = 255 >> format->Aloss << format->Ashift;
621+
alpha = 255 >> Aloss << Ashift;
597622
}
598623
switch (view_p->itemsize) {
599624
case sizeof(Uint8):
@@ -713,7 +738,7 @@ array_to_surface(PyObject *self, PyObject *arg)
713738
else {
714739
Uint32 alpha = 0;
715740
if (format->Amask) {
716-
alpha = 255 >> format->Aloss << format->Ashift;
741+
alpha = 255 >> Aloss << Ashift;
717742
}
718743
switch (view_p->itemsize) {
719744
case sizeof(Uint8):
@@ -839,7 +864,6 @@ map_array(PyObject *self, PyObject *args)
839864
PyObject *src_array;
840865
PyObject *tar_array;
841866
pgSurfaceObject *format_surf;
842-
SDL_PixelFormat *format;
843867
pg_buffer src_pg_view;
844868
Py_buffer *src_view_p;
845869
Uint8 is_src_alloc = 0;
@@ -962,7 +986,14 @@ map_array(PyObject *self, PyObject *args)
962986

963987
/* Determine source and destination pixel formats
964988
*/
965-
format = pgSurface_AsSurface(format_surf)->format;
989+
990+
PG_PixelFormat *format;
991+
SDL_Palette *palette;
992+
if (!PG_GetSurfaceDetails(pgSurface_AsSurface(format_surf), &format,
993+
&palette)) {
994+
return RAISE(pgExc_SDLError, SDL_GetError());
995+
}
996+
966997
pix_bytesize = PG_FORMAT_BytesPerPixel(format);
967998
if (tar_itemsize < pix_bytesize) {
968999
PyErr_SetString(PyExc_ValueError,
@@ -1078,8 +1109,8 @@ map_array(PyObject *self, PyObject *args)
10781109
else if (dim == topdim) {
10791110
/* Next iteration of inner most loop: copy pixel
10801111
*/
1081-
pixel.value = SDL_MapRGB(format, src[src_red], src[src_green],
1082-
src[src_blue]);
1112+
pixel.value = PG_MapRGB(format, palette, src[src_red],
1113+
src[src_green], src[src_blue]);
10831114
/* Bytes are copied from the pixel in most to least significant
10841115
* byte order. If destination bytes get overwritten, when the
10851116
* destination size is less than 4 bytes, only zero pad bytes
@@ -1170,11 +1201,16 @@ make_surface(PyObject *self, PyObject *arg)
11701201
pgBuffer_Release(&pg_view);
11711202
return RAISE(pgExc_SDLError, SDL_GetError());
11721203
}
1204+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1205+
SDL_Palette *palette = SDL_GetSurfacePalette(surf);
1206+
#else
1207+
SDL_Palette *palette = surf->format->palette;
1208+
#endif
11731209
if (SDL_ISPIXELFORMAT_INDEXED(PG_SURF_FORMATENUM(surf))) {
11741210
/* Give the surface something other than an all white palette.
11751211
* */
1176-
if (SDL_SetPaletteColors(surf->format->palette, default_palette_colors,
1177-
0, default_palette_size - 1) != 0) {
1212+
if (SDL_SetPaletteColors(palette, default_palette_colors, 0,
1213+
default_palette_size - 1) != 0) {
11781214
PyErr_SetString(pgExc_SDLError, SDL_GetError());
11791215
SDL_FreeSurface(surf);
11801216
return 0;

0 commit comments

Comments
 (0)