Skip to content

Commit abe99c2

Browse files
authored
Add test & fix for unusual pitch in surface.premul_alpha() (#2882)
* Add test, fix for unusual pitch in premul_alpha() fixes #2750 * Try to please gcc * formatting * added @ankith suggestion * Formatting.
2 parents 2ea7b39 + d8b2954 commit abe99c2

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

src_c/alphablit.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1714,7 +1714,9 @@ premul_surf_color_by_alpha(SDL_Surface *src, SDL_Surface *dst)
17141714
// since we know dst is a copy of src we can simplify the normal checks
17151715
#if !defined(__EMSCRIPTEN__)
17161716
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
1717-
if ((PG_SURF_BytesPerPixel(src) == 4) && pg_has_avx2()) {
1717+
if ((PG_SURF_BytesPerPixel(src) == 4) &&
1718+
(src->pitch == (src->w * PG_SURF_BytesPerPixel(src))) &&
1719+
pg_has_avx2()) {
17181720
premul_surf_color_by_alpha_avx2(src, src_format, dst);
17191721
return 0;
17201722
}
@@ -1749,6 +1751,8 @@ premul_surf_color_by_alpha_non_simd(SDL_Surface *src,
17491751
int srcbpp = PG_FORMAT_BytesPerPixel(src_format);
17501752
int dstbpp = PG_FORMAT_BytesPerPixel(dst_format);
17511753
Uint8 *src_pixels = (Uint8 *)src->pixels;
1754+
int srcskip = src->pitch - (width * srcbpp);
1755+
int dstskip = dst->pitch - (width * dstbpp);
17521756
Uint8 *dst_pixels = (Uint8 *)dst->pixels;
17531757

17541758
int srcpxskip = srcbpp;
@@ -1775,6 +1779,8 @@ premul_surf_color_by_alpha_non_simd(SDL_Surface *src,
17751779
dst_pixels += dstpxskip;
17761780
},
17771781
n, width);
1782+
src_pixels += srcskip;
1783+
dst_pixels += dstskip;
17781784
}
17791785
}
17801786

src_c/simd_blitters_sse2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,9 @@ premul_surf_color_by_alpha_sse2(SDL_Surface *src, PG_PixelFormat *srcfmt,
794794
int width = src->w;
795795
int height = src->h;
796796
Uint32 *srcp = (Uint32 *)src->pixels;
797+
int srcskip = src->pitch - width * PG_SURF_BytesPerPixel(src);
797798
Uint32 *dstp = (Uint32 *)dst->pixels;
799+
int dstskip = dst->pitch - width * PG_SURF_BytesPerPixel(dst);
798800
Uint32 amask = srcfmt->Amask;
799801
Uint64 ones;
800802

@@ -845,6 +847,8 @@ premul_surf_color_by_alpha_sse2(SDL_Surface *src, PG_PixelFormat *srcfmt,
845847
++dstp;
846848
},
847849
n, width);
850+
srcp = (Uint32 *)((Uint8 *)srcp + srcskip);
851+
dstp = (Uint32 *)((Uint8 *)dstp + dstskip);
848852
}
849853
}
850854

test/surface_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4004,6 +4004,26 @@ def test_surface_premul_alpha(self):
40044004
),
40054005
)
40064006

4007+
def create_surface_from_byte_width(byte_width):
4008+
surf_height = 5
4009+
byte_data = bytes(byte_width * surf_height) # 50 bytes
4010+
surf_width = byte_width // 4 # width = 2
4011+
4012+
dest = pygame.image.frombuffer(
4013+
byte_data, (surf_width, surf_height), "RGBA", pitch=byte_width
4014+
)
4015+
dest.fill((120, 50, 70, 200))
4016+
return dest
4017+
4018+
test_surf = create_surface_from_byte_width(10)
4019+
test_surf = test_surf.premul_alpha()
4020+
4021+
for y in range(0, test_surf.get_height()):
4022+
for x in range(0, test_surf.get_width()):
4023+
self.assertEqual(
4024+
test_surf.get_at((x, y)), pygame.Color(94, 39, 55, 200)
4025+
)
4026+
40074027
def test_surface_premul_alpha_ip(self):
40084028
"""Ensure that .premul_alpha_ip() works correctly"""
40094029

0 commit comments

Comments
 (0)