|
|
|
|
#
|
|
|
|
|
# This file is part of Magnum.
|
|
|
|
|
#
|
|
|
|
|
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
|
|
|
|
|
# 2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
|
|
|
|
|
#
|
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
# copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
# to deal in the Software without restriction, including without limitation
|
|
|
|
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
# and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
# Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
#
|
|
|
|
|
# The above copyright notice and this permission notice shall be included
|
|
|
|
|
# in all copies or substantial portions of the Software.
|
|
|
|
|
#
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
# DEALINGS IN THE SOFTWARE.
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
import array
|
|
|
|
|
import sys
|
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
|
|
from corrade import utility
|
|
|
|
|
from magnum import *
|
|
|
|
|
|
|
|
|
|
# tests also corrade.utility.copy() in UtilityCopy
|
|
|
|
|
|
|
|
|
|
class PixelStorage_(unittest.TestCase):
|
|
|
|
|
def test_init(self):
|
|
|
|
|
a = PixelStorage()
|
|
|
|
|
self.assertEqual(a.alignment, 4)
|
|
|
|
|
self.assertEqual(a.row_length, 0)
|
|
|
|
|
self.assertEqual(a.image_height, 0)
|
|
|
|
|
self.assertEqual(a.skip, Vector3i())
|
|
|
|
|
|
|
|
|
|
def test_properties(self):
|
|
|
|
|
a = PixelStorage()
|
|
|
|
|
a.alignment = 1
|
|
|
|
|
a.row_length = 64
|
|
|
|
|
a.image_height = 256
|
|
|
|
|
a.skip = (3, 1, 2)
|
|
|
|
|
self.assertEqual(a.alignment, 1)
|
|
|
|
|
self.assertEqual(a.row_length, 64)
|
|
|
|
|
self.assertEqual(a.image_height, 256)
|
|
|
|
|
self.assertEqual(a.skip, Vector3i(3, 1, 2))
|
|
|
|
|
|
|
|
|
|
class Image(unittest.TestCase):
|
|
|
|
|
def test_init_empty(self):
|
|
|
|
|
storage = PixelStorage()
|
|
|
|
|
storage.alignment = 1
|
|
|
|
|
a = Image2D(storage, PixelFormat.RGB8_UNORM)
|
|
|
|
|
self.assertEqual(a.storage.alignment, 1)
|
|
|
|
|
self.assertEqual(a.size, Vector2i())
|
|
|
|
|
self.assertEqual(a.format, PixelFormat.RGB8_UNORM)
|
|
|
|
|
|
|
|
|
|
b = Image2D(PixelFormat.R8I)
|
|
|
|
|
self.assertEqual(b.storage.alignment, 4)
|
|
|
|
|
self.assertEqual(b.size, Vector2i())
|
|
|
|
|
self.assertEqual(b.format, PixelFormat.R8I)
|
|
|
|
|
|
|
|
|
|
@unittest.skip("No way to create a non-empty Image at the moment")
|
|
|
|
|
def test_data_access(self):
|
|
|
|
|
# Tested in test_gl_gl.Framebuffer.test_read_image instead
|
|
|
|
|
a = Image2D(PixelFormat.R8I, Vector2i(3, 17)) # TODO
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
|
|
|
|
|
data = a.data
|
|
|
|
|
self.assertEqual(len(data), 3*17*1)
|
|
|
|
|
self.assertIs(data.owner, a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
|
|
|
|
|
|
|
|
|
|
del data
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
def test_data_access_empty(self):
|
|
|
|
|
a = Image2D(PixelFormat.R8I)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
|
|
|
|
|
data = a.data
|
|
|
|
|
self.assertEqual(len(data), 0)
|
|
|
|
|
self.assertIs(data.owner, None)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
@unittest.skip("No way to create a non-empty Image at the moment")
|
|
|
|
|
def test_pixels_access(self):
|
|
|
|
|
# Tested in test_gl_gl.Framebuffer.test_read_image instead
|
|
|
|
|
a = Image2D(PixelFormat.RG32UI, Vector2i(3, 17)) # TODO
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
|
|
|
|
|
pixels = a.pixels
|
|
|
|
|
self.assertEqual(pixels.size, (3, 17))
|
|
|
|
|
self.assertEqual(pixels.stride, (17*8, 8))
|
|
|
|
|
self.assertEqual(pixels.format, '2I')
|
|
|
|
|
self.assertIs(pixels.owner, a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
|
|
|
|
|
|
|
|
|
|
del pixels
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
def test_pixels_access_empty(self):
|
|
|
|
|
a = Image2D(PixelFormat.RGB8I)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
|
|
|
|
|
pixels = a.pixels
|
|
|
|
|
self.assertEqual(pixels.size, (0, 0))
|
|
|
|
|
self.assertEqual(pixels.stride, (0, 3))
|
|
|
|
|
self.assertEqual(pixels.format, '3b')
|
|
|
|
|
self.assertIs(pixels.owner, None)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
def test_pixels_access_unsupported_format(self):
|
|
|
|
|
a = Image2D(PixelFormat.DEPTH32F)
|
|
|
|
|
|
|
|
|
|
with self.assertRaisesRegex(NotImplementedError, "access to this pixel format is not implemented yet, sorry"):
|
|
|
|
|
a.pixels
|
|
|
|
|
|
|
|
|
|
class ImageView(unittest.TestCase):
|
|
|
|
|
def test_init(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = (b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = ImageView2D(PixelFormat.RGB8_UNORM, (2, 4), data)
|
|
|
|
|
self.assertEqual(a.storage, PixelStorage())
|
|
|
|
|
self.assertEqual(a.size, Vector2i(2, 4))
|
|
|
|
|
self.assertEqual(a.format, PixelFormat.RGB8_UNORM)
|
|
|
|
|
self.assertEqual(a.pixel_size, 3)
|
|
|
|
|
self.assertEqual(a.owner, data)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
del a
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount)
|
|
|
|
|
|
|
|
|
|
def test_init_storage(self):
|
|
|
|
|
# 2x2x2 RGB pixels
|
|
|
|
|
data = (b'rgbRGB'
|
|
|
|
|
b'abcABC'
|
|
|
|
|
b'defDEF'
|
|
|
|
|
b'ijkIJK')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
storage = PixelStorage()
|
|
|
|
|
storage.alignment = 2
|
|
|
|
|
a = ImageView3D(storage, PixelFormat.RGB8_UNORM, (2, 2, 2), data)
|
|
|
|
|
self.assertEqual(a.storage.alignment, 2)
|
|
|
|
|
self.assertEqual(a.size, Vector3i(2, 2, 2))
|
|
|
|
|
self.assertEqual(a.format, PixelFormat.RGB8_UNORM)
|
|
|
|
|
self.assertEqual(a.pixel_size, 3)
|
|
|
|
|
self.assertEqual(a.owner, data)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
del a
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount)
|
|
|
|
|
|
|
|
|
|
def test_init_empty(self):
|
|
|
|
|
a = MutableImageView1D(PixelFormat.RG16UI, 32)
|
|
|
|
|
self.assertEqual(a.storage.alignment, 4)
|
|
|
|
|
self.assertEqual(a.size, 32)
|
|
|
|
|
self.assertEqual(a.owner, None)
|
|
|
|
|
|
|
|
|
|
storage = PixelStorage()
|
|
|
|
|
storage.alignment = 2
|
|
|
|
|
b = ImageView2D(storage, PixelFormat.R32F, (8, 8))
|
|
|
|
|
self.assertEqual(b.storage.alignment, 2)
|
|
|
|
|
self.assertEqual(b.size, Vector2i(8, 8))
|
|
|
|
|
self.assertEqual(b.owner, None)
|
|
|
|
|
|
|
|
|
|
def test_init_mutable(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = bytearray(b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = MutableImageView2D(PixelFormat.RGB8_UNORM, (2, 4), data)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
# Back to immutable
|
|
|
|
|
b = ImageView2D(a)
|
|
|
|
|
self.assertEqual(b.size, Vector2i(2, 4))
|
|
|
|
|
self.assertEqual(b.format, PixelFormat.RGB8_UNORM)
|
|
|
|
|
self.assertEqual(b.pixel_size, 3)
|
|
|
|
|
self.assertEqual(len(b.data), 32)
|
|
|
|
|
self.assertIs(b.owner, data)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 2)
|
|
|
|
|
|
|
|
|
|
@unittest.skip("No way to create a non-empty Image at the moment")
|
|
|
|
|
def test_init_image(self):
|
|
|
|
|
# Tested in test_gl_gl.Framebuffer.test_read_image instead
|
|
|
|
|
a = Image2D(PixelFormat.R32F, Vector2i(3, 17)) # TODO
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
|
|
|
|
|
view = ImageView2D(a)
|
|
|
|
|
self.assertEqual(view.size, (3, 17))
|
|
|
|
|
self.assertIs(view.owner, a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
|
|
|
|
|
|
|
|
|
|
del view
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
mview = MutableImageView2D(a)
|
|
|
|
|
self.assertEqual(mview.size, (3, 17))
|
|
|
|
|
self.assertIs(mview.owner, a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
|
|
|
|
|
|
|
|
|
|
del mview
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
def test_init_image_empty(self):
|
|
|
|
|
a = Image2D(PixelFormat.R32F)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
|
|
|
|
|
view = ImageView2D(a)
|
|
|
|
|
self.assertEqual(view.size, (0, 0))
|
|
|
|
|
self.assertIs(view.owner, None)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
mview = MutableImageView2D(a)
|
|
|
|
|
self.assertEqual(mview.size, (0, 0))
|
|
|
|
|
self.assertIs(mview.owner, None)
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
|
|
|
|
|
def test_data_access(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = (b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = ImageView2D(PixelFormat.RGB8_UNORM, (2, 4), data)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
a_data = a.data
|
|
|
|
|
self.assertEqual(len(a_data), 32)
|
|
|
|
|
self.assertEqual(a_data[9], 'b')
|
|
|
|
|
self.assertEqual(a_data[20], 'E')
|
|
|
|
|
self.assertIs(a_data.owner, data)
|
|
|
|
|
# The data references the original data as an owner, not the view
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 2)
|
|
|
|
|
|
|
|
|
|
del a_data
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
def test_mutable_data_access(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = bytearray(b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = MutableImageView2D(PixelFormat.RGB8_UNORM, (2, 4), data)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
a_data = a.data
|
|
|
|
|
self.assertEqual(len(a_data), 32)
|
|
|
|
|
self.assertEqual(a_data[9], 'b')
|
|
|
|
|
self.assertEqual(a_data[20], 'E')
|
|
|
|
|
self.assertIs(a_data.owner, data)
|
|
|
|
|
# The data references the original data as an owner, not the view
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 2)
|
|
|
|
|
|
|
|
|
|
a_data[9] = '_'
|
|
|
|
|
a_data[20] = '_'
|
|
|
|
|
self.assertEqual(data, b'rgbRGB '
|
|
|
|
|
b'a_cABC '
|
|
|
|
|
b'defD_F '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
|
|
|
|
|
del a_data
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
def test_set_data(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = (b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = ImageView2D(PixelFormat.RGB8_UNORM, (2, 4), data)
|
|
|
|
|
self.assertIs(a.owner, data)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
data2 = (b'ijkIJK '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'rgbRGB ')
|
|
|
|
|
data2_refcount = sys.getrefcount(data2)
|
|
|
|
|
|
|
|
|
|
# Replacing the data should disown the original object and point to the
|
|
|
|
|
# new one
|
|
|
|
|
a.data = data2
|
|
|
|
|
self.assertEqual(bytes(a.data), (
|
|
|
|
|
b'ijkIJK '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'rgbRGB '))
|
|
|
|
|
self.assertIs(a.owner, data2)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data2), data2_refcount + 1)
|
|
|
|
|
|
|
|
|
|
def test_pixels_access(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = (b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = ImageView2D(PixelFormat.RGB8UI, (2, 4), data)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
pixels = a.pixels
|
|
|
|
|
self.assertEqual(pixels.size, (4, 2))
|
|
|
|
|
self.assertEqual(pixels.stride, (8, 3))
|
|
|
|
|
self.assertEqual(pixels.format, '3B')
|
|
|
|
|
self.assertEqual(pixels[1, 0].g, ord('b'))
|
|
|
|
|
self.assertEqual(pixels[2, 1].g, ord('E'))
|
|
|
|
|
self.assertIs(pixels.owner, data)
|
|
|
|
|
# The data references the original data as an owner, not the view
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 2)
|
|
|
|
|
|
|
|
|
|
del pixels
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
def test_mutable_pixels_access(self):
|
|
|
|
|
# 2x4 RGB pixels, padded for alignment
|
|
|
|
|
data = bytearray(b'rgbRGB '
|
|
|
|
|
b'abcABC '
|
|
|
|
|
b'defDEF '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
data_refcount = sys.getrefcount(data)
|
|
|
|
|
|
|
|
|
|
a = MutableImageView2D(PixelFormat.RGB8UI, (2, 4), data)
|
|
|
|
|
a_refcount = sys.getrefcount(a)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
pixels = a.pixels
|
|
|
|
|
self.assertEqual(pixels.size, (4, 2))
|
|
|
|
|
self.assertEqual(pixels.stride, (8, 3))
|
|
|
|
|
self.assertEqual(pixels.format, '3B')
|
|
|
|
|
self.assertEqual(pixels[1, 0].g, ord('b'))
|
|
|
|
|
self.assertEqual(pixels[2, 1].g, ord('E'))
|
|
|
|
|
self.assertIs(pixels.owner, data)
|
|
|
|
|
# The data references the original data as an owner, not the view
|
|
|
|
|
self.assertEqual(sys.getrefcount(a), a_refcount)
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 2)
|
|
|
|
|
|
|
|
|
|
pixels[1, 0] = Vector3(ord('a'), ord('_'), ord('c'))
|
|
|
|
|
pixels[2, 1] = Vector3(ord('D'), ord('_'), ord('F'))
|
|
|
|
|
self.assertEqual(data, b'rgbRGB '
|
|
|
|
|
b'a_cABC '
|
|
|
|
|
b'defD_F '
|
|
|
|
|
b'ijkIJK ')
|
|
|
|
|
|
|
|
|
|
del pixels
|
|
|
|
|
self.assertEqual(sys.getrefcount(data), data_refcount + 1)
|
|
|
|
|
|
|
|
|
|
def test_pixels_access_direct(self):
|
|
|
|
|
data = array.array('f', [1.0, 2.0, 3.0, 4.0])
|
|
|
|
|
a = MutableImageView2D(PixelFormat.RG32F, (2, 1), data)
|
|
|
|
|
|
|
|
|
|
pixels = a.pixels
|
|
|
|
|
self.assertEqual(pixels.size, (1, 2))
|
|
|
|
|
self.assertEqual(pixels.stride, (16, 8))
|
|
|
|
|
self.assertEqual(pixels.format, '2f')
|
|
|
|
|
self.assertEqual(pixels[0, 1], Vector2(3.0, 4.0))
|
|
|
|
|
|
|
|
|
|
pixels[0, 1] *= 0.25
|
|
|
|
|
self.assertEqual(pixels[0, 1], Vector2(0.75, 1.0))
|
|
|
|
|
|
|
|
|
|
def test_pixels_access_cast(self):
|
|
|
|
|
# 0.0, 1.0, 2.0, 3.0; values taken from Magnum's HalfTest.cpp
|
|
|
|
|
# TODO clean up once array supports half-floats (ugh)
|
|
|
|
|
data = array.array('H', [0x0000, 0x3c00, 0x4000, 0x4200])
|
|
|
|
|
a = MutableImageView2D(PixelFormat.RG16F, (2, 1), data)
|
|
|
|
|
|
|
|
|
|
pixels = a.pixels
|
|
|
|
|
self.assertEqual(pixels.size, (1, 2))
|
|
|
|
|
self.assertEqual(pixels.stride, (8, 4))
|
|
|
|
|
self.assertEqual(pixels.format, '2e')
|
|
|
|
|
self.assertEqual(pixels[0, 1], Vector2(2.0, 3.0))
|
|
|
|
|
|
|
|
|
|
pixels[0, 1] *= 0.25
|
|
|
|
|
self.assertEqual(pixels[0, 1], Vector2(0.5, 0.75))
|
|
|
|
|
|
|
|
|
|
def test_pixels_access_srgb(self):
|
|
|
|
|
# Values taken from Magnum's ColorTest::fromIntegralSrgb()
|
|
|
|
|
data1 = array.array('B', [0xf3, 0x2a, 0x80, 0x23, 0xff, 0x00, 0xff, 0x00])
|
|
|
|
|
data2 = array.array('B', [0xf3, 0x2a, 0x80, 0xff, 0x00, 0xff, 0, 0])
|
|
|
|
|
data3 = array.array('B', [0xf3, 0x2a, 0xff, 0x00, 0, 0, 0, 0])
|
|
|
|
|
data4 = array.array('B', [0xf3, 0xff, 0, 0, 0, 0, 0, 0])
|
|
|
|
|
rgba = MutableImageView2D(PixelFormat.RGBA8_SRGB, (2, 1), data1)
|
|
|
|
|
rgb = MutableImageView2D(PixelFormat.RGB8_SRGB, (2, 1), data2)
|
|
|
|
|
rg = MutableImageView2D(PixelFormat.RG8_SRGB, (2, 1), data3)
|
|
|
|
|
r = MutableImageView2D(PixelFormat.R8_SRGB, (2, 1), data4)
|
|
|
|
|
|
|
|
|
|
rgba_pixels = rgba.pixels
|
|
|
|
|
rgb_pixels = rgb.pixels
|
|
|
|
|
rg_pixels = rg.pixels
|
|
|
|
|
r_pixels = r.pixels
|
|
|
|
|
self.assertEqual(rgba_pixels.format, '4B')
|
|
|
|
|
self.assertEqual(rgb_pixels.format, '3B')
|
|
|
|
|
self.assertEqual(rg_pixels.format, '2B')
|
|
|
|
|
self.assertEqual(r_pixels.format, 'B')
|
|
|
|
|
self.assertEqual(rgba_pixels[0, 0], Vector4(0.896269, 0.0231534, 0.215861, 0.137255))
|
|
|
|
|
self.assertEqual(rgb_pixels[0, 0], Vector3(0.896269, 0.0231534, 0.215861))
|
|
|
|
|
self.assertEqual(rg_pixels[0, 0], Vector2(0.896269, 0.0231534))
|
|
|
|
|
# Python compares floats with an unnecessary precision compared to
|
|
|
|
|
# Magnum's op== on vector types
|
|
|
|
|
self.assertEqual(r_pixels[0, 0], 0.8962693810462952)
|
|
|
|
|
self.assertEqual(rgba_pixels[0, 1], Vector4(1.0, 0.0, 1.0, 0.0))
|
|
|
|
|
self.assertEqual(rgb_pixels[0, 1], Vector3(1.0, 0.0, 1.0))
|
|
|
|
|
self.assertEqual(rg_pixels[0, 1], Vector2(1.0, 0.0))
|
|
|
|
|
self.assertEqual(r_pixels[0, 1], 1.0)
|
|
|
|
|
|
|
|
|
|
rgba_pixels[0, 0] *= 0.5
|
|
|
|
|
rgb_pixels[0, 0] *= 0.5
|
|
|
|
|
rg_pixels[0, 0] *= 0.5
|
|
|
|
|
r_pixels[0, 0] *= 0.5
|
|
|
|
|
self.assertEqual(rgba_pixels[0, 0], Vector4(0.450786, 0.0116122, 0.107023, 0.0705882))
|
|
|
|
|
self.assertEqual(rgb_pixels[0, 0], Vector3(0.450786, 0.0116122, 0.107023))
|
|
|
|
|
self.assertEqual(rg_pixels[0, 0], Vector2(0.450786, 0.0116122))
|
|
|
|
|
# Python compares floats with an unnecessary precision compared to
|
|
|
|
|
# Magnum's op== on vector types
|
|
|
|
|
self.assertEqual(r_pixels[0, 0], 0.4507858455181122)
|
|
|
|
|
|
|
|
|
|
def test_pixels_access_unsupported_format(self):
|
|
|
|
|
data = array.array('f', [1.0, 2.0, 3.0, 4.0])
|
|
|
|
|
a = ImageView2D(PixelFormat.DEPTH32F, (2, 2), data)
|
|
|
|
|
|
|
|
|
|
with self.assertRaisesRegex(NotImplementedError, "access to this pixel format is not implemented yet, sorry"):
|
|
|
|
|
a.pixels
|
|
|
|
|
|
|
|
|
|
class UtilityCopy(unittest.TestCase):
|
|
|
|
|
def test_1d(self):
|
|
|
|
|
a_data = array.array('f', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
|
|
|
|
|
a = ImageView1D(PixelFormat.RGB32F, 2, a_data)
|
|
|
|
|
|
|
|
|
|
b_data = array.array('f', [0.0]*6)
|
|
|
|
|
b = MutableImageView1D(PixelFormat.RGB32F, 2, b_data)
|
|
|
|
|
|
|
|
|
|
utility.copy(a.pixels, b.pixels)
|
|
|
|
|
self.assertEqual(list(b_data), [1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
|
|
|
|
|
|
|
|
|
|
def test_2d(self):
|
|
|
|
|
a_data = array.array('f', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0])
|
|
|
|
|
a = ImageView2D(PixelFormat.RG32F, (2, 2), a_data)
|
|
|
|
|
|
|
|
|
|
b_data = array.array('f', [0.0]*8)
|
|
|
|
|
b = MutableImageView2D(PixelFormat.RG32F, (2, 2), b_data)
|
|
|
|
|
|
|
|
|
|
utility.copy(a.pixels, b.pixels)
|
|
|
|
|
self.assertEqual(list(b_data), [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0])
|
|
|
|
|
|
|
|
|
|
def test_3d(self):
|
|
|
|
|
a_data = array.array('f', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
|
|
|
|
|
a = ImageView3D(PixelFormat.R32F, (3, 1, 3), a_data)
|
|
|
|
|
|
|
|
|
|
b_data = array.array('f', [0.0]*9)
|
|
|
|
|
b = MutableImageView3D(PixelFormat.R32F, (3, 1, 3), b_data)
|
|
|
|
|
|
|
|
|
|
utility.copy(a.pixels, b.pixels)
|
|
|
|
|
self.assertEqual(list(b_data), [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
|
|
|
|
|
|
|
|
|
|
def test_size_mismatch(self):
|
|
|
|
|
a_data = array.array('f', [0.0]*12)
|
|
|
|
|
a = ImageView2D(PixelFormat.RG32F, (3, 2), a_data)
|
|
|
|
|
|
|
|
|
|
b_data = array.array('f', [0.0]*12)
|
|
|
|
|
b = MutableImageView2D(PixelFormat.RG32F, (2, 3), b_data)
|
|
|
|
|
|
|
|
|
|
with self.assertRaisesRegex(AssertionError, "sizes don't match"):
|
|
|
|
|
utility.copy(a.pixels, b.pixels)
|
|
|
|
|
|
|
|
|
|
def test_itemsize_mismatch(self):
|
|
|
|
|
a_data = array.array('f', [0.0]*12)
|
|
|
|
|
a = ImageView2D(PixelFormat.RG32F, (3, 2), a_data)
|
|
|
|
|
|
|
|
|
|
b_data = array.array('f', [0.0]*18)
|
|
|
|
|
b = MutableImageView2D(PixelFormat.RGB32F, (3, 2), b_data)
|
|
|
|
|
|
|
|
|
|
with self.assertRaisesRegex(AssertionError, "type sizes don't match"):
|
|
|
|
|
utility.copy(a.pixels, b.pixels)
|
|
|
|
|
|
|
|
|
|
def test_format_mismatch(self):
|
|
|
|
|
a_data = array.array('f', [0.0]*12)
|
|
|
|
|
a = ImageView2D(PixelFormat.RG32F, (3, 2), a_data)
|
|
|
|
|
|
|
|
|
|
b_data = array.array('I', [0]*18)
|
|
|
|
|
b = MutableImageView2D(PixelFormat.RG32UI, (3, 2), b_data)
|
|
|
|
|
|
|
|
|
|
with self.assertRaisesRegex(AssertionError, "types don't match"):
|
|
|
|
|
utility.copy(a.pixels, b.pixels)
|