pygame-ce icon indicating copy to clipboard operation
pygame-ce copied to clipboard

premul_alpha doesn't respect weird surface pitches

Open Starbuck5 opened this issue 1 year ago • 0 comments
trafficstars

I found this while reviewing the code of #2615

If the surface pitch is not aligned to 4 bytes, it doesn't properly skip through rows.

For example:

import pygame

surf_height = 5


def create_surface_from_byte_width(byte_width):
    byte_data = bytes(byte_width * surf_height)
    surf_width = byte_width // 4

    dest = pygame.image.frombuffer(
        byte_data, (surf_width, surf_height), "RGBA", pitch=byte_width
    )
    dest.fill((120, 50, 70, 200))
    return dest


dest = create_surface_from_byte_width(8)  # 2 pixels wide
print("Surface 1: pitch =", dest.get_pitch())
print("Before premul:", dest.get_at((dest.get_width() - 1, dest.get_height() - 1)))
dest = dest.premul_alpha()
print("After premul:", dest.get_at((dest.get_width() - 1, dest.get_height() - 1)))

dest = create_surface_from_byte_width(10)  # 2.5 pixels wide
print("Surface 2: pitch =", dest.get_pitch())
print("Before premul:", dest.get_at((dest.get_width() - 1, dest.get_height() - 1)))
dest = dest.premul_alpha()
print("After premul:", dest.get_at((dest.get_width() - 1, dest.get_height() - 1)))
Surface 1: pitch = 8
Before premul: Color(120, 50, 70, 200)
After premul: Color(94, 39, 55, 200)
Surface 2: pitch = 10
Before premul: Color(120, 50, 70, 200)
After premul: Color(0, 0, 0, 0)

The final pixels of the 10-byte wide surface are never reached by the premultiply algorithm.

Starbuck5 avatar Mar 17 '24 00:03 Starbuck5