1668 lines
61 KiB
Python
1668 lines
61 KiB
Python
|
import gc
|
||
|
import operator
|
||
|
import platform
|
||
|
import sys
|
||
|
import unittest
|
||
|
import weakref
|
||
|
from functools import reduce
|
||
|
|
||
|
from pygame.tests.test_utils import SurfaceSubclass
|
||
|
|
||
|
try:
|
||
|
from pygame.tests.test_utils import arrinter
|
||
|
except NameError:
|
||
|
pass
|
||
|
|
||
|
import pygame
|
||
|
|
||
|
|
||
|
IS_PYPY = "PyPy" == platform.python_implementation()
|
||
|
|
||
|
|
||
|
class TestMixin:
|
||
|
def assert_surfaces_equal(self, s1, s2, msg=None):
|
||
|
"""Checks if two surfaces are equal in size and color."""
|
||
|
w, h = s1.get_size()
|
||
|
|
||
|
self.assertTupleEqual((w, h), s2.get_size(), msg)
|
||
|
|
||
|
msg = "" if msg is None else f"{msg}, "
|
||
|
msg += f"size: ({w}, {h})"
|
||
|
|
||
|
for x in range(w):
|
||
|
for y in range(h):
|
||
|
self.assertEqual(
|
||
|
s1.get_at((x, y)),
|
||
|
s2.get_at((x, y)),
|
||
|
f"{msg}, position: ({x}, {y})",
|
||
|
)
|
||
|
|
||
|
def assert_surface_filled(self, surface, expected_color, msg=None):
|
||
|
"""Checks if the surface is filled with the given color."""
|
||
|
width, height = surface.get_size()
|
||
|
|
||
|
surface.lock() # Lock for possible speed up.
|
||
|
for pos in ((x, y) for y in range(height) for x in range(width)):
|
||
|
self.assertEqual(surface.get_at(pos), expected_color, msg)
|
||
|
surface.unlock()
|
||
|
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy having issues")
|
||
|
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_compare__same_colors_within_distance(self):
|
||
|
"""Ensures compare works correctly with same colored surfaces."""
|
||
|
size = (3, 5)
|
||
|
pixelarray_result_color = pygame.Color("white")
|
||
|
surface_color = (127, 127, 127, 255)
|
||
|
|
||
|
for depth in (8, 16, 24, 32):
|
||
|
expected_pixelarray_surface = pygame.Surface(size, depth=depth)
|
||
|
expected_pixelarray_surface.fill(pixelarray_result_color)
|
||
|
|
||
|
# Copy the surface to ensure same dimensions/formatting.
|
||
|
surf_a = expected_pixelarray_surface.copy()
|
||
|
surf_a.fill(surface_color)
|
||
|
# For non-32 bit depths, the actual color can be different from what
|
||
|
# was filled.
|
||
|
expected_surface_color = surf_a.get_at((0, 0))
|
||
|
|
||
|
pixelarray_a = pygame.PixelArray(surf_a)
|
||
|
pixelarray_b = pygame.PixelArray(surf_a.copy())
|
||
|
|
||
|
for distance in (0.0, 0.01, 0.1, 1.0):
|
||
|
pixelarray_result = pixelarray_a.compare(
|
||
|
pixelarray_b, distance=distance
|
||
|
)
|
||
|
|
||
|
# Ensure the resulting pixelarray is correct and that the original
|
||
|
# surfaces were not changed.
|
||
|
self.assert_surfaces_equal(
|
||
|
pixelarray_result.surface,
|
||
|
expected_pixelarray_surface,
|
||
|
(depth, distance),
|
||
|
)
|
||
|
self.assert_surface_filled(
|
||
|
pixelarray_a.surface, expected_surface_color, (depth, distance)
|
||
|
)
|
||
|
self.assert_surface_filled(
|
||
|
pixelarray_b.surface, expected_surface_color, (depth, distance)
|
||
|
)
|
||
|
|
||
|
pixelarray_a.close()
|
||
|
pixelarray_b.close()
|
||
|
pixelarray_result.close()
|
||
|
|
||
|
def test_compare__different_colors_within_distance(self):
|
||
|
"""Ensures compare works correctly with different colored surfaces
|
||
|
and the color difference is within the given distance.
|
||
|
"""
|
||
|
size = (3, 5)
|
||
|
pixelarray_result_color = pygame.Color("white")
|
||
|
surface_a_color = (127, 127, 127, 255)
|
||
|
surface_b_color = (128, 127, 127, 255)
|
||
|
|
||
|
for depth in (8, 16, 24, 32):
|
||
|
expected_pixelarray_surface = pygame.Surface(size, depth=depth)
|
||
|
expected_pixelarray_surface.fill(pixelarray_result_color)
|
||
|
|
||
|
# Copy the surface to ensure same dimensions/formatting.
|
||
|
surf_a = expected_pixelarray_surface.copy()
|
||
|
surf_a.fill(surface_a_color)
|
||
|
# For non-32 bit depths, the actual color can be different from what
|
||
|
# was filled.
|
||
|
expected_surface_a_color = surf_a.get_at((0, 0))
|
||
|
pixelarray_a = pygame.PixelArray(surf_a)
|
||
|
|
||
|
surf_b = expected_pixelarray_surface.copy()
|
||
|
surf_b.fill(surface_b_color)
|
||
|
# For non-32 bit depths, the actual color can be different from what
|
||
|
# was filled.
|
||
|
expected_surface_b_color = surf_b.get_at((0, 0))
|
||
|
pixelarray_b = pygame.PixelArray(surf_b)
|
||
|
|
||
|
for distance in (0.2, 0.3, 0.5, 1.0):
|
||
|
pixelarray_result = pixelarray_a.compare(
|
||
|
pixelarray_b, distance=distance
|
||
|
)
|
||
|
|
||
|
# Ensure the resulting pixelarray is correct and that the original
|
||
|
# surfaces were not changed.
|
||
|
self.assert_surfaces_equal(
|
||
|
pixelarray_result.surface,
|
||
|
expected_pixelarray_surface,
|
||
|
(depth, distance),
|
||
|
)
|
||
|
self.assert_surface_filled(
|
||
|
pixelarray_a.surface, expected_surface_a_color, (depth, distance)
|
||
|
)
|
||
|
self.assert_surface_filled(
|
||
|
pixelarray_b.surface, expected_surface_b_color, (depth, distance)
|
||
|
)
|
||
|
|
||
|
pixelarray_a.close()
|
||
|
pixelarray_b.close()
|
||
|
pixelarray_result.close()
|
||
|
|
||
|
def test_compare__different_colors_not_within_distance(self):
|
||
|
"""Ensures compare works correctly with different colored surfaces
|
||
|
and the color difference is not within the given distance.
|
||
|
"""
|
||
|
size = (3, 5)
|
||
|
pixelarray_result_color = pygame.Color("black")
|
||
|
surface_a_color = (127, 127, 127, 255)
|
||
|
surface_b_color = (128, 127, 127, 255)
|
||
|
|
||
|
for depth in (8, 16, 24, 32):
|
||
|
expected_pixelarray_surface = pygame.Surface(size, depth=depth)
|
||
|
expected_pixelarray_surface.fill(pixelarray_result_color)
|
||
|
|
||
|
# Copy the surface to ensure same dimensions/formatting.
|
||
|
surf_a = expected_pixelarray_surface.copy()
|
||
|
surf_a.fill(surface_a_color)
|
||
|
# For non-32 bit depths, the actual color can be different from what
|
||
|
# was filled.
|
||
|
expected_surface_a_color = surf_a.get_at((0, 0))
|
||
|
pixelarray_a = pygame.PixelArray(surf_a)
|
||
|
|
||
|
surf_b = expected_pixelarray_surface.copy()
|
||
|
surf_b.fill(surface_b_color)
|
||
|
# For non-32 bit depths, the actual color can be different from what
|
||
|
# was filled.
|
||
|
expected_surface_b_color = surf_b.get_at((0, 0))
|
||
|
pixelarray_b = pygame.PixelArray(surf_b)
|
||
|
|
||
|
for distance in (0.0, 0.00001, 0.0001, 0.001):
|
||
|
pixelarray_result = pixelarray_a.compare(
|
||
|
pixelarray_b, distance=distance
|
||
|
)
|
||
|
|
||
|
# Ensure the resulting pixelarray is correct and that the original
|
||
|
# surfaces were not changed.
|
||
|
self.assert_surfaces_equal(
|
||
|
pixelarray_result.surface,
|
||
|
expected_pixelarray_surface,
|
||
|
(depth, distance),
|
||
|
)
|
||
|
self.assert_surface_filled(
|
||
|
pixelarray_a.surface, expected_surface_a_color, (depth, distance)
|
||
|
)
|
||
|
self.assert_surface_filled(
|
||
|
pixelarray_b.surface, expected_surface_b_color, (depth, distance)
|
||
|
)
|
||
|
|
||
|
pixelarray_a.close()
|
||
|
pixelarray_b.close()
|
||
|
pixelarray_result.close()
|
||
|
|
||
|
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 access_after():
|
||
|
a[:]
|
||
|
|
||
|
self.assertRaises(ValueError, access_after)
|
||
|
|
||
|
def assign_all_after():
|
||
|
a[:] = 1
|
||
|
|
||
|
self.assertRaises(ValueError, assign_all_after)
|
||
|
|
||
|
def make_surface_after():
|
||
|
a.make_surface()
|
||
|
|
||
|
self.assertRaises(ValueError, make_surface_after)
|
||
|
|
||
|
def iter_after():
|
||
|
for x in a:
|
||
|
pass
|
||
|
|
||
|
self.assertRaises(ValueError, iter_after)
|
||
|
|
||
|
def close_after():
|
||
|
a.close()
|
||
|
|
||
|
self.assertRaises(ValueError, close_after)
|
||
|
|
||
|
def surface_after():
|
||
|
a.surface
|
||
|
|
||
|
self.assertRaises(ValueError, surface_after)
|
||
|
|
||
|
def itemsize_after():
|
||
|
a.itemsize
|
||
|
|
||
|
self.assertRaises(ValueError, itemsize_after)
|
||
|
|
||
|
def transpose_after():
|
||
|
a.transpose()
|
||
|
|
||
|
self.assertRaises(ValueError, transpose_after)
|
||
|
|
||
|
def test_context_manager(self):
|
||
|
"""closes properly."""
|
||
|
s = pygame.Surface((10, 10))
|
||
|
with pygame.PixelArray(s) as a:
|
||
|
a[:]
|
||
|
|
||
|
# Test pixel array write... will also catch refcount issues and
|
||
|
# segfault
|
||
|
with pygame.PixelArray(s) as a:
|
||
|
a[:] = pygame.Color("deepskyblue")
|
||
|
|
||
|
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)
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy malloc abort")
|
||
|
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 range(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 range(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)")
|
||
|
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy having issues")
|
||
|
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")
|
||
|
@unittest.skipIf(IS_PYPY, "pypy having issues")
|
||
|
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()
|