From 23e9a38d933d68abdfc3f3671a140cbb1222df0a Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Mon, 2 Oct 2023 08:45:07 -0300 Subject: [PATCH 01/19] Fix issue #2446: rotozoom keeps the colorkey flag. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joras Co-authored-by: Antonio Co-authored-by: João Co-authored-by: Caio Co-authored-by: Cícero Co-authored-by: Natália --- src_c/rotozoom.c | 16 ++++++++++++++++ src_c/transform.c | 3 +++ test/transform_test.py | 11 +++++++++++ 3 files changed, 30 insertions(+) diff --git a/src_c/rotozoom.c b/src_c/rotozoom.c index 787b5a8afd..c5b188f667 100644 --- a/src_c/rotozoom.c +++ b/src_c/rotozoom.c @@ -511,6 +511,7 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) int dstwidth, dstheight; int is32bit; int src_converted; + Uint32 colorkey; /* * Sanity check @@ -556,6 +557,7 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) /* * ----------------------- */ + int dstwidthhalf, dstheighthalf; double sanglezoom, canglezoom, sanglezoominv, canglezoominv; @@ -583,6 +585,13 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) * Target surface is 32bit with source RGBA/ABGR ordering */ rz_dst = PG_CreateSurface(dstwidth, dstheight, rz_src->format->format); + if (SDL_GetColorKey(src, &colorkey) == 0) { + if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0 || + SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { + SDL_FreeSurface(rz_dst); + return NULL; + } + } /* * Lock source surface @@ -629,6 +638,13 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) * Target surface is 32bit with source RGBA/ABGR ordering */ rz_dst = PG_CreateSurface(dstwidth, dstheight, rz_src->format->format); + if (SDL_GetColorKey(src, &colorkey) == 0) { + if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0 || + SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { + SDL_FreeSurface(rz_dst); + return NULL; + } + } /* * Lock source surface diff --git a/src_c/transform.c b/src_c/transform.c index 5a5d10faa6..ca57ec4992 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -890,6 +890,9 @@ surf_rotozoom(PyObject *self, PyObject *args, PyObject *kwargs) Py_BEGIN_ALLOW_THREADS; newsurf = rotozoomSurface(surf32, angle, scale, 1); + if (newsurf == NULL) { + PyErr_SetString(pgExc_SDLError, SDL_GetError()); + } Py_END_ALLOW_THREADS; if (surf32 == surf) diff --git a/test/transform_test.py b/test/transform_test.py index af1c6109d1..e543e62a86 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -1287,6 +1287,17 @@ def test_rotozoom(self): self.assertEqual(s1.get_rect(), pygame.Rect(0, 0, 0, 0)) self.assertEqual(s2.get_rect(), pygame.Rect(0, 0, 0, 0)) + def test_rotozoom_keeps_colorkey(self): + image = pygame.Surface((64, 64)) + image.set_colorkey('black') + pygame.draw.circle(image, 'red', (32, 32), 32, width=0) + + no_rot = pygame.transform.rotozoom(image, 0, 1.1) + self.assertEqual(image.get_colorkey(), no_rot.get_colorkey()) + + with_rot = pygame.transform.rotozoom(image, 5, 1.1) + self.assertEqual(image.get_colorkey(), with_rot.get_colorkey()) + def test_invert(self): surface = pygame.Surface((10, 10), depth=32) From 21b7fe8a7de07f942b2c5f1175f977db1502ae9e Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Mon, 2 Oct 2023 09:00:35 -0300 Subject: [PATCH 02/19] Remove empty line --- src_c/rotozoom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src_c/rotozoom.c b/src_c/rotozoom.c index c5b188f667..f16748a486 100644 --- a/src_c/rotozoom.c +++ b/src_c/rotozoom.c @@ -557,7 +557,6 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) /* * ----------------------- */ - int dstwidthhalf, dstheighthalf; double sanglezoom, canglezoom, sanglezoominv, canglezoominv; From 41b21943b77e27e6ce2abba42ee72b9435cb676e Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Wed, 4 Oct 2023 08:02:11 -0300 Subject: [PATCH 03/19] Run black --- test/transform_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/transform_test.py b/test/transform_test.py index e543e62a86..a976800f2e 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -1289,8 +1289,8 @@ def test_rotozoom(self): def test_rotozoom_keeps_colorkey(self): image = pygame.Surface((64, 64)) - image.set_colorkey('black') - pygame.draw.circle(image, 'red', (32, 32), 32, width=0) + image.set_colorkey("black") + pygame.draw.circle(image, "red", (32, 32), 32, width=0) no_rot = pygame.transform.rotozoom(image, 0, 1.1) self.assertEqual(image.get_colorkey(), no_rot.get_colorkey()) From 02988ae2f7e71db2695fa80bfc133b31346272c0 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Wed, 4 Oct 2023 08:05:15 -0300 Subject: [PATCH 04/19] Fix use of PyErr_SetString inside nogil --- src_c/transform.c | 140 ++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 73 deletions(-) diff --git a/src_c/transform.c b/src_c/transform.c index ca57ec4992..2834ca7c0e 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -890,10 +890,11 @@ surf_rotozoom(PyObject *self, PyObject *args, PyObject *kwargs) Py_BEGIN_ALLOW_THREADS; newsurf = rotozoomSurface(surf32, angle, scale, 1); + Py_END_ALLOW_THREADS; if (newsurf == NULL) { PyErr_SetString(pgExc_SDLError, SDL_GetError()); + return NULL; } - Py_END_ALLOW_THREADS; if (surf32 == surf) pgSurface_Unlock(surfobj); @@ -1955,86 +1956,79 @@ clamp_4 */ -#define SURF_GET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, p_pix) \ - switch (p_format->BytesPerPixel) { \ - case 1: \ - p_color = (Uint32) * \ - ((Uint8 *)(p_pixels) + (p_y) * p_surf->pitch + (p_x)); \ - break; \ - case 2: \ - p_color = \ - (Uint32) * \ - ((Uint16 *)((p_pixels) + (p_y) * p_surf->pitch) + (p_x)); \ - break; \ - case 3: \ - p_pix = \ - ((Uint8 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x) * 3); \ - p_color = (SDL_BYTEORDER == SDL_LIL_ENDIAN) \ - ? (p_pix[0]) + (p_pix[1] << 8) + (p_pix[2] << 16) \ - : (p_pix[2]) + (p_pix[1] << 8) + (p_pix[0] << 16); \ - break; \ - default: /* case 4: */ \ - p_color = \ - *((Uint32 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)); \ - break; \ +#define SURF_GET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, p_pix) \ + switch (p_format->BytesPerPixel) { \ + case 1: \ + p_color = (Uint32) * \ + ((Uint8 *)(p_pixels) + (p_y)*p_surf->pitch + (p_x)); \ + break; \ + case 2: \ + p_color = (Uint32) * \ + ((Uint16 *)((p_pixels) + (p_y)*p_surf->pitch) + (p_x)); \ + break; \ + case 3: \ + p_pix = ((Uint8 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)*3); \ + p_color = (SDL_BYTEORDER == SDL_LIL_ENDIAN) \ + ? (p_pix[0]) + (p_pix[1] << 8) + (p_pix[2] << 16) \ + : (p_pix[2]) + (p_pix[1] << 8) + (p_pix[0] << 16); \ + break; \ + default: /* case 4: */ \ + p_color = *((Uint32 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)); \ + break; \ } #if (SDL_BYTEORDER == SDL_LIL_ENDIAN) -#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ - p_byte_buf) \ - switch (p_format->BytesPerPixel) { \ - case 1: \ - *((Uint8 *)p_pixels + (p_y) * p_surf->pitch + (p_x)) = \ - (Uint8)p_color; \ - break; \ - case 2: \ - *((Uint16 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ - (Uint16)p_color; \ - break; \ - case 3: \ - p_byte_buf = \ - (Uint8 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x) * 3; \ - *(p_byte_buf + (p_format->Rshift >> 3)) = \ - (Uint8)(p_color >> p_format->Rshift); \ - *(p_byte_buf + (p_format->Gshift >> 3)) = \ - (Uint8)(p_color >> p_format->Gshift); \ - *(p_byte_buf + (p_format->Bshift >> 3)) = \ - (Uint8)(p_color >> p_format->Bshift); \ - break; \ - default: \ - *((Uint32 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ - p_color; \ - break; \ +#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ + p_byte_buf) \ + switch (p_format->BytesPerPixel) { \ + case 1: \ + *((Uint8 *)p_pixels + (p_y)*p_surf->pitch + (p_x)) = \ + (Uint8)p_color; \ + break; \ + case 2: \ + *((Uint16 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = \ + (Uint16)p_color; \ + break; \ + case 3: \ + p_byte_buf = (Uint8 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)*3; \ + *(p_byte_buf + (p_format->Rshift >> 3)) = \ + (Uint8)(p_color >> p_format->Rshift); \ + *(p_byte_buf + (p_format->Gshift >> 3)) = \ + (Uint8)(p_color >> p_format->Gshift); \ + *(p_byte_buf + (p_format->Bshift >> 3)) = \ + (Uint8)(p_color >> p_format->Bshift); \ + break; \ + default: \ + *((Uint32 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = p_color; \ + break; \ } #else -#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ - p_byte_buf) \ - switch (p_format->BytesPerPixel) { \ - case 1: \ - *((Uint8 *)p_pixels + (p_y) * p_surf->pitch + (p_x)) = \ - (Uint8)p_color; \ - break; \ - case 2: \ - *((Uint16 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ - (Uint16)p_color; \ - break; \ - case 3: \ - p_byte_buf = \ - (Uint8 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x) * 3; \ - *(p_byte_buf + 2 - (p_format->Rshift >> 3)) = \ - (Uint8)(p_color >> p_format->Rshift); \ - *(p_byte_buf + 2 - (p_format->Gshift >> 3)) = \ - (Uint8)(p_color >> p_format->Gshift); \ - *(p_byte_buf + 2 - (p_format->Bshift >> 3)) = \ - (Uint8)(p_color >> p_format->Bshift); \ - break; \ - default: \ - *((Uint32 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ - p_color; \ - break; \ +#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ + p_byte_buf) \ + switch (p_format->BytesPerPixel) { \ + case 1: \ + *((Uint8 *)p_pixels + (p_y)*p_surf->pitch + (p_x)) = \ + (Uint8)p_color; \ + break; \ + case 2: \ + *((Uint16 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = \ + (Uint16)p_color; \ + break; \ + case 3: \ + p_byte_buf = (Uint8 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)*3; \ + *(p_byte_buf + 2 - (p_format->Rshift >> 3)) = \ + (Uint8)(p_color >> p_format->Rshift); \ + *(p_byte_buf + 2 - (p_format->Gshift >> 3)) = \ + (Uint8)(p_color >> p_format->Gshift); \ + *(p_byte_buf + 2 - (p_format->Bshift >> 3)) = \ + (Uint8)(p_color >> p_format->Bshift); \ + break; \ + default: \ + *((Uint32 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = p_color; \ + break; \ } #endif From 86453b09c2457b32850b2c84588a62d08f557207 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 5 Oct 2023 19:52:23 +0100 Subject: [PATCH 05/19] Formatting --- src_c/transform.c | 137 ++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/src_c/transform.c b/src_c/transform.c index 2834ca7c0e..8bb3d9fe1a 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -1956,79 +1956,86 @@ clamp_4 */ -#define SURF_GET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, p_pix) \ - switch (p_format->BytesPerPixel) { \ - case 1: \ - p_color = (Uint32) * \ - ((Uint8 *)(p_pixels) + (p_y)*p_surf->pitch + (p_x)); \ - break; \ - case 2: \ - p_color = (Uint32) * \ - ((Uint16 *)((p_pixels) + (p_y)*p_surf->pitch) + (p_x)); \ - break; \ - case 3: \ - p_pix = ((Uint8 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)*3); \ - p_color = (SDL_BYTEORDER == SDL_LIL_ENDIAN) \ - ? (p_pix[0]) + (p_pix[1] << 8) + (p_pix[2] << 16) \ - : (p_pix[2]) + (p_pix[1] << 8) + (p_pix[0] << 16); \ - break; \ - default: /* case 4: */ \ - p_color = *((Uint32 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)); \ - break; \ +#define SURF_GET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, p_pix) \ + switch (p_format->BytesPerPixel) { \ + case 1: \ + p_color = (Uint32) * \ + ((Uint8 *)(p_pixels) + (p_y) * p_surf->pitch + (p_x)); \ + break; \ + case 2: \ + p_color = \ + (Uint32) * \ + ((Uint16 *)((p_pixels) + (p_y) * p_surf->pitch) + (p_x)); \ + break; \ + case 3: \ + p_pix = \ + ((Uint8 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x) * 3); \ + p_color = (SDL_BYTEORDER == SDL_LIL_ENDIAN) \ + ? (p_pix[0]) + (p_pix[1] << 8) + (p_pix[2] << 16) \ + : (p_pix[2]) + (p_pix[1] << 8) + (p_pix[0] << 16); \ + break; \ + default: /* case 4: */ \ + p_color = \ + *((Uint32 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)); \ + break; \ } #if (SDL_BYTEORDER == SDL_LIL_ENDIAN) -#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ - p_byte_buf) \ - switch (p_format->BytesPerPixel) { \ - case 1: \ - *((Uint8 *)p_pixels + (p_y)*p_surf->pitch + (p_x)) = \ - (Uint8)p_color; \ - break; \ - case 2: \ - *((Uint16 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = \ - (Uint16)p_color; \ - break; \ - case 3: \ - p_byte_buf = (Uint8 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)*3; \ - *(p_byte_buf + (p_format->Rshift >> 3)) = \ - (Uint8)(p_color >> p_format->Rshift); \ - *(p_byte_buf + (p_format->Gshift >> 3)) = \ - (Uint8)(p_color >> p_format->Gshift); \ - *(p_byte_buf + (p_format->Bshift >> 3)) = \ - (Uint8)(p_color >> p_format->Bshift); \ - break; \ - default: \ - *((Uint32 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = p_color; \ - break; \ +#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ + p_byte_buf) \ + switch (p_format->BytesPerPixel) { \ + case 1: \ + *((Uint8 *)p_pixels + (p_y) * p_surf->pitch + (p_x)) = \ + (Uint8)p_color; \ + break; \ + case 2: \ + *((Uint16 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ + (Uint16)p_color; \ + break; \ + case 3: \ + p_byte_buf = \ + (Uint8 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x) * 3; \ + *(p_byte_buf + (p_format->Rshift >> 3)) = \ + (Uint8)(p_color >> p_format->Rshift); \ + *(p_byte_buf + (p_format->Gshift >> 3)) = \ + (Uint8)(p_color >> p_format->Gshift); \ + *(p_byte_buf + (p_format->Bshift >> 3)) = \ + (Uint8)(p_color >> p_format->Bshift); \ + break; \ + default: \ + *((Uint32 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ + p_color; \ + break; \ } #else -#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ - p_byte_buf) \ - switch (p_format->BytesPerPixel) { \ - case 1: \ - *((Uint8 *)p_pixels + (p_y)*p_surf->pitch + (p_x)) = \ - (Uint8)p_color; \ - break; \ - case 2: \ - *((Uint16 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = \ - (Uint16)p_color; \ - break; \ - case 3: \ - p_byte_buf = (Uint8 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)*3; \ - *(p_byte_buf + 2 - (p_format->Rshift >> 3)) = \ - (Uint8)(p_color >> p_format->Rshift); \ - *(p_byte_buf + 2 - (p_format->Gshift >> 3)) = \ - (Uint8)(p_color >> p_format->Gshift); \ - *(p_byte_buf + 2 - (p_format->Bshift >> 3)) = \ - (Uint8)(p_color >> p_format->Bshift); \ - break; \ - default: \ - *((Uint32 *)(p_pixels + (p_y)*p_surf->pitch) + (p_x)) = p_color; \ - break; \ +#define SURF_SET_AT(p_color, p_surf, p_x, p_y, p_pixels, p_format, \ + p_byte_buf) \ + switch (p_format->BytesPerPixel) { \ + case 1: \ + *((Uint8 *)p_pixels + (p_y) * p_surf->pitch + (p_x)) = \ + (Uint8)p_color; \ + break; \ + case 2: \ + *((Uint16 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ + (Uint16)p_color; \ + break; \ + case 3: \ + p_byte_buf = \ + (Uint8 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x) * 3; \ + *(p_byte_buf + 2 - (p_format->Rshift >> 3)) = \ + (Uint8)(p_color >> p_format->Rshift); \ + *(p_byte_buf + 2 - (p_format->Gshift >> 3)) = \ + (Uint8)(p_color >> p_format->Gshift); \ + *(p_byte_buf + 2 - (p_format->Bshift >> 3)) = \ + (Uint8)(p_color >> p_format->Bshift); \ + break; \ + default: \ + *((Uint32 *)(p_pixels + (p_y) * p_surf->pitch) + (p_x)) = \ + p_color; \ + break; \ } #endif From 9457d58d76fc5b5d86957cd1d2711ade95a00b47 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Wed, 25 Oct 2023 09:30:14 -0300 Subject: [PATCH 06/19] Requested changes regarding RLE --- src_c/_pygame.h | 4 +++- src_c/rotozoom.c | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 7a2f069ef9..00595f2438 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -72,6 +72,8 @@ #define PG_ConvertSurface SDL_ConvertSurface #define PG_ConvertSurfaceFormat SDL_ConvertSurfaceFormat +#define PG_SurfaceHasRLE(src) SDL_SurfaceHasRLE(src) + #else /* ~SDL_VERSION_ATLEAST(3, 0, 0)*/ #define PG_ShowCursor() SDL_ShowCursor(SDL_ENABLE) #define PG_HideCursor() SDL_ShowCursor(SDL_DISABLE) @@ -100,7 +102,7 @@ #define PG_ConvertSurface(src, fmt) SDL_ConvertSurface(src, fmt, 0) #define PG_ConvertSurfaceFormat(src, pixel_format) \ SDL_ConvertSurfaceFormat(src, pixel_format, 0) - +#define PG_SurfaceHasRLE(src) SDL_HasSurfaceRLE(src) #endif /* DictProxy is useful for event posting with an arbitrary dict. Maintains diff --git a/src_c/rotozoom.c b/src_c/rotozoom.c index f16748a486..b693088087 100644 --- a/src_c/rotozoom.c +++ b/src_c/rotozoom.c @@ -11,6 +11,7 @@ */ +#include "_pygame.h" #define NO_PYGAME_C_API #include "pygame.h" @@ -585,8 +586,11 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) */ rz_dst = PG_CreateSurface(dstwidth, dstheight, rz_src->format->format); if (SDL_GetColorKey(src, &colorkey) == 0) { - if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0 || - SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { + if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0) { + SDL_FreeSurface(rz_dst); + return NULL; + } + if (PG_SurfaceHasRLE(src) && SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { SDL_FreeSurface(rz_dst); return NULL; } @@ -636,10 +640,14 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) /* * Target surface is 32bit with source RGBA/ABGR ordering */ + rz_dst = PG_CreateSurface(dstwidth, dstheight, rz_src->format->format); if (SDL_GetColorKey(src, &colorkey) == 0) { - if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0 || - SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { + if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0) { + SDL_FreeSurface(rz_dst); + return NULL; + } + if (PG_SurfaceHasRLE(src) && SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { SDL_FreeSurface(rz_dst); return NULL; } From 2544e8e1535e3e3533c870066ae6adec87cbd1cb Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 11:30:47 +0100 Subject: [PATCH 07/19] clang format pass --- src_c/rotozoom.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src_c/rotozoom.c b/src_c/rotozoom.c index b693088087..d6a4aae1d0 100644 --- a/src_c/rotozoom.c +++ b/src_c/rotozoom.c @@ -590,7 +590,8 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) SDL_FreeSurface(rz_dst); return NULL; } - if (PG_SurfaceHasRLE(src) && SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { + if (PG_SurfaceHasRLE(src) && + SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { SDL_FreeSurface(rz_dst); return NULL; } @@ -647,7 +648,8 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth) SDL_FreeSurface(rz_dst); return NULL; } - if (PG_SurfaceHasRLE(src) && SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { + if (PG_SurfaceHasRLE(src) && + SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) { SDL_FreeSurface(rz_dst); return NULL; } From 243ffcd0bc6584ebb3e7c48adbd293fcee4631a0 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 11:45:14 +0100 Subject: [PATCH 08/19] define fixes --- src_c/_pygame.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 00595f2438..8eb783a6f8 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -72,7 +72,7 @@ #define PG_ConvertSurface SDL_ConvertSurface #define PG_ConvertSurfaceFormat SDL_ConvertSurfaceFormat -#define PG_SurfaceHasRLE(src) SDL_SurfaceHasRLE(src) +#define PG_SurfaceHasRLE SDL_SurfaceHasRLE #else /* ~SDL_VERSION_ATLEAST(3, 0, 0)*/ #define PG_ShowCursor() SDL_ShowCursor(SDL_ENABLE) @@ -102,7 +102,7 @@ #define PG_ConvertSurface(src, fmt) SDL_ConvertSurface(src, fmt, 0) #define PG_ConvertSurfaceFormat(src, pixel_format) \ SDL_ConvertSurfaceFormat(src, pixel_format, 0) -#define PG_SurfaceHasRLE(src) SDL_HasSurfaceRLE(src) +#define PG_SurfaceHasRLE SDL_HasSurfaceRLE #endif /* DictProxy is useful for event posting with an arbitrary dict. Maintains From 55b71b4dca0bffa0e65c4d3505c09807f0b4e890 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 12:37:55 +0100 Subject: [PATCH 09/19] vendor in SurfaceHasRLE function was added in 2.0.14 - min SDL version currently 2.0.9 --- src_c/_pygame.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 8eb783a6f8..1ca180e1a3 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -102,7 +102,25 @@ #define PG_ConvertSurface(src, fmt) SDL_ConvertSurface(src, fmt, 0) #define PG_ConvertSurfaceFormat(src, pixel_format) \ SDL_ConvertSurfaceFormat(src, pixel_format, 0) +#if SDL_VERSION_ATLEAST(2, 0, 14) #define PG_SurfaceHasRLE SDL_HasSurfaceRLE +#else +// vendored in until our lowest SDL version is 2.0.14 +SDL_bool +PG_SurfaceHasRLE(SDL_Surface *surface) +{ + if (surface == NULL) { + return SDL_FALSE; + } + + if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { + return SDL_FALSE; + } + + return SDL_TRUE; +} +#endif + #endif /* DictProxy is useful for event posting with an arbitrary dict. Maintains From 5825972f3b7dec20003eae1f7074cbeceba92151 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 12:50:30 +0100 Subject: [PATCH 10/19] vendor in SurfaceHasRLE --- src_c/_pygame.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 1ca180e1a3..c4834dbed2 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -106,6 +106,9 @@ #define PG_SurfaceHasRLE SDL_HasSurfaceRLE #else // vendored in until our lowest SDL version is 2.0.14 +#include "_blit_info.h" +#define SDL_COPY_RLE_DESIRED 0x00001000 + SDL_bool PG_SurfaceHasRLE(SDL_Surface *surface) { From e599e737d00e13612862d39d8bff0467cb25233c Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 13:05:00 +0100 Subject: [PATCH 11/19] vendor in SurfaceHasRLE --- src_c/_pygame.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index c4834dbed2..4570088049 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -106,7 +106,19 @@ #define PG_SurfaceHasRLE SDL_HasSurfaceRLE #else // vendored in until our lowest SDL version is 2.0.14 -#include "_blit_info.h" +struct SDL_BlitMap +{ + SDL_Surface *dst; + int identity; + SDL_blit blit; + void *data; + SDL_BlitInfo info; + + /* the version count matches the destination; mismatch indicates + an invalid mapping */ + Uint32 dst_palette_version; + Uint32 src_palette_version; +}; #define SDL_COPY_RLE_DESIRED 0x00001000 SDL_bool From fc1810197cd7d64eba6a788c44967374b06f38ed Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 13:25:29 +0100 Subject: [PATCH 12/19] vendor in SurfaceHasRLE --- src_c/_pygame.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 4570088049..5a27fe5b1e 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -106,8 +106,25 @@ #define PG_SurfaceHasRLE SDL_HasSurfaceRLE #else // vendored in until our lowest SDL version is 2.0.14 -struct SDL_BlitMap -{ +typedef struct { + int width; + int height; + Uint8 *s_pixels; + int s_pxskip; + int s_skip; + Uint8 *d_pixels; + int d_pxskip; + int d_skip; + SDL_PixelFormat *src; + SDL_PixelFormat *dst; + Uint8 src_blanket_alpha; + int src_has_colorkey; + Uint32 src_colorkey; + SDL_BlendMode src_blend; + SDL_BlendMode dst_blend; +} SDL_BlitInfo; + +struct SDL_BlitMap { SDL_Surface *dst; int identity; SDL_blit blit; From a359583e8f734a61af09b9f7afc75c779dc870b9 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 13:34:08 +0100 Subject: [PATCH 13/19] vendor in SurfaceHasRLE --- src_c/_pygame.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 5a27fe5b1e..3bf023a8fa 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -107,21 +107,20 @@ #else // vendored in until our lowest SDL version is 2.0.14 typedef struct { - int width; - int height; - Uint8 *s_pixels; - int s_pxskip; - int s_skip; - Uint8 *d_pixels; - int d_pxskip; - int d_skip; - SDL_PixelFormat *src; - SDL_PixelFormat *dst; - Uint8 src_blanket_alpha; - int src_has_colorkey; - Uint32 src_colorkey; - SDL_BlendMode src_blend; - SDL_BlendMode dst_blend; + Uint8 *src; + int src_w, src_h; + int src_pitch; + int src_skip; + Uint8 *dst; + int dst_w, dst_h; + int dst_pitch; + int dst_skip; + SDL_PixelFormat *src_fmt; + SDL_PixelFormat *dst_fmt; + Uint8 *table; + int flags; + Uint32 colorkey; + Uint8 r, g, b, a; } SDL_BlitInfo; struct SDL_BlitMap { From 8c6f8bdc38f1fdb4bae57a2d82453616069bdbb4 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 13:56:47 +0100 Subject: [PATCH 14/19] vendor in SurfaceHasRLE --- src_c/_pygame.h | 13 +------------ src_c/rotozoom.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 3bf023a8fa..e5bb3b8c36 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -138,18 +138,7 @@ struct SDL_BlitMap { #define SDL_COPY_RLE_DESIRED 0x00001000 SDL_bool -PG_SurfaceHasRLE(SDL_Surface *surface) -{ - if (surface == NULL) { - return SDL_FALSE; - } - - if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { - return SDL_FALSE; - } - - return SDL_TRUE; -} +PG_SurfaceHasRLE(SDL_Surface *surface); #endif #endif diff --git a/src_c/rotozoom.c b/src_c/rotozoom.c index d6a4aae1d0..88696d3d08 100644 --- a/src_c/rotozoom.c +++ b/src_c/rotozoom.c @@ -12,6 +12,22 @@ */ #include "_pygame.h" + +#if !SDL_VERSION_ATLEAST(2, 0, 14) +SDL_bool +PG_SurfaceHasRLE(SDL_Surface *surface) +{ + if (surface == NULL) { + return SDL_FALSE; + } + + if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { + return SDL_FALSE; + } + + return SDL_TRUE; +} +#endif #define NO_PYGAME_C_API #include "pygame.h" From 1597c1e956f26490a08dcf59fcf7d246f1f2ff0e Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 26 Oct 2023 14:10:15 +0100 Subject: [PATCH 15/19] vendor in SurfaceHasRLE --- src_c/_pygame.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index e5bb3b8c36..2d14b1e44c 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -121,14 +121,14 @@ typedef struct { int flags; Uint32 colorkey; Uint8 r, g, b, a; -} SDL_BlitInfo; +} SDL_InternalBlitInfo; struct SDL_BlitMap { SDL_Surface *dst; int identity; SDL_blit blit; void *data; - SDL_BlitInfo info; + SDL_InternalBlitInfo info; /* the version count matches the destination; mismatch indicates an invalid mapping */ From 8ef3627e81cf2ff2c892988a22fe64e315272265 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Fri, 27 Oct 2023 19:27:25 +0100 Subject: [PATCH 16/19] Only add RLE flag when original surf had RLE --- src_c/rotozoom.c | 33 +++++++++++++++++---------------- src_c/transform.c | 7 ++++++- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src_c/rotozoom.c b/src_c/rotozoom.c index 88696d3d08..d2d1df3d22 100644 --- a/src_c/rotozoom.c +++ b/src_c/rotozoom.c @@ -12,22 +12,6 @@ */ #include "_pygame.h" - -#if !SDL_VERSION_ATLEAST(2, 0, 14) -SDL_bool -PG_SurfaceHasRLE(SDL_Surface *surface) -{ - if (surface == NULL) { - return SDL_FALSE; - } - - if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { - return SDL_FALSE; - } - - return SDL_TRUE; -} -#endif #define NO_PYGAME_C_API #include "pygame.h" @@ -48,6 +32,23 @@ typedef struct tColorRGBA { #define M_PI 3.141592654 #endif +#if !SDL_VERSION_ATLEAST(2, 0, 14) +// Remove this when our minimum version is 2.0.14 or larger +SDL_bool +PG_SurfaceHasRLE(SDL_Surface *surface) +{ + if (surface == NULL) { + return SDL_FALSE; + } + + if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { + return SDL_FALSE; + } + + return SDL_TRUE; +} +#endif + /* 32bit Zoomer with optional anti-aliasing by bilinear interpolation. diff --git a/src_c/transform.c b/src_c/transform.c index 8bb3d9fe1a..cdae3c6142 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -179,7 +179,12 @@ newsurf_fromsurf(SDL_Surface *surf, int width, int height) } if (SDL_GetColorKey(surf, &colorkey) == 0) { - if (SDL_SetColorKey(newsurf, SDL_TRUE, colorkey) != 0 || + if (SDL_SetColorKey(newsurf, SDL_TRUE, colorkey) != 0) { + PyErr_SetString(pgExc_SDLError, SDL_GetError()); + SDL_FreeSurface(newsurf); + return NULL; + } + if (PG_SurfaceHasRLE(surf) && SDL_SetSurfaceRLE(newsurf, SDL_TRUE) != 0) { PyErr_SetString(pgExc_SDLError, SDL_GetError()); SDL_FreeSurface(newsurf); From 1d6d6ff624064dbee3849b9c5994a6a9842c53d4 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Tue, 31 Oct 2023 19:32:09 +0000 Subject: [PATCH 17/19] Add test for unwanted RLE --- test/transform_test.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/transform_test.py b/test/transform_test.py index a976800f2e..75bf7781d5 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -1626,6 +1626,20 @@ def test_flip_alpha(self): self.assertEqual(surf.get_at((0, 0)), surf2.get_at((0, 0))) self.assertEqual(surf2.get_at((0, 0)), (255, 0, 0, 255)) + def test_unwanted_rle_not_added(self): + surf = pygame.Surface((16, 16)) + surf.fill((255, 0, 0)) + surf.set_colorkey((0, 0, 0)) + surf.set_alpha(64) + + # scale it to the same size (size doesn't matter here) + scaled_surf = pygame.transform.scale(surf, (16, 16)) + pygame.Surface((100, 100)).blit(scaled_surf, (0, 0)) + + self.assertEqual( + scaled_surf.get_flags() & pygame.RLEACCEL, scaled_surf.get_flags() & pygame.RLEACCEL) + self.assertEqual(scaled_surf.get_at((8, 8)), (255, 0, 0, 255)) + if __name__ == "__main__": unittest.main() From 033d56ad3753251cd16351e7ab859de1699e32c8 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Tue, 31 Oct 2023 19:34:03 +0000 Subject: [PATCH 18/19] Add test for unwanted RLE --- test/transform_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/transform_test.py b/test/transform_test.py index 75bf7781d5..c57e5d6e4c 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -1637,7 +1637,7 @@ def test_unwanted_rle_not_added(self): pygame.Surface((100, 100)).blit(scaled_surf, (0, 0)) self.assertEqual( - scaled_surf.get_flags() & pygame.RLEACCEL, scaled_surf.get_flags() & pygame.RLEACCEL) + surf.get_flags() & pygame.RLEACCEL, scaled_surf.get_flags() & pygame.RLEACCEL) self.assertEqual(scaled_surf.get_at((8, 8)), (255, 0, 0, 255)) From 4ccd79a2cb55e825020ddd340384d69894838339 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Wed, 1 Nov 2023 18:13:53 +0000 Subject: [PATCH 19/19] Add test for unwanted RLE --- test/transform_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/transform_test.py b/test/transform_test.py index c57e5d6e4c..27d34b7148 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -1637,7 +1637,9 @@ def test_unwanted_rle_not_added(self): pygame.Surface((100, 100)).blit(scaled_surf, (0, 0)) self.assertEqual( - surf.get_flags() & pygame.RLEACCEL, scaled_surf.get_flags() & pygame.RLEACCEL) + surf.get_flags() & pygame.RLEACCEL, + scaled_surf.get_flags() & pygame.RLEACCEL, + ) self.assertEqual(scaled_surf.get_at((8, 8)), (255, 0, 0, 255))