forked from pool/python-imagecodecs
Markéta Machová
3ac346bdcc
- Add patches for the compatibility with libavif 1.0.0: * libavif.patch * quantize.patch * avif.patch * tests.patch * integrate.patch OBS-URL: https://build.opensuse.org/request/show/1111056 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-imagecodecs?expand=0&rev=25
200 lines
6.9 KiB
Diff
200 lines
6.9 KiB
Diff
From 0030b7b74fc17ceb356d1f67633ba1734108dac9 Mon Sep 17 00:00:00 2001
|
|
From: Christoph Gohlke <cgohlke@cgohlke.com>
|
|
Date: Sun, 3 Sep 2023 09:36:27 -0700
|
|
Subject: [PATCH] Update tests/test_imagecodecs.py
|
|
|
|
---
|
|
tests/test_imagecodecs.py | 131 ++++++++++++++++++++++++++++++--------
|
|
1 file changed, 106 insertions(+), 25 deletions(-)
|
|
|
|
Index: imagecodecs-2023.3.16/tests/test_imagecodecs.py
|
|
===================================================================
|
|
--- imagecodecs-2023.3.16.orig/tests/test_imagecodecs.py
|
|
+++ imagecodecs-2023.3.16/tests/test_imagecodecs.py
|
|
@@ -79,6 +79,7 @@ except ImportError as exc:
|
|
|
|
try:
|
|
import zarr
|
|
+
|
|
from imagecodecs import numcodecs
|
|
except ImportError:
|
|
SKIP_NUMCODECS = True
|
|
@@ -172,7 +173,7 @@ def test_dependency_exist(name):
|
|
if SKIP_NUMCODECS and IS_PYPY:
|
|
mayfail = True
|
|
elif name in ('blosc', 'blosc2', 'snappy'):
|
|
- if IS_PYPY or sys.version_info[1] >= 10:
|
|
+ if IS_PYPY or not IS_CG:
|
|
mayfail = True
|
|
try:
|
|
importlib.import_module(name)
|
|
@@ -194,7 +195,7 @@ def test_version_functions():
|
|
def test_stubs():
|
|
"""Test stub attributes for non-existing extension."""
|
|
with pytest.raises(AttributeError):
|
|
- imagecodecs._STUB
|
|
+ assert imagecodecs._STUB
|
|
_add_codec('_stub')
|
|
assert not imagecodecs._STUB # typing: ignore
|
|
assert not imagecodecs._STUB.available
|
|
@@ -873,6 +874,74 @@ def test_lzw_msb():
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
+ not imagecodecs.QUANTIZE.available, reason='QUANTIZE missing'
|
|
+)
|
|
+@pytest.mark.parametrize(
|
|
+ 'mode', ['bitgroom', 'granularbr', 'bitround', 'scale']
|
|
+)
|
|
+@pytest.mark.parametrize('dtype', ['f4', 'f8'])
|
|
+def test_quantize_roundtrip(mode, dtype):
|
|
+ """Test quantize roundtrips."""
|
|
+ nsd = 12
|
|
+ atol = 0.006
|
|
+ if mode == 'bitgroom':
|
|
+ nsd = (nsd - 1) // 3 # bits = math.ceil(nsd * 3.32) + 1
|
|
+ if dtype == 'f4':
|
|
+ nsd //= 2
|
|
+ atol = 0.5
|
|
+ data = numpy.linspace(-2.1, 31.4, 51, dtype=dtype).reshape((3, 17))
|
|
+ encoded = imagecodecs.quantize_encode(data, mode, nsd)
|
|
+ out = data.copy()
|
|
+ imagecodecs.quantize_encode(data, mode, nsd, out=out)
|
|
+ assert_array_equal(out, encoded)
|
|
+ assert_allclose(data, encoded, atol=atol)
|
|
+
|
|
+
|
|
+@pytest.mark.skipif(
|
|
+ SKIP_NUMCODECS or not imagecodecs.QUANTIZE.available,
|
|
+ reason='QUANTIZE missing',
|
|
+)
|
|
+@pytest.mark.parametrize('nsd', [1, 4])
|
|
+@pytest.mark.parametrize('dtype', ['f4', 'f8'])
|
|
+def test_quantize_bitround(dtype, nsd):
|
|
+ """Test BitRound quantize against numcodecs."""
|
|
+ from numcodecs import BitRound
|
|
+
|
|
+ from imagecodecs.numcodecs import Quantize
|
|
+
|
|
+ # TODO: 31.4 fails
|
|
+ data = numpy.linspace(-2.1, 31.5, 51, dtype=dtype).reshape((3, 17))
|
|
+ encoded = Quantize(
|
|
+ mode=imagecodecs.QUANTIZE.MODE.BITROUND,
|
|
+ nsd=nsd,
|
|
+ ).encode(data)
|
|
+ nc = BitRound(keepbits=nsd)
|
|
+ encoded2 = nc.decode(nc.encode(data))
|
|
+ assert_array_equal(encoded, encoded2)
|
|
+
|
|
+
|
|
+@pytest.mark.skipif(
|
|
+ SKIP_NUMCODECS or not imagecodecs.QUANTIZE.available,
|
|
+ reason='QUANTIZE missing',
|
|
+)
|
|
+@pytest.mark.parametrize('nsd', [1, 4])
|
|
+@pytest.mark.parametrize('dtype', ['f4', 'f8'])
|
|
+def test_quantize_scale(dtype, nsd):
|
|
+ """Test Scale quantize against numcodecs."""
|
|
+ from numcodecs import Quantize as Quantize2
|
|
+
|
|
+ from imagecodecs.numcodecs import Quantize
|
|
+
|
|
+ data = numpy.linspace(-2.1, 31.4, 51, dtype=dtype).reshape((3, 17))
|
|
+ encoded = Quantize(
|
|
+ mode=imagecodecs.QUANTIZE.MODE.SCALE,
|
|
+ nsd=nsd,
|
|
+ ).encode(data)
|
|
+ encoded2 = Quantize2(digits=nsd, dtype=dtype).encode(data)
|
|
+ assert_array_equal(encoded, encoded2)
|
|
+
|
|
+
|
|
+@pytest.mark.skipif(
|
|
not (imagecodecs.LZW.available and imagecodecs.DELTA.available),
|
|
reason='skip',
|
|
)
|
|
@@ -1818,7 +1896,7 @@ def test_rgbe_roundtrip():
|
|
@pytest.mark.skipif(not imagecodecs.CMS.available, reason='cms missing')
|
|
def test_cms_profile():
|
|
"""Test cms_profile function."""
|
|
- from imagecodecs import cms_profile, cms_profile_validate, CmsError
|
|
+ from imagecodecs import CmsError, cms_profile, cms_profile_validate
|
|
|
|
with pytest.raises(CmsError):
|
|
cms_profile_validate(b'12345')
|
|
@@ -1934,7 +2012,7 @@ def test_cms_profile():
|
|
@pytest.mark.skipif(not imagecodecs.CMS.available, reason='cms missing')
|
|
def test_cms_output_shape():
|
|
"""Test _cms_output_shape function."""
|
|
- from imagecodecs._cms import _cms_output_shape, _cms_format
|
|
+ from imagecodecs._cms import _cms_format, _cms_output_shape
|
|
|
|
for args, colorspace, planar, expected in (
|
|
(((6, 7), 'u1', 'gray'), 'gray', 0, (6, 7)),
|
|
@@ -2086,7 +2164,7 @@ def test_cms_format():
|
|
@pytest.mark.parametrize('out', [None, True])
|
|
def test_cms_identity_transforms(dtype, outdtype, planar, outplanar, out):
|
|
"""Test CMS identity transforms."""
|
|
- from imagecodecs import cms_transform, cms_profile
|
|
+ from imagecodecs import cms_profile, cms_transform
|
|
|
|
shape = (3, 256, 253) if planar else (256, 253, 3)
|
|
dtype = numpy.dtype(dtype)
|
|
@@ -2480,7 +2558,10 @@ def test_avif_strict_disabled():
|
|
|
|
|
|
@pytest.mark.skipif(not IS_CG, reason='avif missing')
|
|
-@pytest.mark.parametrize('codec', ['auto', 'aom', 'rav1e', 'svt']) # 'libgav1'
|
|
+@pytest.mark.parametrize(
|
|
+ 'codec',
|
|
+ ['auto', 'aom', 'rav1e', 'svt'], # 'libgav1', 'avm'
|
|
+)
|
|
def test_avif_encoder(codec):
|
|
"""Test various AVIF encoder codecs."""
|
|
data = numpy.load(datafiles('rgb.u1.npy'))
|
|
@@ -2490,9 +2571,9 @@ def test_avif_encoder(codec):
|
|
else:
|
|
pixelformat = None
|
|
encoded = imagecodecs.avif_encode(
|
|
- data, level=6, codec=codec, pixelformat=pixelformat
|
|
+ data, level=95, codec=codec, pixelformat=pixelformat, numthreads=2
|
|
)
|
|
- decoded = imagecodecs.avif_decode(encoded)
|
|
+ decoded = imagecodecs.avif_decode(encoded, numthreads=2)
|
|
assert_allclose(decoded, data, atol=5, rtol=0)
|
|
|
|
|
|
@@ -3353,6 +3434,8 @@ def test_image_roundtrips(codec, dtype,
|
|
data, bitspersample=12, *args, **kwargs
|
|
)
|
|
|
|
+ if level:
|
|
+ level += 95
|
|
atol = 10
|
|
elif codec == 'heif':
|
|
if not imagecodecs.HEIF.available:
|
|
@@ -3431,13 +3514,8 @@ def test_image_roundtrips(codec, dtype,
|
|
if level < 100:
|
|
atol *= 4
|
|
assert_allclose(data, decoded, atol=atol)
|
|
- elif codec == 'avif' and level == 5:
|
|
- if dtype.itemsize > 1:
|
|
- # TODO: bug in libavif?
|
|
- pytest.xfail('why does this fail?')
|
|
- atol = 32
|
|
- else:
|
|
- atol = 6
|
|
+ elif codec == 'avif' and level == 94:
|
|
+ atol = 38 if dtype.itemsize > 1 else 6
|
|
assert_allclose(data, decoded, atol=atol)
|
|
else:
|
|
assert_array_equal(data, decoded, verbose=True)
|
|
@@ -3847,7 +3926,7 @@ def test_numcodecs(codec, photometric):
|
|
if photometric != 'rgb':
|
|
pytest.xfail('AVIF does not support grayscale')
|
|
compressor = numcodecs.Avif(
|
|
- level=0,
|
|
+ level=100,
|
|
speed=None,
|
|
tilelog2=None,
|
|
bitspersample=None,
|