[pypy-svn] r54843 - in pypy/dist/pypy/rlib/rsdl: . test

arigo at codespeak.net arigo at codespeak.net
Sat May 17 17:12:23 CEST 2008


Author: arigo
Date: Sat May 17 17:12:22 2008
New Revision: 54843

Modified:
   pypy/dist/pypy/rlib/rsdl/RSDL.py
   pypy/dist/pypy/rlib/rsdl/test/test_sdl_image.py
Log:
Some pixel manipulation routines, used to check that
the loaded image is correct.


Modified: pypy/dist/pypy/rlib/rsdl/RSDL.py
==============================================================================
--- pypy/dist/pypy/rlib/rsdl/RSDL.py	(original)
+++ pypy/dist/pypy/rlib/rsdl/RSDL.py	Sat May 17 17:12:22 2008
@@ -30,8 +30,11 @@
     _compilation_info_ = eci
 
     Uint8  = platform.SimpleType('Uint8',  rffi.INT)
+    Uint16 = platform.SimpleType('Uint16', rffi.INT)
     Uint32 = platform.SimpleType('Uint32', rffi.INT)
 
+    BYTEORDER = platform.ConstantInteger('SDL_BYTEORDER')
+    BIG_ENDIAN = platform.ConstantInteger('SDL_BIG_ENDIAN')
     INIT_VIDEO = platform.ConstantInteger('SDL_INIT_VIDEO')
 
     Rect = platform.Struct('SDL_Rect', [('x', rffi.INT),
@@ -40,8 +43,11 @@
                                         ('h', rffi.INT)])
     Surface = platform.Struct('SDL_Surface', [('w', rffi.INT),
                                               ('h', rffi.INT),
-                                              ('format', PixelFormatPtr)])
-    PixelFormat = platform.Struct('SDL_PixelFormat', [])
+                                              ('format', PixelFormatPtr),
+                                              ('pitch', rffi.INT),
+                                              ('pixels', rffi.UCHARP)])
+    PixelFormat = platform.Struct('SDL_PixelFormat',
+                                  [('BytesPerPixel', rffi.INT)])
 
 globals().update(platform.configure(CConfig))
 
@@ -49,6 +55,10 @@
 SurfacePtr.TO.become(Surface)
 PixelFormatPtr.TO.become(PixelFormat)
 
+Uint8P = lltype.Ptr(lltype.Array(Uint8, hints={'nolength': True}))
+Uint16P = lltype.Ptr(lltype.Array(Uint16, hints={'nolength': True}))
+Uint32P = lltype.Ptr(lltype.Array(Uint32, hints={'nolength': True}))
+
 def Init(flags):
     if sys.platform == 'darwin':
         from AppKit import NSApplication
@@ -66,7 +76,40 @@
                                                      Uint32, Uint32,
                                                      Uint32, Uint32],
                             SurfacePtr)
+LockSurface = external('SDL_LockSurface', [SurfacePtr], rffi.INT)
+UnlockSurface = external('SDL_UnlockSurface', [SurfacePtr], lltype.Void)
 FreeSurface = external('SDL_FreeSurface', [SurfacePtr], lltype.Void)
 
 MapRGB = external('SDL_MapRGB', [PixelFormatPtr, Uint8, Uint8, Uint8], Uint32)
+GetRGB = external('SDL_GetRGB', [Uint32, PixelFormatPtr,
+                                 Uint8P, Uint8P, Uint8P], lltype.Void)
 FillRect = external('SDL_FillRect', [SurfacePtr, RectPtr, Uint32], rffi.INT)
+
+
+def getpixel(image, x, y):
+    """Return the pixel value at (x, y)
+    NOTE: The surface must be locked before calling this!
+    """
+    bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel')
+    pitch = rffi.getintfield(image, 'c_pitch')
+    # Here p is the address to the pixel we want to retrieve
+    p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp)
+    if bpp == 1:
+        return rffi.cast(Uint32, p[0])
+    elif bpp == 2:
+        p = rffi.cast(Uint16P, p)
+        return rffi.cast(Uint32, p[0])
+    elif bpp == 3:
+        p0 = rffi.cast(lltype.Signed, p[0])
+        p1 = rffi.cast(lltype.Signed, p[1])
+        p2 = rffi.cast(lltype.Signed, p[2])
+        if BYTEORDER == BIG_ENDIAN:
+            result = p0 << 16 | p1 << 8 | p2
+        else:
+            result = p0 | p1 << 8 | p2 << 16
+        return rffi.cast(Uint32, result)
+    elif bpp == 4:
+        p = rffi.cast(Uint32P, p)
+        return p[0]
+    else:
+        raise ValueError("bad BytesPerPixel")

Modified: pypy/dist/pypy/rlib/rsdl/test/test_sdl_image.py
==============================================================================
--- pypy/dist/pypy/rlib/rsdl/test/test_sdl_image.py	(original)
+++ pypy/dist/pypy/rlib/rsdl/test/test_sdl_image.py	Sat May 17 17:12:22 2008
@@ -1,7 +1,7 @@
 import py, os
 import autopath
 from pypy.rlib.rsdl import RSDL, RIMG
-from pypy.rpython.lltypesystem import rffi
+from pypy.rpython.lltypesystem import lltype, rffi
 
 
 def test_load_image():
@@ -11,3 +11,41 @@
         assert rffi.getintfield(image, 'c_w') == 17
         assert rffi.getintfield(image, 'c_h') == 23
         RSDL.FreeSurface(image)
+
+def test_image_pixels():
+    for filename in ["demo.jpg", "demo.png"]:
+        image = RIMG.Load(os.path.join(autopath.this_dir, filename))
+        assert image
+        assert rffi.getintfield(image.c_format, 'c_BytesPerPixel') in (3, 4)
+        RSDL.LockSurface(image)
+        result = {}
+        try:
+            rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 3, flavor='raw')
+            try:
+                for y in range(23):
+                    for x in range(17):
+                        color = RSDL.getpixel(image, x, y)
+                        RSDL.GetRGB(color,
+                                    image.c_format,
+                                    rffi.ptradd(rgb, 0),
+                                    rffi.ptradd(rgb, 1),
+                                    rffi.ptradd(rgb, 2))
+                        r = rffi.cast(lltype.Signed, rgb[0])
+                        g = rffi.cast(lltype.Signed, rgb[1])
+                        b = rffi.cast(lltype.Signed, rgb[2])
+                        result[x, y] = r, g, b
+            finally:
+                lltype.free(rgb, flavor='raw')
+        finally:
+            RSDL.UnlockSurface(image)
+        RSDL.FreeSurface(image)
+        for y in range(23):
+            for x in range(17):
+                f = (x*17 + y*23) / float(17*17+23*23)
+                expected_r = int(255.0 * (1.0-f))
+                expected_g = 0
+                expected_b = int(255.0 * f)
+                r, g, b = result[x, y]
+                assert abs(r-expected_r) < 10
+                assert abs(g-expected_g) < 10
+                assert abs(b-expected_b) < 10



More information about the Pypy-commit mailing list