[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] ARGB vs. RGBA



All righty, I made a test for pygame.image.fromstring with "ARGB" as
the type, looks like it's broken

attached is the test (all 4 drawn things should be identical, but you
can see ones where fromstring is used are bad)

looks like image.tostring with "ARGB" is just fine.

I don't have the ability to build pygame from sources at the moment,
otherwise I'd make a patch & test it - but I think what I said in my
last email should work
import pygame
import array

####################################################################
def AreSurfacesIdentical(surf_a, surf_b):
    if surf_a.get_width() != surf_b.get_width() or surf_a.get_height() != surf_b.get_height():
        return False
    for y in xrange(surf_a.get_height()):
        for x in xrange(surf_b.get_width()):
            if surf_a.get_at((x,y)) != surf_b.get_at((x,y)):
                return False
    return True

####################################################################
def RotateRGBAtoARGB(str_buf):
    byte_buf = array.array("B", str_buf)
    num_quads = len(byte_buf)/4
    for i in xrange(num_quads):
        alpha = byte_buf[i*4 + 3]
        byte_buf[i*4 + 3] = byte_buf[i*4 + 2]
        byte_buf[i*4 + 2] = byte_buf[i*4 + 1]
        byte_buf[i*4 + 1] = byte_buf[i*4 + 0]
        byte_buf[i*4 + 0] = alpha
    return byte_buf.tostring()

####################################################################
def RotateARGBtoRGBA(str_buf):
    byte_buf = array.array("B", str_buf)
    num_quads = len(byte_buf)/4
    for i in xrange(num_quads):
        alpha = byte_buf[i*4 + 0]
        byte_buf[i*4 + 0] = byte_buf[i*4 + 1]
        byte_buf[i*4 + 1] = byte_buf[i*4 + 2]
        byte_buf[i*4 + 2] = byte_buf[i*4 + 3]
        byte_buf[i*4 + 3] = alpha
    return byte_buf.tostring()
        
####################################################################
test_surface = pygame.Surface((48, 256), flags=pygame.SRCALPHA, depth=32)
for i in xrange(256):
    for j in xrange(16):
        intensity = j*16 + 15
        test_surface.set_at((j + 0, i), (intensity, i, i, 255))
        test_surface.set_at((j + 16, i), (i, intensity, i, 255))
        test_surface.set_at((j + 32, i), (i, i, intensity, 255))
    
assert(AreSurfacesIdentical(test_surface, test_surface))

rgba_buf = pygame.image.tostring(test_surface, "RGBA")
rgba_buf = RotateARGBtoRGBA(RotateRGBAtoARGB(rgba_buf))
test_rotate_functions = pygame.image.fromstring(rgba_buf, test_surface.get_size(), "RGBA")

assert(AreSurfacesIdentical(test_surface, test_rotate_functions))

rgba_buf = pygame.image.tostring(test_surface, "RGBA")
argb_buf = RotateRGBAtoARGB(rgba_buf)
test_from_argb_string = pygame.image.fromstring(argb_buf, test_surface.get_size(), "ARGB")

if not AreSurfacesIdentical(test_surface, test_from_argb_string):
    print "ERROR: image.fromstring with ARGB failed"


argb_buf = pygame.image.tostring(test_surface, "ARGB")
rgba_buf = RotateARGBtoRGBA(argb_buf)
test_to_argb_string = pygame.image.fromstring(rgba_buf, test_surface.get_size(), "RGBA")

if not AreSurfacesIdentical(test_surface, test_to_argb_string):
    print "ERROR: image.tostring with ARGB failed"


argb_buf = pygame.image.tostring(test_surface, "ARGB")
test_to_from_argb_string = pygame.image.fromstring(argb_buf, test_surface.get_size(), "ARGB")

if not AreSurfacesIdentical(test_surface, test_to_from_argb_string):
    print "ERROR: image.fromstring and image.tostring with ARGB are not symmetric"

pygame.display.init()
screen = pygame.display.set_mode((320,256))

screen.fill((0,0,0))
screen.blit(test_surface,(0,0))
screen.blit(test_from_argb_string,(80,0))
screen.blit(test_to_argb_string,(160,0))
screen.blit(test_to_from_argb_string,(240,0))
pygame.display.update()

while 1:
    for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == 27:
                    raise SystemExit
    pygame.display.update()