Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Glymur for openSUSE:Factory checked in at 2021-02-19 23:43:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Glymur (Old) and /work/SRC/openSUSE:Factory/.python-Glymur.new.28504 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Glymur" Fri Feb 19 23:43:16 2021 rev:7 rq:871407 version:0.9.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Glymur/python-Glymur.changes 2020-07-15 11:32:07.510025568 +0200 +++ /work/SRC/openSUSE:Factory/.python-Glymur.new.28504/python-Glymur.changes 2021-02-19 23:44:53.407341322 +0100 @@ -1,0 +2,17 @@ +Thu Feb 11 00:02:44 UTC 2021 - Benjamin Greiner <c...@bnavigator.de> + +- NEP 29: NumPy dropped Python 3.6 -- skip python36 build in TW +- Make importlib_resources conditional for Python < 3.7 (SLE/Leap) + +------------------------------------------------------------------- +Sat Jan 23 12:18:53 UTC 2021 - Benjamin Greiner <c...@bnavigator.de> + +- Update to 0.9.3 + * Qualify on Python 3.9 + * Qualify on OpenJPEG 2.4.0 + * Add support for multithreaded writes. +- Always require importlib_resources for tests: the new python36 + flavor on TW needs it, the python38 flavor is okay with it being + installed. + +------------------------------------------------------------------- Old: ---- Glymur-0.9.2.tar.gz New: ---- Glymur-0.9.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Glymur.spec ++++++ --- /var/tmp/diff_new_pack.QNClqt/_old 2021-02-19 23:44:53.995341899 +0100 +++ /var/tmp/diff_new_pack.QNClqt/_new 2021-02-19 23:44:53.999341903 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-Glymur # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,8 +18,10 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 +# NEP 29: NumPy dropped Python 3.6 +%define skip_python36 1 Name: python-Glymur -Version: 0.9.2 +Version: 0.9.3 Release: 0 Summary: Tools for accessing JPEG2000 files License: MIT @@ -36,13 +38,12 @@ Recommends: python-lxml BuildArch: noarch # SECTION test requirements +# (importlib_resources for Leap's Python 3.6) +BuildRequires: %{python_module importlib_resources if %python-base < 3.7} BuildRequires: %{python_module lxml} BuildRequires: %{python_module numpy >= 1.7.1} BuildRequires: %{python_module pytest} BuildRequires: %{python_module scikit-image} -%if 0%{?suse_version} <= 1500 -BuildRequires: %{python_module importlib_resources} -%endif # /SECTION %python_subpackages @@ -57,10 +58,11 @@ %install %python_install -# don't install tests -rm -rf %{buildroot}%{python_sitelib}/tests %python_clone -a %{buildroot}%{_bindir}/jp2dump -%python_expand %fdupes %{buildroot}%{$python_sitelib} +%{python_expand # don't install tests +rm -rf %{buildroot}%{$python_sitelib}/tests +%fdupes %{buildroot}%{$python_sitelib} +} %check %pytest @@ -76,6 +78,6 @@ %license LICENSE.txt %python_alternative %{_bindir}/jp2dump %{python_sitelib}/glymur* -%{python_sitelib}/Glymur* +%{python_sitelib}/Glymur-%{version}*-info %changelog ++++++ Glymur-0.9.2.tar.gz -> Glymur-0.9.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/.travis.yml new/glymur-0.9.3/.travis.yml --- old/glymur-0.9.2/.travis.yml 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/.travis.yml 2020-12-31 22:02:06.000000000 +0100 @@ -2,21 +2,27 @@ matrix: fast_finish: true include: - - python: 3.6 - env: - - JOB="3.6 No OPENJPEG" ENV_FILE="ci/travis-36-no-opj.yaml" - - python: 3.6 - env: - - JOB="3.6" ENV_FILE="ci/travis-36.yaml" - - python: 3.7 - env: - - JOB="3.7" ENV_FILE="ci/travis-37.yaml" - - python: 3.7 - env: - - JOB="3.7" ENV_FILE="ci/travis-37-no-gdal.yaml" - - python: 3.8 - env: - - JOB="3.8" ENV_FILE="ci/travis-38.yaml" + - python: 3.9-dev + env: + - JOB="3.9" ENV_FILE="ci/travis-39.yaml" + - python: 3.9-dev + env: + - JOB="3.9 opj 2.4" ENV_FILE="ci/travis-39-opj2p4.yaml" + - python: 3.8 + env: + - JOB="3.8" ENV_FILE="ci/travis-38.yaml" + - python: 3.7 + env: + - JOB="3.7" ENV_FILE="ci/travis-37.yaml" + - python: 3.7 + env: + - JOB="3.7" ENV_FILE="ci/travis-37-no-gdal.yaml" + - python: 3.6 + env: + - JOB="3.6 No OPENJPEG" ENV_FILE="ci/travis-36-no-opj.yaml" + - python: 3.6 + env: + - JOB="3.6" ENV_FILE="ci/travis-36.yaml" before_install: - echo "before_install" - sudo apt-get update diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/ci/doc.yml new/glymur-0.9.3/ci/doc.yml --- old/glymur-0.9.2/ci/doc.yml 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/ci/doc.yml 2020-12-31 22:02:06.000000000 +0100 @@ -5,5 +5,3 @@ - python=3.7 - numpydoc>=0.8 - sphinx_rtd_theme>=0.4.2 - - mock>=2.0.0 - - contextlib2>=0.5.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/ci/travis-38.yaml new/glymur-0.9.3/ci/travis-38.yaml --- old/glymur-0.9.2/ci/travis-38.yaml 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/ci/travis-38.yaml 2020-12-31 22:02:06.000000000 +0100 @@ -1,6 +1,6 @@ name: glymur channels: - - conda-forge + - defaults dependencies: - python=3.8.* - gdal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/ci/travis-39-opj2p4.yaml new/glymur-0.9.3/ci/travis-39-opj2p4.yaml --- old/glymur-0.9.2/ci/travis-39-opj2p4.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/glymur-0.9.3/ci/travis-39-opj2p4.yaml 2020-12-31 22:02:06.000000000 +0100 @@ -0,0 +1,8 @@ +name: glymur +channels: + - conda-forge +dependencies: + - python=3.9.* + - lxml + - numpy + - openjpeg >= 2.4.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/ci/travis-39.yaml new/glymur-0.9.3/ci/travis-39.yaml --- old/glymur-0.9.2/ci/travis-39.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/glymur-0.9.3/ci/travis-39.yaml 2020-12-31 22:02:06.000000000 +0100 @@ -0,0 +1,10 @@ +name: glymur +channels: + - conda-forge +dependencies: + - python=3.9.* + - gdal + - lxml + - numpy + - openjpeg + - scikit-image diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/docs/source/conf.py new/glymur-0.9.3/docs/source/conf.py --- old/glymur-0.9.2/docs/source/conf.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/docs/source/conf.py 2020-12-31 22:02:06.000000000 +0100 @@ -78,7 +78,7 @@ # The short X.Y version. version = '0.9' # The full version, including alpha/beta/rc tags. -release = '0.9.2' +release = '0.9.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/docs/source/how_do_i.rst new/glymur-0.9.3/docs/source/how_do_i.rst --- old/glymur-0.9.2/docs/source/how_do_i.rst 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/docs/source/how_do_i.rst 2020-12-31 22:02:06.000000000 +0100 @@ -57,6 +57,30 @@ >>> jp2[:] = data +********************************************** +... write images using multithreaded encoding? +********************************************** +If you have glymur 0.9.2 or higher +and OpenJPEG 2.4.0 or higher, +you can make use of OpenJPEG's thread support to speed-up read operations. +With a puny 2015 macbook, just two cores, and a 5824x10368x3 image, we get:: + + >>> import time, numpy as np, glymur + >>> data = glymur.Jp2k(glymur.data.nemo())[:] + >>> data = np.tile(data, (4, 4, 1)) + >>> t0 = time.time() + >>> glymur.Jp2k('1thread.jp2', data) + >>> t1 = time.time() + >>> print(f'1 thread: {(t1 - t0):.3} seconds') + 12.0 seconds + >>> t0 = time.time() + >>> glymur.set_option('lib.num_threads', 2) + >>> glymur.Jp2k('2threads.jp2', data) + >>> t1 = time.time() + >>> print(f'2 threads: {(t1 - t0):.3} seconds') + 7.24 seconds + + ************************************************************************ ... write images with different compression ratios for different layers? ************************************************************************ @@ -83,13 +107,13 @@ the layer is lossless. However, the OpenJPEG library will reorder the layers to make the first layer lossless, not the last. :: - >>> import skimage.data, skimage.measure, glymur + >>> import skimage.data, skimage.metrics, glymur >>> truth = skimage.data.camera() >>> jp2 = glymur.Jp2k('myfile.jp2', data=truth, psnr=[30, 40, 50, 0]) >>> psnr = [] >>> for layer in range(4): ... jp2.layer = layer - ... psnr.append(skimage.measure.compare_psnr(truth, jp2[:])) + ... psnr.append(skimage.metrics.peak_signal_noise_ratio(truth, jp2[:])) >>> print(psnr) [inf, 29.028560403833303, 39.206919416670402, 47.593129828702246] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/docs/source/introduction.rst new/glymur-0.9.3/docs/source/introduction.rst --- old/glymur-0.9.2/docs/source/introduction.rst 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/docs/source/introduction.rst 2020-12-31 22:02:06.000000000 +0100 @@ -15,7 +15,7 @@ fall back upon the standard library's **ElementTree** if **lxml** is not available. -The current version of glymur works on Python versions 3.6, 3.7, and 3.8. +The current version of glymur works on Python versions 3.6, 3.7, 3.8, and 3.9. For more information about OpenJPEG, please consult http://www.openjpeg.org. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/docs/source/whatsnew/0.9.rst new/glymur-0.9.3/docs/source/whatsnew/0.9.rst --- old/glymur-0.9.2/docs/source/whatsnew/0.9.rst 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/docs/source/whatsnew/0.9.rst 2020-12-31 22:02:06.000000000 +0100 @@ -3,6 +3,14 @@ ##################### **************** +Changes in 0.9.3 +**************** + + * Qualify on Python 3.9 + * Qualify on OpenJPEG 2.4.0 + * Add support for multithreaded writes. + +**************** Changes in 0.9.2 **************** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/glymur/config.py new/glymur-0.9.3/glymur/config.py --- old/glymur-0.9.2/glymur/config.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/glymur/config.py 2020-12-31 22:02:06.000000000 +0100 @@ -7,7 +7,6 @@ import os import pathlib import platform -import sys import warnings @@ -42,11 +41,11 @@ Parameters ---------- libname : str - Short name for library (openjp2). + short name for library (openjp2) Returns ------- - Path to openjp2 library. + path to openjp2 library or None if openjp2 library not found """ # A location specified by the glymur configuration file has precedence. @@ -54,45 +53,19 @@ if path is not None: return path - # No joy on configuration file. - # Are we using Anaconda? - if ( - 'Anaconda' in sys.version - or 'Continuum Analytics, Inc.' in sys.version - or 'packaged by conda-forge' in sys.version - ): - # If Anaconda, then openjpeg may have been installed via conda. - if platform.system() in ['Linux', 'Darwin']: - suffix = '.so' if platform.system() == 'Linux' else '.dylib' - basedir = pathlib.Path(sys.executable).parents[1] - path = basedir / 'lib' / ('lib' + libname + suffix) - elif platform.system() == 'Windows': - basedir = pathlib.Path(sys.executable).parents[0] - path = basedir / 'Library' / 'bin' / (libname + '.dll') + # No joy on config file. Cygwin? Cygwin is a bit of an odd case. + if platform.system().startswith('CYGWIN'): + g = pathlib.Path('/usr/bin').glob('cygopenjp2*.dll') + try: + path = list(g)[0] + except IndexError: + # openjpeg possibly not installed + pass + else: + if path.exists(): + return path - return path - - # No joy on config file or Anaconda. - # MacPorts? - path = pathlib.Path('/opt/local/lib/libopenjp2.dylib') - if platform.system() == 'Darwin' and path.exists(): - return path - - # No joy on config file or Anaconda or macports. - # Cygwin? - g = pathlib.Path('/usr/bin').glob('cygopenjp2*.dll') - try: - path = list(g)[0] - except IndexError: - # If the generator is None... probably not on cygwin. - # Try something else. - pass - else: - if platform.system().startswith('CYGWIN') and path.exists(): - return path - - # No joy on config file, not Anaconda or MacPorts or Cygwin. - # Can ctypes find it anyway? + # No joy on config file and not Cygwin. Can ctypes find it anyway? path = find_library(libname) if path is not None: return pathlib.Path(path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/glymur/jp2k.py new/glymur-0.9.3/glymur/jp2k.py --- old/glymur-0.9.2/glymur/jp2k.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/glymur/jp2k.py 2020-12-31 22:02:06.000000000 +0100 @@ -750,6 +750,17 @@ strm = opj2.stream_create_default_file_stream(self.filename, False) + num_threads = get_option('lib.num_threads') + if version.openjpeg_version >= '2.4.0': + opj2.codec_set_threads(codec, num_threads) + elif num_threads > 1: + msg = ( + f'Threaded encoding is not supported in library versions ' + f'prior to 2.4.0. Your version is ' + f'{version.openjpeg_version}.' + ) + warnings.warn(msg, UserWarning) + stack.callback(opj2.stream_destroy, strm) opj2.start_compress(codec, image, strm) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/glymur/lib/openjp2.py new/glymur-0.9.3/glymur/lib/openjp2.py --- old/glymur-0.9.2/glymur/lib/openjp2.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/glymur/lib/openjp2.py 2020-12-31 22:02:06.000000000 +0100 @@ -1341,7 +1341,7 @@ OPENJP2.opj_stream_destroy(stream) -def write_tile(codec, tile_index, data, data_size, stream): +def write_tile(codec, tile_index, data, *pargs): """Wraps openjp2 library function opj_write_tile. Write a tile into an image. @@ -1354,8 +1354,8 @@ The index of the tile to write, zero-indexing assumed data : array Image data arranged in usual C-order - data_size : int - Size of a tile in bytes + data_size : int, optional + Size of a tile in bytes. If not provided, it will be inferred. stream : STREAM_TYPE_P The stream to write data to @@ -1364,6 +1364,14 @@ RuntimeError If the OpenJPEG library routine opj_write_tile fails. """ + if len(pargs) == 2: + # old signature + data_size, stream = pargs + else: + # new signature + data_size = data.nbytes + stream = pargs[0] + OPENJP2.opj_write_tile.argtypes = [CODEC_TYPE, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint8), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/glymur/version.py new/glymur-0.9.3/glymur/version.py --- old/glymur-0.9.2/glymur/version.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/glymur/version.py 2020-12-31 22:02:06.000000000 +0100 @@ -20,7 +20,7 @@ # Do not change the format of this next line! Doing so risks breaking # setup.py -version = "0.9.2" +version = "0.9.3" _sv = LooseVersion(version) version_tuple = _sv.version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/setup.py new/glymur-0.9.3/setup.py --- old/glymur-0.9.2/setup.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/setup.py 2020-12-31 22:02:06.000000000 +0100 @@ -27,6 +27,7 @@ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "License :: OSI Approved :: MIT License", "Development Status :: 5 - Production/Stable", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/tests/test_config.py new/glymur-0.9.3/tests/test_config.py --- old/glymur-0.9.2/tests/test_config.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/tests/test_config.py 2020-12-31 22:02:06.000000000 +0100 @@ -3,11 +3,10 @@ """ # Standard library imports ... import contextlib -import imp +import importlib import os import pathlib import platform -import sys import unittest from unittest.mock import patch import warnings @@ -59,62 +58,9 @@ """ super(TestSuitePathToLibrary, self).tearDown() - imp.reload(glymur) - imp.reload(glymur.lib.openjp2) + importlib.reload(glymur) + importlib.reload(glymur.lib.openjp2) - @patch('glymur.config.platform.system') - @patch('glymur.config.sys.version', 'Anaconda') - @patch('glymur.config.sys.executable', '/opt/anaconda/bin/python') - def test_anaconda_on_mac(self, mock_platform_system): - """ - SCENARIO: the platform is Anaconda on mac. - - EXPECTED RESULT: the path of the openjp2 library is under the anaconda - root. - """ - mock_platform_system.return_value = 'Darwin' - - actual = glymur.config._determine_full_path('openjp2') - expected = pathlib.Path('/opt/anaconda/lib/libopenjp2.dylib') - - self.assertEqual(actual, expected) - - @unittest.skipIf(platform.system() == 'Windows', 'nonsensical on windows') - @patch('glymur.config.platform.system') - @patch('glymur.config.sys.version', 'Anaconda') - @patch('glymur.config.sys.executable', '/usr/bin/python') - def test_windows_path(self, mock_platform_system): - """ - SCENARIO: the platform is Anaconda on windows, even though we are not - actually running on windows. - - EXPECTED RESULT: the path of the openjp2 library is an Anaconda DLL - """ - mock_platform_system.return_value = 'Windows' - - actual = glymur.config._determine_full_path('openjp2') - expected = pathlib.Path('/usr/bin/Library/bin/openjp2.dll') - - self.assertEqual(actual, expected) - - @patch('pathlib.Path.exists') - @patch('glymur.config.sys.version', 'not anaconda') - @patch('glymur.config.platform.system') - def test_macports(self, mock_platform_system, mock_path_exists): - """ - SCENARIO: the platform is MacPorts. - - EXPECTED RESULT: the path of the openjp2 library is in /opt/local - """ - mock_platform_system.return_value = 'Darwin' - mock_path_exists.return_value = True - - actual = glymur.config._determine_full_path('openjp2') - expected = pathlib.Path('/opt/local/lib/libopenjp2.dylib') - - self.assertEqual(actual, expected) - - @patch('glymur.config.sys.version', 'not anaconda') @patch('glymur.config.find_library') @patch('glymur.config.platform.system') def test_via_ctypes(self, mock_platform_system, mock_find_library): @@ -142,7 +88,6 @@ problem in CI environments, just development environments. """ - @patch('glymur.config.sys.version', 'not anaconda') @patch('glymur.config.find_library') @patch('glymur.config.platform.system') def test_not_via_ctypes(self, @@ -243,8 +188,8 @@ """ super(TestSuiteConfigFile, self).tearDown() - imp.reload(glymur) - imp.reload(glymur.lib.openjp2) + importlib.reload(glymur) + importlib.reload(glymur.lib.openjp2) def test_config_file_via_environ(self): """ @@ -263,7 +208,7 @@ new = {'XDG_CONFIG_HOME': str(self.config_root)} with patch.dict('os.environ', new): - imp.reload(glymur.lib.openjp2) + importlib.reload(glymur.lib.openjp2) Jp2k(self.jp2file) def test_config_file_without_library_section(self): @@ -279,7 +224,7 @@ new = {'XDG_CONFIG_HOME': str(self.config_root)} with patch.dict('os.environ', new): - imp.reload(glymur.lib.openjp2) + importlib.reload(glymur.lib.openjp2) # It's enough that we did not error out self.assertTrue(True) @@ -294,37 +239,26 @@ new = {'XDG_CONFIG_HOME': str(self.config_root)} with patch.dict('os.environ', new): - imp.reload(glymur.lib.openjp2) + importlib.reload(glymur.lib.openjp2) self.assertIsNotNone(glymur.lib.openjp2.OPENJP2) - @unittest.skipIf(platform.system() == 'Windows', - 'Symlinks require elevated privs on Windows, GH#505') - @unittest.skipIf(platform.system() == 'Linux' and sys.prefix == '/usr', - 'Difficult to run on Linux unless Anaconda, GH#496') def test_config_file_in_current_directory(self): """ SCENARIO: A configuration file exists in the current directory. - EXPECTED RESULT: openjp2 library is loaded normally. + EXPECTED RESULT: the path to the specified openjp2 library is returned """ - existing_library = glymur.lib.openjp2.OPENJP2._name - - # Make a soft link from a fake library directory to the existing - # location. new_lib_dir = self.test_dir_path / 'lib' new_lib_dir.mkdir() - new_library_path = new_lib_dir / 'libopenjp2.dylib' - new_library_path.symlink_to(existing_library) + expected = new_lib_dir / 'libopenjp2.dylib' with self.config_file.open('wt') as f: f.write('[library]\n') - f.write(f'openjp2: {new_library_path}\n') + f.write(f'openjp2: {expected}\n') with chdir(self.glymur_configdir): # Should be able to load openjp2 as before. - imp.reload(glymur.lib.openjp2) + actual = glymur.config.read_config_file('openjp2') - actual = glymur.lib.openjp2.OPENJP2._name - expected = new_library_path self.assertEqual(actual, expected) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/tests/test_jp2k.py new/glymur-0.9.3/tests/test_jp2k.py --- old/glymur-0.9.2/tests/test_jp2k.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/tests/test_jp2k.py 2020-12-31 22:02:06.000000000 +0100 @@ -26,7 +26,7 @@ import numpy as np try: import skimage.data - import skimage.measure + import skimage.metrics _HAVE_SCIKIT_IMAGE = True except ModuleNotFoundError: _HAVE_SCIKIT_IMAGE = False @@ -1104,6 +1104,7 @@ self.assertEqual(j.layer, 0) + @unittest.skipIf(os.cpu_count() < 4, "makes no sense if 4 cores not there") def test_thread_support(self): """ SCENARIO: Set a non-default thread support value. @@ -1124,6 +1125,7 @@ self.assertTrue(delta1 < delta0) + @unittest.skipIf(os.cpu_count() < 4, "makes no sense if 4 cores not there") def test_thread_support_on_openjpeg_lt_220(self): """ SCENARIO: Set number of threads on openjpeg < 2.2.0 @@ -1134,6 +1136,7 @@ with self.assertRaises(RuntimeError): glymur.set_option('lib.num_threads', 4) + @unittest.skipIf(os.cpu_count() < 4, "makes no sense if 4 cores not there") @patch('glymur.lib.openjp2.has_thread_support') def test_thread_support_not_compiled_into_library(self, mock_ts): """ @@ -1226,6 +1229,24 @@ os.unlink(cls.single_channel_j2k) os.unlink(cls.single_channel_jp2) + @unittest.skipIf(os.cpu_count() < 2, "makes no sense if 2 cores not there") + def test_threads(self): + """ + SCENARIO: Attempt to encode with threading support. This feature is + new as of openjpeg library version 2.4.0. + + EXPECTED RESULT: In library versions prior to 2.4.0, a warning is + issued. + """ + glymur.set_option('lib.num_threads', 2) + with open(self.temp_jp2_filename, mode='wb') as tfile: + with warnings.catch_warnings(record=True) as w: + Jp2k(tfile.name, data=self.jp2_data) + if glymur.version.openjpeg_version >= '2.4.0': + self.assertEqual(len(w), 0) + else: + self.assertEqual(len(w), 1) + def test_no_jp2c_box_in_outermost_jp2_list(self): """ SCENARIO: A JP2 file is encountered without a JP2C box in the outer- @@ -1307,7 +1328,9 @@ # warning warnings.simplefilter('ignore') psnr = [ - skimage.measure.compare_psnr(skimage.data.camera(), d[j]) + skimage.metrics.peak_signal_noise_ratio( + skimage.data.camera(), d[j] + ) for j in range(4) ] @@ -2343,9 +2366,22 @@ self.assertEqual(ssdata.shape, (1, 1, 3)) def test_NR_DEC_p1_06_j2k_75_decode(self): - # Image size would be 0 x 0. - with self.assertRaises(InvalidJp2kError): - self.j2k[9:12:4, 9:12:4] + """ + SCENARIO: Try to read an image area with an impossible stride. + + EXPECTED RESULT: An error is raised. + """ + if glymur.version.openjpeg_version >= '2.4.0': + # The library catches this on its own. + expected_error = glymur.lib.openjp2.OpenJPEGLibraryError + else: + # Image size would be 0 x 0. We have to manually detect this. + expected_error = InvalidJp2kError + with self.assertRaises(expected_error): + with warnings.catch_warnings(): + # Only openjpeg 2.4.0 issues warnings + warnings.simplefilter('ignore') + self.j2k[9:12:4, 9:12:4] def test_NR_DEC_p0_04_j2k_85_decode(self): actual = self.j2k[:256, :256] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/tests/test_openjp2.py new/glymur-0.9.3/tests/test_openjp2.py --- old/glymur-0.9.2/tests/test_openjp2.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/tests/test_openjp2.py 2020-12-31 22:02:06.000000000 +0100 @@ -175,6 +175,12 @@ xtx5_setup(filename) self.assertTrue(True) + def test_tte5_short_write_tile_signature(self): + """Runs test designated tte5 in OpenJPEG test suite.""" + filename = str(self.temp_j2k_filename) + xtx5_setup(filename, short_sig=True) + self.assertTrue(True) + def tile_encoder(**kwargs): """Fixture used by many tests.""" @@ -243,7 +249,10 @@ openjp2.start_compress(codec, l_image, stream) for j in np.arange(num_tiles): - openjp2.write_tile(codec, j, data, tile_size, stream) + if 'short_sig' in kwargs and kwargs['short_sig']: + openjp2.write_tile(codec, j, data, stream) + else: + openjp2.write_tile(codec, j, data, tile_size, stream) openjp2.end_compress(codec, stream) openjp2.stream_destroy(stream) @@ -352,17 +361,20 @@ tile_encoder(**kwargs) -def xtx5_setup(filename): +def xtx5_setup(filename, short_sig=False): """Runs tests rta5, tte5.""" - kwargs = {'filename': filename, - 'codec': openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 0, - 'num_comps': 1, - 'image_height': 512, - 'image_width': 512, - 'tile_height': 256, - 'tile_width': 256} + kwargs = { + 'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 512, + 'image_width': 512, + 'tile_height': 256, + 'tile_width': 256, + 'short_sig': short_sig + } tile_encoder(**kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glymur-0.9.2/tests/test_printing.py new/glymur-0.9.3/tests/test_printing.py --- old/glymur-0.9.2/tests/test_printing.py 2020-06-30 22:34:59.000000000 +0200 +++ new/glymur-0.9.3/tests/test_printing.py 2020-12-31 22:02:06.000000000 +0100 @@ -1667,8 +1667,9 @@ ''' sgnd: 0\n''' ''' resno_decoded: 0\n''' ''' factor: 0\n''' - ''' data: <glymur.lib.openjp2.LP_c_(int|long) object at ''' - '''0x[a-fA-F0-9]+>\n''' + ''' data: ''' + '''<(glymur.lib.openjp2|ctypes.wintypes).LP_c_(int|long) ''' + '''object at 0x[a-fA-F0-9]+>\n''' ''' alpha: 0\n''' ) self.assertRegex(actual, expected)