1421 lines
55 KiB
Python
1421 lines
55 KiB
Python
import sys
|
|
import platform
|
|
try:
|
|
reduce
|
|
except NameError:
|
|
from functools import reduce
|
|
import operator
|
|
import weakref
|
|
import gc
|
|
import unittest
|
|
|
|
from pygame.tests.test_utils import SurfaceSubclass
|
|
|
|
try:
|
|
from pygame.tests.test_utils import arrinter
|
|
except NameError:
|
|
pass
|
|
|
|
import pygame
|
|
from pygame.compat import xrange_
|
|
|
|
PY3 = sys.version_info >= (3, 0, 0)
|
|
IS_PYPY = 'PyPy' == platform.python_implementation()
|
|
|
|
|
|
class TestMixin (object):
|
|
def assert_surfaces_equal (self, s1, s2):
|
|
# Assumes the surfaces are the same size.
|
|
w, h = s1.get_size ()
|
|
for x in range (w):
|
|
for y in range (h):
|
|
self.assertEqual (s1.get_at ((x, y)), s2.get_at ((x, y)),
|
|
"size: (%i, %i), position: (%i, %i)" %
|
|
(w, h, x, y))
|
|
|
|
class PixelArrayTypeTest (unittest.TestCase, TestMixin):
|
|
def test_compare(self):
|
|
# __doc__ (as of 2008-06-25) for pygame.pixelarray.PixelArray.compare:
|
|
|
|
# PixelArray.compare (array, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray
|
|
# Compares the PixelArray with another one.
|
|
|
|
w = 10
|
|
h = 20
|
|
size = w, h
|
|
sf = pygame.Surface (size, 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
sf2 = pygame.Surface (size, 0, 32)
|
|
self.assertRaises (TypeError, ar.compare, sf2)
|
|
ar2 = pygame.PixelArray (sf2)
|
|
ar3 = ar.compare (ar2)
|
|
self.assertTrue(isinstance (ar3, pygame.PixelArray))
|
|
self.assertEqual (ar3.shape, size)
|
|
sf2.fill (pygame.Color ('white'))
|
|
self.assert_surfaces_equal (sf2, ar3.surface)
|
|
del ar3
|
|
r = pygame.Rect (2, 5, 6, 13)
|
|
sf.fill (pygame.Color ('blue'), r)
|
|
sf2.fill (pygame.Color ('red'))
|
|
sf2.fill (pygame.Color ('blue'), r)
|
|
ar3 = ar.compare (ar2)
|
|
sf.fill (pygame.Color ('white'), r)
|
|
self.assert_surfaces_equal (sf, ar3.surface)
|
|
|
|
# FINISH ME!
|
|
# Test other bit depths, slices, and distance != 0.
|
|
|
|
def test_close(self):
|
|
""" does not crash when it is deleted.
|
|
"""
|
|
s = pygame.Surface((10,10))
|
|
a = pygame.PixelArray(s)
|
|
a.close()
|
|
del a
|
|
|
|
def test_close_raises(self):
|
|
""" when you try to do an operation after it is closed.
|
|
"""
|
|
s = pygame.Surface((10,10))
|
|
a = pygame.PixelArray(s)
|
|
a.close()
|
|
def do_operation():
|
|
a[:]
|
|
self.assertRaises (ValueError, do_operation)
|
|
|
|
def do_operation2():
|
|
a[:] = 1
|
|
self.assertRaises (ValueError, do_operation2)
|
|
|
|
def do_operation3():
|
|
a.make_surface()
|
|
self.assertRaises (ValueError, do_operation3)
|
|
|
|
def do_operation4():
|
|
for x in a:
|
|
pass
|
|
self.assertRaises (ValueError, do_operation4)
|
|
|
|
def test_context_manager(self):
|
|
""" closes properly.
|
|
"""
|
|
s = pygame.Surface((10,10))
|
|
with pygame.PixelArray(s) as a:
|
|
a[:]
|
|
|
|
def test_pixel_array (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 20), 0, bpp)
|
|
sf.fill ((0, 0, 0))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
self.assertEqual (ar._pixels_address, sf._pixels_address)
|
|
|
|
if sf.mustlock ():
|
|
self.assertTrue (sf.get_locked ())
|
|
|
|
self.assertEqual (len (ar), 10)
|
|
|
|
del ar
|
|
if sf.mustlock ():
|
|
self.assertFalse (sf.get_locked ())
|
|
|
|
def test_as_class (self):
|
|
# Check general new-style class freatures.
|
|
sf = pygame.Surface ((2, 3), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
self.assertRaises (AttributeError, getattr, ar, 'nonnative')
|
|
ar.nonnative = 'value'
|
|
self.assertEqual (ar.nonnative, 'value')
|
|
r = weakref.ref (ar)
|
|
self.assertTrue (r() is ar)
|
|
del ar
|
|
gc.collect ()
|
|
self.assertTrue (r() is None)
|
|
|
|
class C (pygame.PixelArray):
|
|
def __str__ (self):
|
|
return "string (%i, %i)" % self.shape
|
|
|
|
ar = C (sf)
|
|
self.assertEqual (str (ar), "string (2, 3)")
|
|
r = weakref.ref (ar)
|
|
self.assertTrue (r() is ar)
|
|
del ar
|
|
gc.collect ()
|
|
self.assertTrue (r() is None)
|
|
|
|
def test_pixelarray__subclassed_surface(self):
|
|
"""Ensure the PixelArray constructor accepts subclassed surfaces."""
|
|
surface = SurfaceSubclass((3, 5), 0, 32)
|
|
pixelarray = pygame.PixelArray(surface)
|
|
|
|
self.assertIsInstance(pixelarray, pygame.PixelArray)
|
|
|
|
# Sequence interfaces
|
|
def test_get_column (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((6, 8), 0, bpp)
|
|
sf.fill ((0, 0, 255))
|
|
val = sf.map_rgb ((0, 0, 255))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
ar2 = ar.__getitem__ (1)
|
|
self.assertEqual (len(ar2), 8)
|
|
self.assertEqual (ar2.__getitem__ (0), val)
|
|
self.assertEqual (ar2.__getitem__ (1), val)
|
|
self.assertEqual (ar2.__getitem__ (2), val)
|
|
|
|
ar2 = ar.__getitem__ (-1)
|
|
self.assertEqual (len(ar2), 8)
|
|
self.assertEqual (ar2.__getitem__ (0), val)
|
|
self.assertEqual (ar2.__getitem__ (1), val)
|
|
self.assertEqual (ar2.__getitem__ (2), val)
|
|
|
|
def test_get_pixel (self):
|
|
w = 10
|
|
h = 20
|
|
size = w, h
|
|
bg_color = (0, 0, 255)
|
|
fg_color_y = (0, 0, 128)
|
|
fg_color_x = (0, 0, 11)
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface (size, 0, bpp)
|
|
mapped_bg_color = sf.map_rgb (bg_color)
|
|
mapped_fg_color_y = sf.map_rgb (fg_color_y)
|
|
mapped_fg_color_x = sf.map_rgb (fg_color_x)
|
|
self.assertNotEqual (mapped_fg_color_y, mapped_bg_color,
|
|
"Unusable test colors for bpp %i" % (bpp,))
|
|
self.assertNotEqual (mapped_fg_color_x, mapped_bg_color,
|
|
"Unusable test colors for bpp %i" % (bpp,))
|
|
self.assertNotEqual (mapped_fg_color_y, mapped_fg_color_x,
|
|
"Unusable test colors for bpp %i" % (bpp,))
|
|
sf.fill (bg_color)
|
|
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
ar_y = ar.__getitem__ (1)
|
|
for y in xrange_ (h):
|
|
ar2 = ar_y.__getitem__ (y)
|
|
self.assertEqual (ar2, mapped_bg_color,
|
|
"ar[1][%i] == %i, mapped_bg_color == %i" %
|
|
(y, ar2, mapped_bg_color))
|
|
|
|
sf.set_at ((1, y), fg_color_y)
|
|
ar2 = ar_y.__getitem__ (y)
|
|
self.assertEqual (ar2, mapped_fg_color_y,
|
|
"ar[1][%i] == %i, mapped_fg_color_y == %i" %
|
|
(y, ar2, mapped_fg_color_y))
|
|
|
|
sf.set_at ((1, 1), bg_color)
|
|
for x in xrange_ (w):
|
|
ar2 = ar.__getitem__ (x).__getitem__ (1)
|
|
self.assertEqual (ar2, mapped_bg_color,
|
|
"ar[%i][1] = %i, mapped_bg_color = %i" %
|
|
(x, ar2, mapped_bg_color))
|
|
sf.set_at ((x, 1), fg_color_x)
|
|
ar2 = ar.__getitem__ (x).__getitem__ (1)
|
|
self.assertEqual (ar2, mapped_fg_color_x,
|
|
"ar[%i][1] = %i, mapped_fg_color_x = %i" %
|
|
(x, ar2, mapped_fg_color_x))
|
|
|
|
ar2 = ar.__getitem__ (0).__getitem__ (0)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (1).__getitem__ (0)
|
|
self.assertEqual (ar2, mapped_fg_color_y, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (-4).__getitem__ (1)
|
|
self.assertEqual (ar2, mapped_fg_color_x, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (-4).__getitem__ (5)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (-4).__getitem__ (0)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (-w + 1).__getitem__ (0)
|
|
self.assertEqual (ar2, mapped_fg_color_y, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (-w).__getitem__ (0)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (5).__getitem__ (-4)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (5).__getitem__ (-h + 1)
|
|
self.assertEqual (ar2, mapped_fg_color_x, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (5).__getitem__ (-h)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (0).__getitem__ (-h + 1)
|
|
self.assertEqual (ar2, mapped_fg_color_x, "bpp = %i" % (bpp,))
|
|
|
|
ar2 = ar.__getitem__ (0).__getitem__ (-h)
|
|
self.assertEqual (ar2, mapped_bg_color, "bpp = %i" % (bpp,))
|
|
|
|
def test_set_pixel (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 20), 0, bpp)
|
|
sf.fill ((0, 0, 0))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
ar.__getitem__ (0).__setitem__ (0, (0, 255, 0))
|
|
self.assertEqual (ar[0][0], sf.map_rgb ((0, 255, 0)))
|
|
|
|
ar.__getitem__ (1).__setitem__ (1, (128, 128, 128))
|
|
self.assertEqual (ar[1][1], sf.map_rgb ((128, 128, 128)))
|
|
|
|
ar.__getitem__(-1).__setitem__ (-1, (128, 128, 128))
|
|
self.assertEqual (ar[9][19], sf.map_rgb ((128, 128, 128)))
|
|
|
|
ar.__getitem__ (-2).__setitem__ (-2, (128, 128, 128))
|
|
self.assertEqual (ar[8][-2], sf.map_rgb ((128, 128, 128)))
|
|
|
|
def test_set_column (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((6, 8), 0, bpp)
|
|
sf.fill ((0, 0, 0))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
sf2 = pygame.Surface ((6, 8), 0, bpp)
|
|
sf2.fill ((0, 255, 255))
|
|
ar2 = pygame.PixelArray (sf2)
|
|
|
|
# Test single value assignment
|
|
ar.__setitem__ (2, (128, 128, 128))
|
|
self.assertEqual (ar[2][0], sf.map_rgb ((128, 128, 128)))
|
|
self.assertEqual (ar[2][1], sf.map_rgb ((128, 128, 128)))
|
|
|
|
ar.__setitem__ (-1, (0, 255, 255))
|
|
self.assertEqual (ar[5][0], sf.map_rgb ((0, 255, 255)))
|
|
self.assertEqual (ar[-1][1], sf.map_rgb ((0, 255, 255)))
|
|
|
|
ar.__setitem__ (-2, (255, 255, 0))
|
|
self.assertEqual (ar[4][0], sf.map_rgb ((255, 255, 0)))
|
|
self.assertEqual (ar[-2][1], sf.map_rgb ((255, 255, 0)))
|
|
|
|
# Test list assignment.
|
|
ar.__setitem__ (0, [(255, 255, 255)] * 8)
|
|
self.assertEqual (ar[0][0], sf.map_rgb ((255, 255, 255)))
|
|
self.assertEqual (ar[0][1], sf.map_rgb ((255, 255, 255)))
|
|
|
|
# Test tuple assignment.
|
|
# Changed in Pygame 1.9.2 - Raises an exception.
|
|
self.assertRaises (ValueError, ar.__setitem__, 1,
|
|
((204, 0, 204), (17, 17, 17), (204, 0, 204),
|
|
(17, 17, 17), (204, 0, 204), (17, 17, 17),
|
|
(204, 0, 204), (17, 17, 17)))
|
|
|
|
# Test pixel array assignment.
|
|
ar.__setitem__ (1, ar2.__getitem__ (3))
|
|
self.assertEqual (ar[1][0], sf.map_rgb ((0, 255, 255)))
|
|
self.assertEqual (ar[1][1], sf.map_rgb ((0, 255, 255)))
|
|
|
|
def test_get_slice (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 20), 0, bpp)
|
|
sf.fill ((0, 0, 0))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
self.assertEqual (len (ar[0:2]), 2)
|
|
self.assertEqual (len (ar[3:7][3]), 20)
|
|
|
|
self.assertEqual (ar[0:0], None)
|
|
self.assertEqual (ar[5:5], None)
|
|
self.assertEqual (ar[9:9], None)
|
|
|
|
# Has to resolve to ar[7:8]
|
|
self.assertEqual (len (ar[-3:-2]), 1) # 2D
|
|
self.assertEqual (len (ar[-3:-2][0]), 20) # 1D
|
|
|
|
# Try assignments.
|
|
|
|
# 2D assignment.
|
|
ar[2:5] = (255, 255, 255)
|
|
|
|
# 1D assignment
|
|
ar[3][3:7] = (10, 10, 10)
|
|
self.assertEqual (ar[3][5], sf.map_rgb ((10, 10, 10)))
|
|
self.assertEqual (ar[3][6], sf.map_rgb ((10, 10, 10)))
|
|
|
|
@unittest.skipIf(IS_PYPY, 'skipping for PyPy (segfaults on mac pypy3 6.0.0)')
|
|
def test_contains (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 20), 0, bpp)
|
|
sf.fill ((0, 0, 0))
|
|
sf.set_at ((8, 8), (255, 255, 255))
|
|
|
|
ar = pygame.PixelArray (sf)
|
|
self.assertTrue ((0, 0, 0) in ar)
|
|
self.assertTrue ((255, 255, 255) in ar)
|
|
self.assertFalse ((255, 255, 0) in ar)
|
|
self.assertFalse (0x0000ff in ar)
|
|
|
|
# Test sliced array
|
|
self.assertTrue ((0, 0, 0) in ar[8])
|
|
self.assertTrue ((255, 255, 255) in ar[8])
|
|
self.assertFalse ((255, 255, 0) in ar[8])
|
|
self.assertFalse (0x0000ff in ar[8])
|
|
|
|
def test_get_surface (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface((10, 20), 0, bpp)
|
|
sf.fill((0, 0, 0))
|
|
ar = pygame.PixelArray(sf)
|
|
self.assertTrue(ar.surface is sf)
|
|
|
|
def test_get_surface__subclassed_surface(self):
|
|
"""Ensure the surface attribute can handle subclassed surfaces."""
|
|
expected_surface = SurfaceSubclass((5, 3), 0, 32)
|
|
pixelarray = pygame.PixelArray(expected_surface)
|
|
|
|
surface = pixelarray.surface
|
|
|
|
self.assertIs(surface, expected_surface)
|
|
self.assertIsInstance(surface, pygame.Surface)
|
|
self.assertIsInstance(surface, SurfaceSubclass)
|
|
|
|
def test_set_slice (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((6, 8), 0, bpp)
|
|
sf.fill ((0, 0, 0))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
# Test single value assignment
|
|
val = sf.map_rgb ((128, 128, 128))
|
|
ar[0:2] = val
|
|
self.assertEqual (ar[0][0], val)
|
|
self.assertEqual (ar[0][1], val)
|
|
self.assertEqual (ar[1][0], val)
|
|
self.assertEqual (ar[1][1], val)
|
|
|
|
val = sf.map_rgb ((0, 255, 255))
|
|
ar[-3:-1] = val
|
|
self.assertEqual (ar[3][0], val)
|
|
self.assertEqual (ar[-2][1], val)
|
|
|
|
val = sf.map_rgb ((255, 255, 255))
|
|
ar[-3:] = (255, 255, 255)
|
|
self.assertEqual (ar[4][0], val)
|
|
self.assertEqual (ar[-1][1], val)
|
|
|
|
# Test array size mismatch.
|
|
# Changed in ver. 1.9.2
|
|
# (was "Test list assignment, this is a vertical assignment.")
|
|
val = sf.map_rgb ((0, 255, 0))
|
|
self.assertRaises (ValueError, ar.__setitem__, slice (2, 4),
|
|
[val] * 8)
|
|
|
|
# And the horizontal assignment.
|
|
val = sf.map_rgb ((255, 0, 0))
|
|
val2 = sf.map_rgb ((128, 0, 255))
|
|
ar[0:2] = [val, val2]
|
|
self.assertEqual (ar[0][0], val)
|
|
self.assertEqual (ar[1][0], val2)
|
|
self.assertEqual (ar[0][1], val)
|
|
self.assertEqual (ar[1][1], val2)
|
|
self.assertEqual (ar[0][4], val)
|
|
self.assertEqual (ar[1][4], val2)
|
|
self.assertEqual (ar[0][5], val)
|
|
self.assertEqual (ar[1][5], val2)
|
|
|
|
# Test pixelarray assignment.
|
|
ar[:] = (0, 0, 0)
|
|
sf2 = pygame.Surface ((6, 8), 0, bpp)
|
|
sf2.fill ((255, 0, 255))
|
|
|
|
val = sf.map_rgb ((255, 0, 255))
|
|
ar2 = pygame.PixelArray (sf2)
|
|
|
|
ar[:] = ar2[:]
|
|
self.assertEqual (ar[0][0], val)
|
|
self.assertEqual (ar[5][7], val)
|
|
|
|
# Ensure p1 ... pn are freed for array[...] = [p1, ..., pn]
|
|
# Bug fix: reference counting.
|
|
if hasattr(sys, 'getrefcount'):
|
|
class Int(int):
|
|
"""Unique int instances"""
|
|
pass
|
|
|
|
sf = pygame.Surface ((5, 2), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
pixel_list = [Int(i) for i in range(ar.shape[0])]
|
|
refcnts_before = [sys.getrefcount (i) for i in pixel_list]
|
|
ar[...] = pixel_list
|
|
refcnts_after = [sys.getrefcount (i) for i in pixel_list]
|
|
gc.collect ()
|
|
self.assertEqual (refcnts_after, refcnts_before)
|
|
|
|
def test_subscript (self):
|
|
# By default we do not need to work with any special __***__
|
|
# methods as map subscripts are the first looked up by the
|
|
# object system.
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((6, 8), 0, bpp)
|
|
sf.set_at ((1, 3), (0, 255, 0))
|
|
sf.set_at ((0, 0), (0, 255, 0))
|
|
sf.set_at ((4, 4), (0, 255, 0))
|
|
val = sf.map_rgb ((0, 255, 0))
|
|
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
# Test single value requests.
|
|
self.assertEqual (ar[1,3], val)
|
|
self.assertEqual (ar[0,0], val)
|
|
self.assertEqual (ar[4,4], val)
|
|
self.assertEqual (ar[1][3], val)
|
|
self.assertEqual (ar[0][0], val)
|
|
self.assertEqual (ar[4][4], val)
|
|
|
|
# Test ellipse working.
|
|
self.assertEqual (len (ar[...,...]), 6)
|
|
self.assertEqual (len (ar[1,...]), 8)
|
|
self.assertEqual (len (ar[...,3]), 6)
|
|
|
|
# Test simple slicing
|
|
self.assertEqual (len (ar[:,:]), 6)
|
|
self.assertEqual (len (ar[:,]), 6)
|
|
self.assertEqual (len (ar[1,:]), 8)
|
|
self.assertEqual (len (ar[:,2]), 6)
|
|
# Empty slices
|
|
self.assertEqual (ar[4:4,], None)
|
|
self.assertEqual (ar[4:4,...], None)
|
|
self.assertEqual (ar[4:4,2:2], None)
|
|
self.assertEqual (ar[4:4,1:4], None)
|
|
self.assertEqual (ar[4:4:2,], None)
|
|
self.assertEqual (ar[4:4:-2,], None)
|
|
self.assertEqual (ar[4:4:1,...], None)
|
|
self.assertEqual (ar[4:4:-1,...], None)
|
|
self.assertEqual (ar[4:4:1,2:2], None)
|
|
self.assertEqual (ar[4:4:-1,1:4], None)
|
|
self.assertEqual (ar[...,4:4], None)
|
|
self.assertEqual (ar[1:4,4:4], None)
|
|
self.assertEqual (ar[...,4:4:1], None)
|
|
self.assertEqual (ar[...,4:4:-1], None)
|
|
self.assertEqual (ar[2:2,4:4:1], None)
|
|
self.assertEqual (ar[1:4,4:4:-1], None)
|
|
|
|
# Test advanced slicing
|
|
ar[0] = 0
|
|
ar[1] = 1
|
|
ar[2] = 2
|
|
ar[3] = 3
|
|
ar[4] = 4
|
|
ar[5] = 5
|
|
|
|
# We should receive something like [0,2,4]
|
|
self.assertEqual (ar[::2,1][0], 0)
|
|
self.assertEqual (ar[::2,1][1], 2)
|
|
self.assertEqual (ar[::2,1][2], 4)
|
|
# We should receive something like [2,2,2]
|
|
self.assertEqual (ar[2,::2][0], 2)
|
|
self.assertEqual (ar[2,::2][1], 2)
|
|
self.assertEqual (ar[2,::2][2], 2)
|
|
|
|
# Should create a 3x3 array of [0,2,4]
|
|
ar2 = ar[::2,::2]
|
|
self.assertEqual (len (ar2), 3)
|
|
self.assertEqual (ar2[0][0], 0)
|
|
self.assertEqual (ar2[0][1], 0)
|
|
self.assertEqual (ar2[0][2], 0)
|
|
self.assertEqual (ar2[2][0], 4)
|
|
self.assertEqual (ar2[2][1], 4)
|
|
self.assertEqual (ar2[2][2], 4)
|
|
self.assertEqual (ar2[1][0], 2)
|
|
self.assertEqual (ar2[2][0], 4)
|
|
self.assertEqual (ar2[1][1], 2)
|
|
|
|
# Should create a reversed 3x8 array over X of [1,2,3] -> [3,2,1]
|
|
ar2 = ar[3:0:-1]
|
|
self.assertEqual (len (ar2), 3)
|
|
self.assertEqual (ar2[0][0], 3)
|
|
self.assertEqual (ar2[0][1], 3)
|
|
self.assertEqual (ar2[0][2], 3)
|
|
self.assertEqual (ar2[0][7], 3)
|
|
self.assertEqual (ar2[2][0], 1)
|
|
self.assertEqual (ar2[2][1], 1)
|
|
self.assertEqual (ar2[2][2], 1)
|
|
self.assertEqual (ar2[2][7], 1)
|
|
self.assertEqual (ar2[1][0], 2)
|
|
self.assertEqual (ar2[1][1], 2)
|
|
# Should completely reverse the array over X -> [5,4,3,2,1,0]
|
|
ar2 = ar[::-1]
|
|
self.assertEqual (len (ar2), 6)
|
|
self.assertEqual (ar2[0][0], 5)
|
|
self.assertEqual (ar2[0][1], 5)
|
|
self.assertEqual (ar2[0][3], 5)
|
|
self.assertEqual (ar2[0][-1], 5)
|
|
self.assertEqual (ar2[1][0], 4)
|
|
self.assertEqual (ar2[1][1], 4)
|
|
self.assertEqual (ar2[1][3], 4)
|
|
self.assertEqual (ar2[1][-1], 4)
|
|
self.assertEqual (ar2[-1][-1], 0)
|
|
self.assertEqual (ar2[-2][-2], 1)
|
|
self.assertEqual (ar2[-3][-1], 2)
|
|
|
|
# Test advanced slicing
|
|
ar[:] = 0
|
|
ar2 = ar[:,1]
|
|
ar2[:] = [99] * len(ar2)
|
|
self.assertEqual (ar2[0], 99)
|
|
self.assertEqual (ar2[-1], 99)
|
|
self.assertEqual (ar2[-2], 99)
|
|
self.assertEqual (ar2[2], 99)
|
|
self.assertEqual (ar[0,1], 99)
|
|
self.assertEqual (ar[1,1], 99)
|
|
self.assertEqual (ar[2,1], 99)
|
|
self.assertEqual (ar[-1,1], 99)
|
|
self.assertEqual (ar[-2,1], 99)
|
|
|
|
# Cases where a 2d array should have a dimension of length 1.
|
|
ar2 = ar[1:2,:]
|
|
self.assertEqual (ar2.shape, (1, ar.shape[1]))
|
|
ar2 = ar[:,1:2]
|
|
self.assertEqual (ar2.shape, (ar.shape[0], 1))
|
|
sf2 = pygame.Surface ((1, 5), 0, 32)
|
|
ar2 = pygame.PixelArray (sf2)
|
|
self.assertEqual (ar2.shape, sf2.get_size ())
|
|
sf2 = pygame.Surface ((7, 1), 0, 32)
|
|
ar2 = pygame.PixelArray (sf2)
|
|
self.assertEqual (ar2.shape, sf2.get_size ())
|
|
|
|
# Array has a single ellipsis subscript: the identity operator
|
|
ar2 = ar[...]
|
|
self.assertTrue(ar2 is ar)
|
|
|
|
# Ensure x and y are freed for p = array[x, y]
|
|
# Bug fix: reference counting
|
|
if hasattr(sys, 'getrefcount'):
|
|
class Int(int):
|
|
"""Unique int instances"""
|
|
pass
|
|
|
|
sf = pygame.Surface ((2, 2), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
x, y = Int(0), Int(1)
|
|
rx_before, ry_before = sys.getrefcount (x), sys.getrefcount (y)
|
|
p = ar[x, y]
|
|
rx_after, ry_after = sys.getrefcount (x), sys.getrefcount (y)
|
|
self.assertEqual (rx_after, rx_before)
|
|
self.assertEqual (ry_after, ry_before)
|
|
|
|
def test_ass_subscript (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((6, 8), 0, bpp)
|
|
sf.fill ((255, 255, 255))
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
# Test ellipse working
|
|
ar[...,...] = (0, 0, 0)
|
|
self.assertEqual (ar[0,0], 0)
|
|
self.assertEqual (ar[1,0], 0)
|
|
self.assertEqual (ar[-1,-1], 0)
|
|
ar[...,] = (0, 0, 255)
|
|
self.assertEqual (ar[0,0], sf.map_rgb ((0, 0, 255)))
|
|
self.assertEqual (ar[1,0], sf.map_rgb ((0, 0, 255)))
|
|
self.assertEqual (ar[-1,-1], sf.map_rgb ((0, 0, 255)))
|
|
ar[:,...] = (255, 0, 0)
|
|
self.assertEqual (ar[0,0], sf.map_rgb ((255, 0, 0)))
|
|
self.assertEqual (ar[1,0], sf.map_rgb ((255, 0, 0)))
|
|
self.assertEqual (ar[-1,-1], sf.map_rgb ((255, 0, 0)))
|
|
ar[...] = (0, 255, 0)
|
|
self.assertEqual (ar[0,0], sf.map_rgb ((0, 255, 0)))
|
|
self.assertEqual (ar[1,0], sf.map_rgb ((0, 255, 0)))
|
|
self.assertEqual (ar[-1,-1], sf.map_rgb ((0, 255, 0)))
|
|
|
|
# Ensure x and y are freed for array[x, y] = p
|
|
# Bug fix: reference counting
|
|
if hasattr(sys, 'getrefcount'):
|
|
class Int(int):
|
|
"""Unique int instances"""
|
|
pass
|
|
|
|
sf = pygame.Surface ((2, 2), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
x, y = Int(0), Int(1)
|
|
rx_before, ry_before = sys.getrefcount (x), sys.getrefcount (y)
|
|
ar[x, y] = 0
|
|
rx_after, ry_after = sys.getrefcount (x), sys.getrefcount (y)
|
|
self.assertEqual (rx_after, rx_before)
|
|
self.assertEqual (ry_after, ry_before)
|
|
|
|
def test_pixels_field(self):
|
|
for bpp in [1, 2, 3, 4]:
|
|
sf = pygame.Surface ((11, 7), 0, bpp * 8)
|
|
ar = pygame.PixelArray (sf)
|
|
ar2 = ar[1:,:]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
ar.itemsize)
|
|
ar2 = ar[:,1:]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
ar.strides[1])
|
|
ar2 = ar[::-1,:]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
(ar.shape[0] - 1) * ar.itemsize)
|
|
ar2 = ar[::-2,:]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
(ar.shape[0] - 1) * ar.itemsize)
|
|
ar2 = ar[:,::-1]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
(ar.shape[1] - 1) * ar.strides[1])
|
|
ar3 = ar2[::-1,:]
|
|
self.assertEqual (ar3._pixels_address - ar._pixels_address,
|
|
(ar.shape[0] - 1) * ar.strides[0] +
|
|
(ar.shape[1] - 1) * ar.strides[1])
|
|
ar2 = ar[:,::-2]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
(ar.shape[1] - 1) * ar.strides[1])
|
|
ar2 = ar[2::,3::]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
ar.strides[0] * 2 + ar.strides[1] * 3)
|
|
ar2 = ar[2::2,3::4]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
ar.strides[0] * 2 + ar.strides[1] * 3)
|
|
ar2 = ar[9:2:-1,:]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
ar.strides[0] * 9)
|
|
ar2 = ar[:,5:2:-1]
|
|
self.assertEqual (ar2._pixels_address - ar._pixels_address,
|
|
ar.strides[1] * 5)
|
|
##? ar2 = ar[:,9:2:-1]
|
|
|
|
def test_make_surface (self):
|
|
bg_color = pygame.Color (255, 255, 255)
|
|
fg_color = pygame.Color (128, 100, 0)
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 20), 0, bpp)
|
|
bg_color_adj = sf.unmap_rgb (sf.map_rgb (bg_color))
|
|
fg_color_adj = sf.unmap_rgb (sf.map_rgb (fg_color))
|
|
sf.fill (bg_color_adj)
|
|
sf.fill (fg_color_adj, (2, 5, 4, 11))
|
|
ar = pygame.PixelArray (sf)
|
|
newsf = ar[::2,::2].make_surface ()
|
|
rect = newsf.get_rect ()
|
|
self.assertEqual (rect.width, 5)
|
|
self.assertEqual (rect.height, 10)
|
|
for p in [(0, 2), (0, 3), (1, 2),
|
|
(2, 2), (3, 2), (3, 3),
|
|
(0, 7), (0, 8), (1, 8),
|
|
(2, 8), (3, 8), (3, 7)]:
|
|
self.assertEqual (newsf.get_at (p), bg_color_adj)
|
|
for p in [(1, 3), (2, 3), (1, 5), (2, 5), (1, 7), (2, 7)]:
|
|
self.assertEqual (newsf.get_at (p), fg_color_adj)
|
|
|
|
# Bug when array width is not a multiple of the slice step.
|
|
w = 17
|
|
lst = list(range(w))
|
|
w_slice = len(lst[::2])
|
|
h = 3
|
|
sf = pygame.Surface ((w, h), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
ar2 = ar[::2,:]
|
|
sf2 = ar2.make_surface ()
|
|
w2, h2 = sf2.get_size ()
|
|
self.assertEqual (w2, w_slice)
|
|
self.assertEqual (h2, h)
|
|
|
|
# Bug when array height is not a multiple of the slice step.
|
|
# This can hang the Python interpreter.
|
|
h = 17
|
|
lst = list(range(h))
|
|
h_slice = len(lst[::2])
|
|
w = 3
|
|
sf = pygame.Surface ((w, h), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
ar2 = ar[:,::2]
|
|
sf2 = ar2.make_surface () # Hangs here.
|
|
w2, h2 = sf2.get_size ()
|
|
self.assertEqual (w2, w)
|
|
self.assertEqual (h2, h_slice)
|
|
|
|
def test_make_surface__subclassed_surface(self):
|
|
"""Ensure make_surface can handle subclassed surfaces."""
|
|
expected_size = (3, 5)
|
|
expected_flags = 0
|
|
expected_depth = 32
|
|
original_surface = SurfaceSubclass(expected_size, expected_flags,
|
|
expected_depth)
|
|
pixelarray = pygame.PixelArray(original_surface)
|
|
|
|
surface = pixelarray.make_surface()
|
|
|
|
self.assertIsNot(surface, original_surface)
|
|
self.assertIsInstance(surface, pygame.Surface)
|
|
self.assertNotIsInstance(surface, SurfaceSubclass)
|
|
self.assertEqual(surface.get_size(), expected_size)
|
|
self.assertEqual(surface.get_flags(), expected_flags)
|
|
self.assertEqual(surface.get_bitsize(), expected_depth)
|
|
|
|
def test_iter (self):
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((5, 10), 0, bpp)
|
|
ar = pygame.PixelArray (sf)
|
|
iterations = 0
|
|
for col in ar:
|
|
self.assertEqual (len (col), 10)
|
|
iterations += 1
|
|
self.assertEqual (iterations, 5)
|
|
|
|
def test_replace (self):
|
|
#print "replace start"
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 10), 0, bpp)
|
|
sf.fill ((255, 0, 0))
|
|
rval = sf.map_rgb ((0, 0, 255))
|
|
oval = sf.map_rgb ((255, 0, 0))
|
|
ar = pygame.PixelArray (sf)
|
|
ar[::2].replace ((255, 0, 0), (0, 0, 255))
|
|
self.assertEqual (ar[0][0], rval)
|
|
self.assertEqual (ar[1][0], oval)
|
|
self.assertEqual (ar[2][3], rval)
|
|
self.assertEqual (ar[3][6], oval)
|
|
self.assertEqual (ar[8][9], rval)
|
|
self.assertEqual (ar[9][9], oval)
|
|
|
|
ar[::2].replace ((0, 0, 255), (255, 0, 0), weights=(10, 20, 50))
|
|
self.assertEqual (ar[0][0], oval)
|
|
self.assertEqual (ar[2][3], oval)
|
|
self.assertEqual (ar[3][6], oval)
|
|
self.assertEqual (ar[8][9], oval)
|
|
self.assertEqual (ar[9][9], oval)
|
|
#print "replace end"
|
|
|
|
def test_extract (self):
|
|
#print "extract start"
|
|
for bpp in (8, 16, 24, 32):
|
|
sf = pygame.Surface ((10, 10), 0, bpp)
|
|
sf.fill ((0, 0, 255))
|
|
sf.fill ((255, 0, 0), (2, 2, 6, 6))
|
|
|
|
white = sf.map_rgb ((255, 255, 255))
|
|
black = sf.map_rgb ((0, 0, 0))
|
|
|
|
ar = pygame.PixelArray (sf)
|
|
newar = ar.extract ((255, 0, 0))
|
|
|
|
self.assertEqual (newar[0][0], black)
|
|
self.assertEqual (newar[1][0], black)
|
|
self.assertEqual (newar[2][3], white)
|
|
self.assertEqual (newar[3][6], white)
|
|
self.assertEqual (newar[8][9], black)
|
|
self.assertEqual (newar[9][9], black)
|
|
|
|
newar = ar.extract ((255, 0, 0), weights=(10, 0.1, 50))
|
|
self.assertEqual (newar[0][0], black)
|
|
self.assertEqual (newar[1][0], black)
|
|
self.assertEqual (newar[2][3], white)
|
|
self.assertEqual (newar[3][6], white)
|
|
self.assertEqual (newar[8][9], black)
|
|
self.assertEqual (newar[9][9], black)
|
|
#print "extract end"
|
|
|
|
def test_2dslice_assignment (self):
|
|
w = 2 * 5 * 8
|
|
h = 3 * 5 * 9
|
|
sf = pygame.Surface ((w, h), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
size = (w, h)
|
|
strides = (1, w)
|
|
offset = 0
|
|
self._test_assignment (sf, ar, size, strides, offset)
|
|
xslice = slice (None, None, 2)
|
|
yslice = slice (None, None, 3)
|
|
ar, size, strides, offset = self._array_slice (
|
|
ar, size, (xslice, yslice), strides, offset)
|
|
self._test_assignment (sf, ar, size, strides, offset)
|
|
xslice = slice (5, None, 5)
|
|
yslice = slice (5, None, 5)
|
|
ar, size, strides, offset = self._array_slice (
|
|
ar, size, (xslice, yslice), strides, offset)
|
|
self._test_assignment (sf, ar, size, strides, offset)
|
|
|
|
def _test_assignment (self, sf, ar, ar_size, ar_strides, ar_offset):
|
|
self.assertEqual (ar.shape, ar_size)
|
|
ar_w, ar_h = ar_size
|
|
ar_xstride, ar_ystride = ar_strides
|
|
sf_w, sf_h = sf.get_size ()
|
|
black = pygame.Color ('black')
|
|
color = pygame.Color (0, 0, 12)
|
|
pxcolor = sf.map_rgb (color)
|
|
sf.fill (black)
|
|
for ar_x, ar_y in [(0, 0),
|
|
(0, ar_h - 4),
|
|
(ar_w - 3, 0),
|
|
(0, ar_h - 1),
|
|
(ar_w - 1, 0),
|
|
(ar_w - 1, ar_h - 1)]:
|
|
sf_offset = ar_offset + ar_x * ar_xstride + ar_y * ar_ystride
|
|
sf_y = sf_offset // sf_w
|
|
sf_x = sf_offset - sf_y * sf_w
|
|
sf_posn = (sf_x, sf_y)
|
|
sf_pix = sf.get_at (sf_posn)
|
|
self.assertEqual (sf_pix, black,
|
|
"at pixarr posn (%i, %i) (surf posn (%i, %i)): "
|
|
"%s != %s" %
|
|
(ar_x, ar_y, sf_x, sf_y, sf_pix, black))
|
|
ar[ar_x, ar_y] = pxcolor
|
|
sf_pix = sf.get_at (sf_posn)
|
|
self.assertEqual (sf_pix, color,
|
|
"at pixarr posn (%i, %i) (surf posn (%i, %i)): "
|
|
"%s != %s" %
|
|
(ar_x, ar_y, sf_x, sf_y, sf_pix, color))
|
|
|
|
def _array_slice (self, ar, size, slices, strides, offset):
|
|
ar = ar[slices]
|
|
xslice, yslice = slices
|
|
w, h = size
|
|
xstart, xstop, xstep = xslice.indices(w)
|
|
ystart, ystop, ystep = yslice.indices(h)
|
|
w = (xstop - xstart + xstep - 1) // xstep
|
|
h = (ystop - ystart + ystep - 1) // ystep
|
|
xstride, ystride = strides
|
|
offset += xstart * xstride + ystart * ystride
|
|
xstride *= xstep
|
|
ystride *= ystep
|
|
return ar, (w, h), (xstride, ystride), offset
|
|
|
|
def test_array_properties(self):
|
|
# itemsize, ndim, shape, and strides.
|
|
for bpp in [1, 2, 3, 4]:
|
|
sf = pygame.Surface ((2, 2), 0, bpp * 8)
|
|
ar = pygame.PixelArray (sf)
|
|
self.assertEqual (ar.itemsize, bpp)
|
|
|
|
for shape in [(4, 16), (5, 13)]:
|
|
w, h = shape
|
|
sf = pygame.Surface (shape, 0, 32)
|
|
bpp = sf.get_bytesize ()
|
|
pitch = sf.get_pitch ()
|
|
ar = pygame.PixelArray (sf)
|
|
self.assertEqual (ar.ndim, 2)
|
|
self.assertEqual (ar.shape, shape)
|
|
self.assertEqual (ar.strides, (bpp, pitch))
|
|
ar2 = ar[::2,:]
|
|
w2 = len(([0] * w)[::2])
|
|
self.assertEqual (ar2.ndim, 2)
|
|
self.assertEqual (ar2.shape, (w2, h))
|
|
self.assertEqual (ar2.strides, (2 * bpp, pitch))
|
|
ar2 = ar[:,::2]
|
|
h2 = len(([0] * h)[::2])
|
|
self.assertEqual (ar2.ndim, 2)
|
|
self.assertEqual (ar2.shape, (w, h2))
|
|
self.assertEqual (ar2.strides, (bpp, 2 * pitch))
|
|
ar2 = ar[1]
|
|
self.assertEqual (ar2.ndim, 1)
|
|
self.assertEqual (ar2.shape, (h,))
|
|
self.assertEqual (ar2.strides, (pitch,))
|
|
ar2 = ar[:,1]
|
|
self.assertEqual (ar2.ndim, 1)
|
|
self.assertEqual (ar2.shape, (w,))
|
|
self.assertEqual (ar2.strides, (bpp,))
|
|
|
|
def test_self_assign(self):
|
|
# This differs from NumPy arrays.
|
|
w = 10
|
|
max_x = w - 1
|
|
h = 20
|
|
max_y = h - 1
|
|
for bpp in [1, 2, 3, 4]:
|
|
sf = pygame.Surface ((w, h), 0, bpp * 8)
|
|
ar = pygame.PixelArray (sf)
|
|
for i in range (w * h):
|
|
ar[i % w, i // w] = i
|
|
ar[:,:] = ar[::-1,:]
|
|
for i in range (w * h):
|
|
self.assertEqual (ar[max_x - i % w, i // w], i)
|
|
ar = pygame.PixelArray (sf)
|
|
for i in range (w * h):
|
|
ar[i % w, i // w] = i
|
|
ar[:,:] = ar[:,::-1]
|
|
for i in range (w * h):
|
|
self.assertEqual (ar[i % w, max_y - i // w ], i)
|
|
ar = pygame.PixelArray (sf)
|
|
for i in range(w * h):
|
|
ar[i % w, i // w] = i
|
|
ar[:,:] = ar[::-1,::-1]
|
|
for i in range (w * h):
|
|
self.assertEqual (ar[max_x - i % w, max_y - i // w], i)
|
|
|
|
def test_color_value (self):
|
|
# Confirm that a PixelArray slice assignment distinguishes between
|
|
# pygame.Color and tuple objects as single (r, g, b[, a]) colors
|
|
# and other sequences as sequences of colors to be treated as
|
|
# slices.
|
|
sf = pygame.Surface ((5, 5), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
index = slice(None, None, 1)
|
|
ar.__setitem__ (index, (1, 2, 3))
|
|
self.assertEqual (ar[0, 0], sf.map_rgb ((1, 2, 3)))
|
|
ar.__setitem__ (index, pygame.Color (10, 11, 12))
|
|
self.assertEqual (ar[0, 0], sf.map_rgb ((10, 11, 12)))
|
|
self.assertRaises (ValueError, ar.__setitem__, index, (1, 2, 3, 4, 5))
|
|
self.assertRaises (ValueError, ar.__setitem__, (index, index),
|
|
(1, 2, 3, 4, 5))
|
|
self.assertRaises (ValueError, ar.__setitem__, index, [1, 2, 3])
|
|
self.assertRaises (ValueError, ar.__setitem__, (index, index),
|
|
[1, 2, 3])
|
|
sf = pygame.Surface ((3, 3), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
ar[:] = (20, 30, 40)
|
|
self.assertEqual (ar[0, 0], sf.map_rgb ((20, 30, 40)))
|
|
ar[:] = [20, 30, 40]
|
|
self.assertEqual (ar[0, 0], 20)
|
|
self.assertEqual (ar[1, 0], 30)
|
|
self.assertEqual (ar[2, 0], 40)
|
|
|
|
def test_transpose (self):
|
|
# PixelArray.transpose(): swap axis on a 2D array, add a length
|
|
# 1 x axis to a 1D array.
|
|
sf = pygame.Surface ((3, 7), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
w, h = ar.shape
|
|
dx, dy = ar.strides
|
|
for i in range (w * h):
|
|
x = i % w
|
|
y = i // w
|
|
ar[x, y] = i
|
|
ar_t = ar.transpose()
|
|
self.assertEqual (ar_t.shape, (h, w))
|
|
self.assertEqual (ar_t.strides, (dy, dx))
|
|
for i in range (w * h):
|
|
x = i % w
|
|
y = i // w
|
|
self.assertEqual (ar_t[y, x], ar[x, y])
|
|
ar1D = ar[0]
|
|
ar2D = ar1D.transpose()
|
|
self.assertEqual (ar2D.shape, (1, h))
|
|
for y in range (h):
|
|
self.assertEqual (ar1D[y], ar2D[0, y])
|
|
ar1D = ar[:,0]
|
|
ar2D = ar1D.transpose()
|
|
self.assertEqual (ar2D.shape, (1, w))
|
|
for x in range (2):
|
|
self.assertEqual (ar1D[x], ar2D[0, x])
|
|
|
|
def test_length_1_dimension_broadcast (self):
|
|
w = 5
|
|
sf = pygame.Surface ((w, w), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
# y-axis broadcast.
|
|
sf_x = pygame.Surface ((w, 1), 0, 32)
|
|
ar_x = pygame.PixelArray (sf_x)
|
|
for i in range (w):
|
|
ar_x[i, 0] = (w + 1) * 10
|
|
ar[...] = ar_x
|
|
for y in range (w):
|
|
for x in range (w):
|
|
self.assertEqual (ar[x, y], ar_x[x, 0])
|
|
# x-axis broadcast.
|
|
ar[...] = 0
|
|
sf_y = pygame.Surface ((1, w), 0, 32)
|
|
ar_y = pygame.PixelArray (sf_y)
|
|
for i in range (w):
|
|
ar_y[0, i] = (w + 1) * 10
|
|
ar[...] = ar_y
|
|
for x in range (w):
|
|
for y in range (w):
|
|
self.assertEqual (ar[x, y], ar_y[0, y])
|
|
# (1, 1) array broadcast.
|
|
ar[...] = 0
|
|
sf_1px = pygame.Surface ((1, 1), 0, 32)
|
|
ar_1px = pygame.PixelArray (sf_1px)
|
|
ar_1px[0, 0] = 42 # Well it had to show up somewhere.
|
|
ar[...] = ar_1px
|
|
for y in range (w):
|
|
for x in range (w):
|
|
self.assertEqual (ar[x, y], 42)
|
|
|
|
def test_assign_size_mismatch (self):
|
|
sf = pygame.Surface ((7, 11), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
self.assertRaises (ValueError, ar.__setitem__, Ellipsis, ar[:, 0:2])
|
|
self.assertRaises (ValueError, ar.__setitem__, Ellipsis, ar[0:2, :])
|
|
|
|
def test_repr (self):
|
|
# Python 3.x bug: the tp_repr slot function returned NULL instead
|
|
# of a Unicode string, triggering an exception.
|
|
sf = pygame.Surface ((3, 1), pygame.SRCALPHA, 16)
|
|
ar = pygame.PixelArray(sf)
|
|
ar[...] = 42
|
|
pixel = sf.get_at_mapped ((0, 0))
|
|
self.assertEqual(repr (ar),
|
|
type (ar).__name__ + "([\n [42, 42, 42]]\n)")
|
|
|
|
|
|
class PixelArrayArrayInterfaceTest(unittest.TestCase, TestMixin):
|
|
|
|
@unittest.skipIf(IS_PYPY, 'skipping for PyPy (why?)')
|
|
def test_basic (self):
|
|
# Check unchanging fields.
|
|
sf = pygame.Surface ((2, 2), 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
|
|
ai = arrinter.ArrayInterface (ar)
|
|
self.assertEqual (ai.two, 2)
|
|
self.assertEqual (ai.typekind, 'u')
|
|
self.assertEqual (ai.nd, 2)
|
|
self.assertEqual (ai.data, ar._pixels_address)
|
|
|
|
@unittest.skipIf(IS_PYPY, 'skipping for PyPy (why?)')
|
|
def test_shape(self):
|
|
|
|
for shape in [[4, 16], [5, 13]]:
|
|
w, h = shape
|
|
sf = pygame.Surface (shape, 0, 32)
|
|
ar = pygame.PixelArray (sf)
|
|
ai = arrinter.ArrayInterface (ar)
|
|
ai_shape = [ai.shape[i] for i in range(ai.nd)]
|
|
self.assertEqual (ai_shape, shape)
|
|
ar2 = ar[::2,:]
|
|
ai2 = arrinter.ArrayInterface (ar2)
|
|
w2 = len(([0] * w)[::2])
|
|
ai_shape = [ai2.shape[i] for i in range(ai2.nd)]
|
|
self.assertEqual (ai_shape, [w2, h])
|
|
ar2 = ar[:,::2]
|
|
ai2 = arrinter.ArrayInterface (ar2)
|
|
h2 = len(([0] * h)[::2])
|
|
ai_shape = [ai2.shape[i] for i in range(ai2.nd)]
|
|
self.assertEqual (ai_shape, [w, h2])
|
|
|
|
@unittest.skipIf(IS_PYPY, 'skipping for PyPy (why?)')
|
|
def test_itemsize (self):
|
|
for bytes_per_pixel in range(1, 5):
|
|
bits_per_pixel = 8 * bytes_per_pixel
|
|
sf = pygame.Surface ((2, 2), 0, bits_per_pixel)
|
|
ar = pygame.PixelArray (sf)
|
|
ai = arrinter.ArrayInterface (ar)
|
|
self.assertEqual (ai.itemsize, bytes_per_pixel)
|
|
|
|
@unittest.skipIf(IS_PYPY, 'skipping for PyPy (why?)')
|
|
def test_flags (self):
|
|
aim = arrinter
|
|
common_flags = (aim.PAI_NOTSWAPPED | aim.PAI_WRITEABLE |
|
|
aim.PAI_ALIGNED)
|
|
s = pygame.Surface ((10, 2), 0, 32)
|
|
ar = pygame.PixelArray (s)
|
|
ai = aim.ArrayInterface (ar)
|
|
self.assertEqual (ai.flags, common_flags | aim.PAI_FORTRAN)
|
|
|
|
ar2 = ar[::2,:]
|
|
ai = aim.ArrayInterface (ar2)
|
|
self.assertEqual (ai.flags, common_flags)
|
|
|
|
s = pygame.Surface ((8, 2), 0, 24)
|
|
ar = pygame.PixelArray (s)
|
|
ai = aim.ArrayInterface (ar)
|
|
self.assertEqual (ai.flags, common_flags | aim.PAI_FORTRAN)
|
|
|
|
s = pygame.Surface ((7, 2), 0, 24)
|
|
ar = pygame.PixelArray (s)
|
|
ai = aim.ArrayInterface (ar)
|
|
self.assertEqual (ai.flags, common_flags)
|
|
|
|
def test_slicing (self):
|
|
# This will implicitly test data and strides fields.
|
|
#
|
|
# Need an 8 bit test surfaces because pixelcopy.make_surface
|
|
# returns an 8 bit surface for a 2d array.
|
|
|
|
factors = [7, 3, 11]
|
|
|
|
w = reduce (operator.mul, factors, 1)
|
|
h = 13
|
|
sf = pygame.Surface ((w, h), 0, 8)
|
|
color = sf.map_rgb ((1, 17, 128))
|
|
ar = pygame.PixelArray (sf)
|
|
for f in factors[:-1]:
|
|
w = w // f
|
|
sf.fill ((0, 0, 0))
|
|
ar = ar[f:f + w,:]
|
|
ar[0][0] = color
|
|
ar[-1][-2] = color
|
|
ar[0][-3] = color
|
|
sf2 = ar.make_surface ()
|
|
sf3 = pygame.pixelcopy.make_surface (ar)
|
|
self.assert_surfaces_equal (sf3, sf2)
|
|
|
|
h = reduce (operator.mul, factors, 1)
|
|
w = 13
|
|
sf = pygame.Surface ((w, h), 0, 8)
|
|
color = sf.map_rgb ((1, 17, 128))
|
|
ar = pygame.PixelArray (sf)
|
|
for f in factors[:-1]:
|
|
h = h // f
|
|
sf.fill ((0, 0, 0))
|
|
ar = ar[:,f:f + h]
|
|
ar[0][0] = color
|
|
ar[-1][-2] = color
|
|
ar[0][-3] = color
|
|
sf2 = ar.make_surface ()
|
|
sf3 = pygame.pixelcopy.make_surface (ar)
|
|
self.assert_surfaces_equal (sf3, sf2)
|
|
|
|
w = 20
|
|
h = 10
|
|
sf = pygame.Surface ((w, h), 0, 8)
|
|
color = sf.map_rgb ((1, 17, 128))
|
|
ar = pygame.PixelArray (sf)
|
|
for slices in [(slice (w), slice (h)),
|
|
(slice (0, w, 2), slice (h)),
|
|
(slice (0, w, 3), slice (h)),
|
|
(slice (w), slice (0, h, 2)),
|
|
(slice (w), slice (0, h, 3)),
|
|
(slice (0, w, 2), slice (0, h, 2)),
|
|
(slice (0, w, 3), slice (0, h, 3)),
|
|
]:
|
|
sf.fill ((0, 0, 0))
|
|
ar2 = ar[slices]
|
|
ar2[0][0] = color
|
|
ar2[-1][-2] = color
|
|
ar2[0][-3] = color
|
|
sf2 = ar2.make_surface ()
|
|
sf3 = pygame.pixelcopy.make_surface (ar2)
|
|
self.assert_surfaces_equal (sf3, sf2)
|
|
|
|
|
|
@unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
|
|
class PixelArrayNewBufferTest(unittest.TestCase, TestMixin):
|
|
|
|
if pygame.HAVE_NEWBUF:
|
|
from pygame.tests.test_utils import buftools
|
|
|
|
bitsize_to_format = {8: 'B', 16: '=H', 24: '3x', 32: '=I'}
|
|
|
|
def test_newbuf_2D (self):
|
|
buftools = self.buftools
|
|
Importer = buftools.Importer
|
|
|
|
for bit_size in [8, 16, 24, 32]:
|
|
s = pygame.Surface ((10, 2), 0, bit_size)
|
|
ar = pygame.PixelArray (s)
|
|
format = self.bitsize_to_format[bit_size]
|
|
itemsize = ar.itemsize
|
|
shape = ar.shape
|
|
w, h = shape
|
|
strides = ar.strides
|
|
length = w * h * itemsize
|
|
imp = Importer (ar, buftools.PyBUF_FULL)
|
|
self.assertTrue (imp.obj, ar)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 2)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertEqual (imp.format, format)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertTrue (imp.suboffsets is None)
|
|
self.assertEqual (imp.buf, s._pixels_address)
|
|
|
|
s = pygame.Surface ((8, 16), 0, 32)
|
|
ar = pygame.PixelArray (s)
|
|
format = self.bitsize_to_format[s.get_bitsize ()]
|
|
itemsize = ar.itemsize
|
|
shape = ar.shape
|
|
w, h = shape
|
|
strides = ar.strides
|
|
length = w * h * itemsize
|
|
imp = Importer (ar, buftools.PyBUF_SIMPLE)
|
|
self.assertTrue (imp.obj, ar)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 0)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertTrue (imp.shape is None)
|
|
self.assertTrue (imp.strides is None)
|
|
self.assertTrue (imp.suboffsets is None)
|
|
self.assertEqual (imp.buf, s._pixels_address)
|
|
imp = Importer (ar, buftools.PyBUF_FORMAT)
|
|
self.assertEqual (imp.ndim, 0)
|
|
self.assertEqual (imp.format, format)
|
|
imp = Importer (ar, buftools.PyBUF_WRITABLE)
|
|
self.assertEqual (imp.ndim, 0)
|
|
self.assertTrue (imp.format is None)
|
|
imp = Importer (ar, buftools.PyBUF_F_CONTIGUOUS)
|
|
self.assertEqual (imp.ndim, 2)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
imp = Importer (ar, buftools.PyBUF_ANY_CONTIGUOUS)
|
|
self.assertEqual (imp.ndim, 2)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_C_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar, buftools.PyBUF_ND)
|
|
|
|
ar_sliced = ar[:,::2]
|
|
format = self.bitsize_to_format[s.get_bitsize ()]
|
|
itemsize = ar_sliced.itemsize
|
|
shape = ar_sliced.shape
|
|
w, h = shape
|
|
strides = ar_sliced.strides
|
|
length = w * h * itemsize
|
|
imp = Importer (ar_sliced, buftools.PyBUF_STRIDED)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 2)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertEqual (imp.buf, s._pixels_address)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_SIMPLE)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_ND)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_C_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_F_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_ANY_CONTIGUOUS)
|
|
|
|
ar_sliced = ar[::2,:]
|
|
format = self.bitsize_to_format[s.get_bitsize ()]
|
|
itemsize = ar_sliced.itemsize
|
|
shape = ar_sliced.shape
|
|
w, h = shape
|
|
strides = ar_sliced.strides
|
|
length = w * h * itemsize
|
|
imp = Importer (ar_sliced, buftools.PyBUF_STRIDED)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 2)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertEqual (imp.buf, s._pixels_address)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_SIMPLE)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_ND)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_C_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_F_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar_sliced,
|
|
buftools.PyBUF_ANY_CONTIGUOUS)
|
|
|
|
s2 = s.subsurface ((2, 3, 5, 7))
|
|
ar = pygame.PixelArray (s2)
|
|
format = self.bitsize_to_format[s.get_bitsize ()]
|
|
itemsize = ar.itemsize
|
|
shape = ar.shape
|
|
w, h = shape
|
|
strides = ar.strides
|
|
length = w * h * itemsize
|
|
imp = Importer (ar, buftools.PyBUF_STRIDES)
|
|
self.assertTrue (imp.obj, ar)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 2)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertTrue (imp.suboffsets is None)
|
|
self.assertEqual (imp.buf, s2._pixels_address)
|
|
self.assertRaises (BufferError, Importer, ar, buftools.PyBUF_SIMPLE)
|
|
self.assertRaises (BufferError, Importer, ar, buftools.PyBUF_FORMAT)
|
|
self.assertRaises (BufferError, Importer, ar, buftools.PyBUF_WRITABLE)
|
|
self.assertRaises (BufferError, Importer, ar, buftools.PyBUF_ND)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_C_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_F_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_ANY_CONTIGUOUS)
|
|
|
|
def test_newbuf_1D(self):
|
|
buftools = self.buftools
|
|
Importer = buftools.Importer
|
|
|
|
s = pygame.Surface ((2, 16), 0, 32)
|
|
ar_2D = pygame.PixelArray (s)
|
|
x = 0
|
|
ar = ar_2D[x]
|
|
format = self.bitsize_to_format[s.get_bitsize ()]
|
|
itemsize = ar.itemsize
|
|
shape = ar.shape
|
|
h = shape[0]
|
|
strides = ar.strides
|
|
length = h * itemsize
|
|
buf = s._pixels_address + x * itemsize
|
|
imp = Importer (ar, buftools.PyBUF_STRIDES)
|
|
self.assertTrue (imp.obj, ar)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 1)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertTrue (imp.suboffsets is None)
|
|
self.assertEqual (imp.buf, buf)
|
|
imp = Importer (ar, buftools.PyBUF_FULL)
|
|
self.assertEqual (imp.ndim, 1)
|
|
self.assertEqual (imp.format, format)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_SIMPLE)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_FORMAT)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_WRITABLE)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_ND)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_C_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_F_CONTIGUOUS)
|
|
self.assertRaises (BufferError, Importer, ar,
|
|
buftools.PyBUF_ANY_CONTIGUOUS)
|
|
y = 10
|
|
ar = ar_2D[:,y]
|
|
shape = ar.shape
|
|
w = shape[0]
|
|
strides = ar.strides
|
|
length = w * itemsize
|
|
buf = s._pixels_address + y * s.get_pitch()
|
|
imp = Importer (ar, buftools.PyBUF_FULL)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 1)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertEqual (imp.format, format)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertEqual (imp.strides, strides)
|
|
self.assertEqual (imp.buf, buf)
|
|
self.assertTrue (imp.suboffsets is None)
|
|
imp = Importer (ar, buftools.PyBUF_SIMPLE)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 0)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertTrue (imp.shape is None)
|
|
self.assertTrue (imp.strides is None)
|
|
imp = Importer (ar, buftools.PyBUF_ND)
|
|
self.assertEqual (imp.len, length)
|
|
self.assertEqual (imp.ndim, 1)
|
|
self.assertEqual (imp.itemsize, itemsize)
|
|
self.assertTrue (imp.format is None)
|
|
self.assertFalse (imp.readonly)
|
|
self.assertEqual (imp.shape, shape)
|
|
self.assertTrue (imp.strides is None)
|
|
imp = Importer (ar, buftools.PyBUF_C_CONTIGUOUS)
|
|
self.assertEqual (imp.ndim, 1)
|
|
imp = Importer (ar, buftools.PyBUF_F_CONTIGUOUS)
|
|
self.assertEqual (imp.ndim, 1)
|
|
imp = Importer (ar, buftools.PyBUF_ANY_CONTIGUOUS)
|
|
self.assertEqual (imp.ndim, 1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|