From b742938a07d91698cca81fb4253f529080b00490 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Tue, 28 May 2024 19:15:06 +0100 Subject: [PATCH 1/3] Add test, fix for unusual pitch in premul_alpha() fixes #2750 --- src_c/alphablit.c | 7 ++++++- src_c/simd_blitters_sse2.c | 4 ++++ test/surface_test.py | 20 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src_c/alphablit.c b/src_c/alphablit.c index e975218fda..a4867053b7 100644 --- a/src_c/alphablit.c +++ b/src_c/alphablit.c @@ -2841,7 +2841,8 @@ premul_surf_color_by_alpha(SDL_Surface *src, SDL_Surface *dst) // since we know dst is a copy of src we can simplify the normal checks #if !defined(__EMSCRIPTEN__) #if SDL_BYTEORDER == SDL_LIL_ENDIAN - if ((PG_SURF_BytesPerPixel(src) == 4) && pg_has_avx2()) { + if ((PG_SURF_BytesPerPixel(src) == 4) && + (src->pitch % PG_SURF_BytesPerPixel(src) == 0) && pg_has_avx2()) { premul_surf_color_by_alpha_avx2(src, dst); return 0; } @@ -2873,6 +2874,8 @@ premul_surf_color_by_alpha_non_simd(SDL_Surface *src, SDL_Surface *dst) int srcbpp = PG_FORMAT_BytesPerPixel(srcfmt); int dstbpp = PG_FORMAT_BytesPerPixel(dstfmt); Uint8 *src_pixels = (Uint8 *)src->pixels; + int srcskip = src->pitch - (width * srcbpp); + int dstskip = dst->pitch - (width * dstbpp); Uint8 *dst_pixels = (Uint8 *)dst->pixels; int srcpxskip = PG_SURF_BytesPerPixel(src); @@ -2898,6 +2901,8 @@ premul_surf_color_by_alpha_non_simd(SDL_Surface *src, SDL_Surface *dst) dst_pixels += dstpxskip; }, n, width); + src_pixels += srcskip; + dst_pixels += dstskip; } } diff --git a/src_c/simd_blitters_sse2.c b/src_c/simd_blitters_sse2.c index 1c1c881fe7..d59148ac2f 100644 --- a/src_c/simd_blitters_sse2.c +++ b/src_c/simd_blitters_sse2.c @@ -783,7 +783,9 @@ premul_surf_color_by_alpha_sse2(SDL_Surface *src, SDL_Surface *dst) int width = src->w; int height = src->h; Uint32 *srcp = (Uint32 *)src->pixels; + int srcskip = src->pitch - width * PG_SURF_BytesPerPixel(src); Uint32 *dstp = (Uint32 *)dst->pixels; + int dstskip = dst->pitch - width * PG_SURF_BytesPerPixel(dst); SDL_PixelFormat *srcfmt = src->format; Uint32 amask = srcfmt->Amask; @@ -836,6 +838,8 @@ premul_surf_color_by_alpha_sse2(SDL_Surface *src, SDL_Surface *dst) ++dstp; }, n, width); + (Uint8 *)srcp += srcskip; + (Uint8 *)dstp += dstskip; } } diff --git a/test/surface_test.py b/test/surface_test.py index d0c01c28a5..c1a7efd4f3 100644 --- a/test/surface_test.py +++ b/test/surface_test.py @@ -4029,6 +4029,26 @@ def test_surface_premul_alpha(self): ), ) + def create_surface_from_byte_width(byte_width): + surf_height = 5 + byte_data = bytes(byte_width * surf_height) # 50 bytes + surf_width = byte_width // 4 # width = 2 + + dest = pygame.image.frombuffer( + byte_data, (surf_width, surf_height), "RGBA", pitch=byte_width + ) + dest.fill((120, 50, 70, 200)) + return dest + + test_surf = create_surface_from_byte_width(10) + test_surf = test_surf.premul_alpha() + + for y in range(0, test_surf.get_height()): + for x in range(0, test_surf.get_width()): + self.assertEqual( + test_surf.get_at((x, y)), pygame.Color(94, 39, 55, 200) + ) + class SurfaceSelfBlitTest(unittest.TestCase): """Blit to self tests. From 8b28d80c8ebefc268c8ea977660bbd8aa12ce194 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Wed, 29 May 2024 15:57:13 +0100 Subject: [PATCH 2/3] Try to please gcc --- src_c/simd_blitters_sse2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/simd_blitters_sse2.c b/src_c/simd_blitters_sse2.c index d59148ac2f..0fb4079b2d 100644 --- a/src_c/simd_blitters_sse2.c +++ b/src_c/simd_blitters_sse2.c @@ -838,8 +838,8 @@ premul_surf_color_by_alpha_sse2(SDL_Surface *src, SDL_Surface *dst) ++dstp; }, n, width); - (Uint8 *)srcp += srcskip; - (Uint8 *)dstp += dstskip; + srcp = (Uint32 *)((Uint8 *)srcp + srcskip); + dstp = (Uint32 *)((Uint8 *)dstp + dstskip); } } From c739cf2f669bd4851e2cc9a5b937bd8a528258d5 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Thu, 25 Jul 2024 14:26:16 +0100 Subject: [PATCH 3/3] formatting --- test/surface_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/surface_test.py b/test/surface_test.py index 4940938050..df64e6882d 100644 --- a/test/surface_test.py +++ b/test/surface_test.py @@ -4038,7 +4038,6 @@ def test_surface_premul_alpha(self): ), ) - def create_surface_from_byte_width(byte_width): surf_height = 5 byte_data = bytes(byte_width * surf_height) # 50 bytes