[Git][debian-gis-team/glymur][upstream] New upstream version 0.13.5
Antonio Valentino (@antonio.valentino)
gitlab at salsa.debian.org
Tue Jul 30 07:12:02 BST 2024
Antonio Valentino pushed to branch upstream at Debian GIS Project / glymur
Commits:
2e9ed81b by Antonio Valentino at 2024-07-30T05:40:35+00:00
New upstream version 0.13.5
- - - - -
17 changed files:
- CHANGES.txt
- ci/doc.yml
- docs/requirements.txt
- docs/source/api.rst
- docs/source/conf.py
- docs/source/introduction.rst
- docs/source/whatsnew/0.13.rst
- glymur/codestream.py
- glymur/jp2k.py
- glymur/jp2kr.py
- glymur/version.py
- setup.cfg
- tests/test_codestream.py
- tests/test_jp2k.py
- tests/test_jp2kr.py
- tests/test_printing.py
- tests/test_threading.py
Changes:
=====================================
CHANGES.txt
=====================================
@@ -1,3 +1,8 @@
+July 26, 2024 - v0.13.5
+ Add support for parsing the CAP segment.
+ End official support for OpenJPEG 2.3.x.
+ Fix issue preventing API docs from building.
+
July 4, 2024 - v0.13.4
Don't reset openjpeg codec in Jp2k if already set in Jp2kr.
Update CI configuration to specify openjpeg versions.
=====================================
ci/doc.yml
=====================================
@@ -3,6 +3,7 @@ channels:
- conda-forge
dependencies:
- python=3.12
+ - lxml
- numpydoc>=0.8
- sphinx_rtd_theme>=0.4.2
=====================================
docs/requirements.txt
=====================================
@@ -1,2 +1,3 @@
numpydoc>=0.8
sphinx_rtd_theme>=0.4.2
+lxml
=====================================
docs/source/api.rst
=====================================
@@ -2,8 +2,12 @@
API reference
#############
-.. autoclass:: glymur.Jp2k
+.. automodule:: glymur.jp2kr
+
+.. autoclass:: glymur.Jp2kr
:members:
-.. autoclass:: glymur.jp2box.Jp2kBox
+.. automodule:: glymur.jp2k
+
+.. autoclass:: glymur.Jp2k
:members:
=====================================
docs/source/conf.py
=====================================
@@ -12,7 +12,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys
+import os, sys
class Mock(object):
@@ -42,7 +42,9 @@ for mod_name in MOCK_MODULES:
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-# sys.path.insert(0, os.path.abspath('.'))
+print(sys.path)
+sys.path.insert(0, os.path.abspath('../..'))
+print(sys.path)
# -- General configuration ----------------------------------------------------
@@ -78,7 +80,7 @@ copyright = '2013-2024, John Evans'
# The short X.Y version.
version = '0.13'
# The full version, including alpha/beta/rc tags.
-release = '0.13.4'
+release = '0.13.5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
=====================================
docs/source/introduction.rst
=====================================
@@ -2,17 +2,18 @@
Glymur: a Python interface for JPEG 2000
########################################
-**Glymur** is an interface to the OpenJPEG library
-which allows one to read and write JPEG 2000 files from Python.
-Glymur supports both reading and writing of JPEG 2000 images. A historical
-limitation of glymur was that it could not write images that did not fit
-into memory, but that limitation has been removed.
+**Glymur** is an interface to the OpenJPEG library which allows one
+to read and write JPEG 2000 files from Python. Glymur supports
+both reading and writing of JPEG 2000 images. There was a historical
+limitation of glymur where it could not write images that did not
+fit into memory, but that limitation has been removed.
In regards to metadata, most JP2 boxes are properly interpreted.
Certain optional JP2 boxes can also be written, including XML boxes and
XMP UUIDs. There is incomplete support for reading JPX metadata.
-The current version of glymur is supported on Python versions 3.10, 3.11, and 3.12.
+The current version of glymur is supported on Python versions 3.10,
+3.11, and 3.12. You should have at least version 2.4.0 of OpenJPEG.
For more information about OpenJPEG, please consult http://www.openjpeg.org.
=====================================
docs/source/whatsnew/0.13.rst
=====================================
@@ -2,6 +2,14 @@
Changes in glymur 0.13
######################
+*****************
+Changes in 0.13.5
+*****************
+
+ * Add support for parsing the CAP segment.
+ * End official support for OpenJPEG 2.3.x.
+ * Fix issue preventing API docs from building.
+
*****************
Changes in 0.13.4
*****************
=====================================
glymur/codestream.py
=====================================
@@ -189,7 +189,7 @@ class Codestream(object):
0xff3f: self._parse_reserved_marker,
# 0xff4f: SOC (already encountered by the time we get here)
- 0xff50: self._parse_reserved_segment,
+ 0xff50: self._parse_cap_segment,
0xff51: self._parse_siz_segment,
0xff52: self._parse_cod_segment,
0xff53: self._parse_coc_segment,
@@ -713,6 +713,37 @@ class Codestream(object):
return RGNsegment(crgn, srgn, sprgn, length, offset)
+ @classmethod
+ def _parse_cap_segment(cls, fptr):
+ """Parse the SIZ segment.
+
+ Parameters
+ ----------
+ fptr : file
+ Open file object.
+
+ Returns
+ -------
+ SIZSegment
+ The current SIZ segment.
+ """
+ offset = fptr.tell() - 2
+
+ read_buffer = fptr.read(2)
+ length, = struct.unpack('>H', read_buffer)
+ read_buffer = fptr.read(length - 2)
+
+ pcap, = struct.unpack('>I', read_buffer[:4])
+
+ n = (length - 6) // 2
+ ccap = struct.unpack('>' + 'H' * n, read_buffer[4:])
+
+ segment = CAPsegment(
+ pcap=pcap, ccap=ccap, length=length, offset=offset,
+ )
+
+ return segment
+
@classmethod
def _parse_siz_segment(cls, fptr):
"""Parse the SIZ segment.
@@ -934,6 +965,49 @@ class Segment(object):
return msg
+class CAPsegment(Segment):
+ """CAP (Extended Capabilities) segment information.
+
+ Attributes
+ ----------
+ marker_id : str
+ Identifier for the segment.
+ offset : int
+ Offset of marker segment in bytes from beginning of file.
+ length : int
+ Length of marker segment in bytes. This number does not include the
+ two bytes constituting the marker.
+ pcap : 32-bit unsigned int
+ bitmask where the kth 1 represents use of capabilities in Part k of
+ ISO/IEC 15444-k.
+ ccap : 16-bit unsigned int
+ The precise meaning depends on the related parts of ISO/IEC 15444-k.
+ """
+ def __init__(self, pcap, ccap, length, offset):
+ super().__init__(marker_id='CAP')
+ self.pcap = pcap
+ self.ccap = ccap
+ self.length = length
+ self.offset = offset
+
+ def __str__(self):
+ msg = Segment.__str__(self)
+
+ msg += '\n'
+
+ # have to cast to uint64 because, you know, stupid windows
+ parts = [
+ k for k in range(32)
+ if np.bitwise_and(np.uint64(self.pcap), np.uint64(1 << (32 - k)))
+ ]
+
+ for b in parts:
+ msg += f' Pcap: Part {b} (ISO/IEC 15444-{b})\n'
+ msg += f' Ccap: {self.ccap}'
+
+ return msg
+
+
class COCsegment(Segment):
"""COC (Coding style Component) segment information.
=====================================
glymur/jp2k.py
=====================================
@@ -34,13 +34,12 @@ from .lib import openjp2 as opj2
class Jp2k(Jp2kr):
- """Write JPEG 2000 files.
+ """Write JPEG 2000 files (and optionally read them as well).
Parameters
----------
filename : str or path
- The path to JPEG 2000 file. If you are only reading JPEG 2000 files,
- this is the only argument you need to supply.
+ The path to JPEG 2000 file.
data : np.ndarray, optional
Image data to be written to file.
shape : Tuple[int, int, ...], optional
@@ -105,35 +104,6 @@ class Jp2k(Jp2kr):
verbose : bool, optional
Print informational messages produced by the OpenJPEG library.
- Examples
- --------
- >>> jfile = glymur.data.nemo()
- >>> jp2 = glymur.Jp2k(jfile)
- >>> jp2.shape
- (1456, 2592, 3)
- >>> image = jp2[:]
- >>> image.shape
- (1456, 2592, 3)
-
- Read a lower resolution thumbnail.
-
- >>> thumbnail = jp2[::2, ::2]
- >>> thumbnail.shape
- (728, 1296, 3)
-
- Make use of OpenJPEG's thread support
-
- >>> import time
- >>> if glymur.version.openjpeg_version >= '2.2.0':
- ... jp2file = glymur.data.nemo()
- ... jp2 = glymur.Jp2k(jp2file)
- ... t0 = time.time(); data = jp2[:]; t1 = time.time()
- ... t1 - t0 #doctest: +SKIP
- 0.9024193286895752
- ... glymur.set_options('lib.num_threads', 4)
- ... t0 = time.time(); data = jp2[:]; t1 = time.time()
- ... t1 - t0 #doctest: +SKIP
- 0.4060473537445068
"""
def __init__(
@@ -800,12 +770,6 @@ class Jp2k(Jp2kr):
-------
Jp2k
Newly wrapped Jp2k object.
-
- Examples
- --------
- >>> jfile = glymur.data.goodstuff()
- >>> j2k = glymur.Jp2k(jfile)
- >>> jp2 = j2k.wrap('jp2_from_j2k.jp2')
"""
if boxes is None:
boxes = self._get_default_jp2_boxes()
=====================================
glymur/jp2kr.py
=====================================
@@ -55,6 +55,19 @@ class Jp2kr(Jp2kBox):
>>> thumbnail = jp2[::2, ::2]
>>> thumbnail.shape
(728, 1296, 3)
+
+ Make use of OpenJPEG's thread support
+
+ >>> import time
+ >>> jp2file = glymur.data.nemo()
+ >>> jp2 = glymur.Jp2k(jp2file)
+ >>> t0 = time.time(); data = jp2[:]; t1 = time.time()
+ >>> t1 - t0 #doctest: +SKIP
+ 0.9024193286895752
+ >>> glymur.set_option('lib.num_threads', 4)
+ >>> t0 = time.time(); data = jp2[:]; t1 = time.time()
+ >>> t1 - t0 #doctest: +SKIP
+ 0.4060473537445068
"""
def __init__(
@@ -233,7 +246,7 @@ class Jp2kr(Jp2kBox):
@property
def codestream(self):
- """Metadata for JP2 or J2K codestream (header only)."""
+ """Metadata for JP2 or J2K codestream header."""
if self._codestream is None:
self._codestream = self.get_codestream(header_only=True)
return self._codestream
@@ -523,6 +536,9 @@ class Jp2kr(Jp2kBox):
def read(self, **kwargs):
"""Read a JPEG 2000 image.
+ .. deprecated:: 0.13.5
+ Use numpy-style slicing instead.
+
Returns
-------
img_array : ndarray
@@ -724,7 +740,7 @@ class Jp2kr(Jp2kBox):
verbose=False, ignore_pclr_cmap_cdef=False):
"""Read a JPEG 2000 image.
- The only time you should use this method is when the image has
+ The only time you should ever use this method is when the image has
different subsampling factors across components. Otherwise you should
use the read method.
@@ -870,6 +886,10 @@ class Jp2kr(Jp2kBox):
def get_codestream(self, header_only=True):
"""Retrieve codestream.
+ This differs from the codestream property in that segment
+ metadata that lies past the end of the codestream header
+ can be retrieved.
+
Parameters
----------
header_only : bool, optional
=====================================
glymur/version.py
=====================================
@@ -20,7 +20,7 @@ from .lib import tiff
# Do not change the format of this next line! Doing so risks breaking
# setup.py
-version = "0.13.4"
+version = "0.13.5"
version_tuple = parse(version).release
=====================================
setup.cfg
=====================================
@@ -1,6 +1,6 @@
[metadata]
name = Glymur
-version = 0.13.4
+version = 0.13.5
author = 'John Evans'
author_email = "John Evans" <jevans667cc at proton.me>
license = 'MIT'
=====================================
tests/test_codestream.py
=====================================
@@ -30,6 +30,19 @@ class TestSuite(fixtures.TestCommon):
self.p1_06 = ir.files('tests.data').joinpath('p1_06.j2k')
self.issue142 = ir.files('tests.data').joinpath('issue142.j2k')
self.edf_c2_1178956 = ir.files('tests.data').joinpath('edf_c2_1178956.jp2') # noqa : E501
+ self.htj2k = ir.files('tests.data').joinpath('oj-ht-byte.jph')
+
+ def test_cap_marker_segment(self):
+ """
+ SCENARIO: the file has a CAP marker segment for the 3rd segment
+
+ EXPECTED RESULT: the segment metadata is verified
+ """
+ j = Jp2k(self.htj2k)
+ cap = j.codestream.segment[2]
+
+ self.assertEqual(cap.pcap, 131072)
+ self.assertEqual(cap.ccap, (3,))
def test_unrecognized_marker(self):
"""
=====================================
tests/test_jp2k.py
=====================================
@@ -29,8 +29,8 @@ from . import fixtures
@unittest.skipIf(OPENJPEG_NOT_AVAILABLE, OPENJPEG_NOT_AVAILABLE_MSG)
- at unittest.skipIf(glymur.version.openjpeg_version < '2.3.0',
- "Requires as least v2.3.0")
+ at unittest.skipIf(glymur.version.openjpeg_version < '2.4.0',
+ "Requires as least v2.4.0")
class TestJp2k(fixtures.TestCommon):
"""These tests should be run by just about all configuration."""
=====================================
tests/test_jp2kr.py
=====================================
@@ -29,8 +29,8 @@ from . import fixtures
@unittest.skipIf(OPENJPEG_NOT_AVAILABLE, OPENJPEG_NOT_AVAILABLE_MSG)
- at unittest.skipIf(glymur.version.openjpeg_version < '2.3.0',
- "Requires as least v2.3.0")
+ at unittest.skipIf(glymur.version.openjpeg_version < '2.4.0',
+ "Requires as least v2.4.0")
class TestJp2kr(fixtures.TestCommon):
"""These tests should be run by just about all configuration."""
=====================================
tests/test_printing.py
=====================================
@@ -42,6 +42,22 @@ class TestPrinting(fixtures.TestCommon):
super().tearDown()
glymur.reset_option('all')
+ def test_cap_segment(self):
+ """
+ Scenario: Print a CAP segment
+
+ Expected Result: segment is verified
+ """
+ htj2k_file = ir.files('tests.data').joinpath('oj-ht-byte.jph')
+ j = glymur.Jp2kr(htj2k_file)
+ actual = str(j.codestream.segment[2])
+ expected = (
+ 'CAP marker segment @ (467, 8)\n'
+ ' Pcap: Part 15 (ISO/IEC 15444-15)\n'
+ ' Ccap: (3,)'
+ )
+ self.assertEqual(actual, expected)
+
def test_empty_file(self):
"""
SCENARIO: Print the file after with object is constructed, but
=====================================
tests/test_threading.py
=====================================
@@ -22,8 +22,8 @@ from . import fixtures
@unittest.skipIf(os.cpu_count() < 2, "makes no sense if 2 cores not there")
@unittest.skipIf(OPENJPEG_NOT_AVAILABLE, OPENJPEG_NOT_AVAILABLE_MSG)
- at unittest.skipIf(glymur.version.openjpeg_version < '2.3.0',
- "Requires as least v2.3.0")
+ at unittest.skipIf(glymur.version.openjpeg_version < '2.4.0',
+ "Requires as least v2.4.0")
class TestSuite(fixtures.TestCommon):
"""Test behavior when multiple threads are possible."""
@@ -79,7 +79,7 @@ class TestSuite(fixtures.TestCommon):
glymur.set_option('lib.num_threads', 2)
@unittest.skipIf(
- glymur.version.openjpeg_version < '2.4.0', "Requires as least v2.3.0"
+ glymur.version.openjpeg_version < '2.4.0', "Requires as least v2.4.0"
)
def test_threads_write_support__ge_2p4(self):
"""
View it on GitLab: https://salsa.debian.org/debian-gis-team/glymur/-/commit/2e9ed81b18a814aa2001fdde516e0ad33ce78c0b
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/glymur/-/commit/2e9ed81b18a814aa2001fdde516e0ad33ce78c0b
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20240730/64b5bde3/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list