[Git][debian-gis-team/glymur][upstream] New upstream version 0.14.7

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Fri Feb 6 07:28:36 GMT 2026



Antonio Valentino pushed to branch upstream at Debian GIS Project / glymur


Commits:
e0efc97c by Antonio Valentino at 2026-02-06T07:25:53+00:00
New upstream version 0.14.7
- - - - -


15 changed files:

- .circleci/config.yml
- CHANGES.txt
- + ci/ci-311-np1.yaml
- ci/ci-312.yaml
- ci/ci-313.yaml
- docs/source/conf.py
- docs/source/whatsnew/0.14.rst
- glymur/jp2box.py
- glymur/jp2k.py
- glymur/jp2kr.py
- glymur/version.py
- pyproject.toml
- tests/test_jp2k.py
- tests/test_jp2kr.py
- tests/test_printing.py


Changes:

=====================================
.circleci/config.yml
=====================================
@@ -6,6 +6,7 @@ workflows:
   version: 2
   test:
     jobs:
+      - ci-311-np1
       - ci-311
       - ci-312
       - ci-313
@@ -47,6 +48,9 @@ test-template: &test-template
           pytest --doctest-modules glymur
 
 jobs:
+  ci-311-np1:
+    <<: *test-template
+
   ci-311:
     <<: *test-template
 


=====================================
CHANGES.txt
=====================================
@@ -1,4 +1,8 @@
-Jan 26, 2025 - v0.14.6
+Feb 04, 2026 - v0.14.7
+    Refactor image dimension validation
+    Refactor codestream parsing
+
+Jan 26, 2026 - v0.14.6
     Fix numpy 2.5 deprecation issue
 
 Oct 08, 2025 - v0.14.4


=====================================
ci/ci-311-np1.yaml
=====================================
@@ -0,0 +1,13 @@
+name: glymur
+channels:
+    - conda-forge
+dependencies:
+    - python=3.11.*
+    - gdal>=3.8.0,<3.9.0
+    - pillow
+    - libtiff>=4.6.0,<4.7.0
+    - lxml>=5.0
+    - numpy<2.0
+    - openjpeg>=2.5
+    - pytest-xdist
+    - scikit-image


=====================================
ci/ci-312.yaml
=====================================
@@ -7,7 +7,7 @@ dependencies:
     - pillow
     - libtiff>=4.7.0,<4.8.0
     - lxml>=5.0.0
-    - numpy>=2.0
+    - numpy>=2.0,<2.3
     - openjpeg>=2.5
     - pytest-xdist
     - scikit-image


=====================================
ci/ci-313.yaml
=====================================
@@ -8,7 +8,7 @@ dependencies:
     - pillow
     - libtiff>=4.7.0,<4.8.0
     - lxml>=5.3.0,<6.0.0
-    - numpy>=2.1,<2.3.3
+    - numpy>=2.3,<2.4
     - openjpeg>=2.5.3,<2.5.4
     - pytest-xdist
     - scikit-image


=====================================
docs/source/conf.py
=====================================
@@ -81,7 +81,7 @@ copyright = '2013-2026, John Evans'
 # The short X.Y version.
 version = '0.14'
 # The full version, including alpha/beta/rc tags.
-release = '0.14.6'
+release = '0.14.7'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.


=====================================
docs/source/whatsnew/0.14.rst
=====================================
@@ -2,6 +2,16 @@
 Changes in glymur 0.14
 ######################
 
+*****************
+Changes in 0.14.7
+*****************
+
+    * Refactor image dimension validation
+    * Refactor codestream parsing
+    * Update CI numpy specs
+    * Add CI workflow for numpy<2.0
+
+
 *****************
 Changes in 0.14.6
 *****************


=====================================
glymur/jp2box.py
=====================================
@@ -2,11 +2,11 @@
 
 References
 ----------
-.. [JP2K15444-1i] International Organization for Standardication.  ISO/IEC
+.. [JP2K15444-1i] International Organization for Standardization.  ISO/IEC
    15444-1:2004 - Information technology -- JPEG 2000 image coding system:
    Core coding system
 
-.. [JP2K15444-2m] International Organization for Standardication.  ISO/IEC
+.. [JP2K15444-2m] International Organization for Standardization.  ISO/IEC
    15444-2:2004 - Information technology -- JPEG 2000 image coding system:
    Extensions
 """
@@ -1065,7 +1065,7 @@ class ContiguousCodestreamBox(Jp2kBox):
         offset=-1
     ):
         super().__init__()
-        self._codestream = codestream
+        self.codestream = codestream
         self.length = length
         self.offset = offset
         self.main_header_offset = main_header_offset
@@ -1073,24 +1073,6 @@ class ContiguousCodestreamBox(Jp2kBox):
         # The filename can be set if lazy loading is desired.
         self._filename = None
 
-    @property
-    def codestream(self):
-        if get_option("parse.full_codestream") is True:
-            header_only = False
-        else:
-            header_only = True
-        if self._codestream is None:
-            if self._filename is not None:
-                with open(self._filename, "rb") as fptr:
-                    fptr.seek(self.main_header_offset)
-                    self._codestream = Codestream(
-                        fptr,
-                        self.length,
-                        header_only=header_only
-                    )
-
-        return self._codestream
-
     def __repr__(self):
         msg = "glymur.jp2box.ContiguousCodeStreamBox"
         msg += f"(codestream={repr(self.codestream)})"
@@ -1134,7 +1116,7 @@ class ContiguousCodestreamBox(Jp2kBox):
         if get_option("parse.full_codestream"):
             codestream = Codestream(fptr, length, header_only=False)
         else:
-            codestream = None
+            codestream = Codestream(fptr, length, header_only=True)
         box = cls(
             codestream,
             main_header_offset=main_header_offset,
@@ -3555,7 +3537,7 @@ class UUIDBox(Jp2kBox):
 
     References
     ----------
-    .. [XMP] International Organization for Standardication.  ISO/IEC
+    .. [XMP] International Organization for Standardization.  ISO/IEC
        16684-1:2012 - Graphic technology -- Extensible metadata platform (XMP)
        specification -- Part 1:  Data model, serialization and core properties
     """


=====================================
glymur/jp2k.py
=====================================
@@ -1079,8 +1079,9 @@ class Jp2k(Jp2kr):
         else:
             numrows, numcols, num_comps = self.shape
 
-        for k in range(num_comps):
-            self._validate_nonzero_image_size(numrows, numcols, k)
+        if 0 in imgdata.shape:
+            msg = f"The image has invalid dimensions, {imgdata.shape}."
+            raise InvalidJp2kError(msg)
 
         # set image offset and reference grid
         image.contents.x0 = self._cparams.image_offset_x0


=====================================
glymur/jp2kr.py
=====================================
@@ -455,6 +455,13 @@ class Jp2kr(Jp2kBox):
             # boxes) here.
             fptr.seek(0)
             self.box = self.parse_superbox(fptr)
+
+            # Set the codestream property if it is there.  Do this now because
+            # the validation process would otherwise cause another file-open to
+            # occur and re-parse the codestream (if it exists).
+            jp2c = next(filter(lambda x: x.box_id == 'jp2c', self.box), None)
+            self._codestream = jp2c.codestream if jp2c is not None else None
+
             self._validate()
 
         self._parse_count += 1
@@ -926,7 +933,14 @@ class Jp2kr(Jp2kBox):
         for k in range(raw_image.contents.numcomps):
             component = raw_image.contents.comps[k]
 
-            self._validate_nonzero_image_size(nrows[k], ncols[k], k)
+            # validate the image size
+            if nrows[k] == 0 or ncols[k] == 0:
+                # Letting this situation continue would segfault openjpeg.
+                msg = (
+                    f"Component {k} has invalid dimensions, "
+                    f"{nrows[k]} x {ncols[k]}"
+                )
+                raise InvalidJp2kError(msg)
 
             addr = ctypes.addressof(component.data.contents)
             with warnings.catch_warnings():
@@ -984,10 +998,6 @@ 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
@@ -1023,50 +1033,37 @@ class Jp2kr(Jp2kBox):
 
             # if it's just a raw codestream file, it's easy
             if self._codec_format == opj2.CODEC_J2K:
-                return self._get_codestream(fptr, self.length, header_only)
-
-            # continue assuming JP2, must seek to the JP2C box and past its
-            # header
-            box = next(filter(lambda x: x.box_id == "jp2c", self.box), None)
-
-            fptr.seek(box.offset)
-            read_buffer = fptr.read(8)
-            (box_length, _) = struct.unpack(">I4s", read_buffer)
-            if box_length == 0:
-                # The length of the box is presumed to last until the end
-                # of the file.  Compute the effective length of the box.
-                box_length = self.path.stat().st_size - fptr.tell() + 8
-            elif box_length == 1:
-                # Seek past the XL field.
-                read_buffer = fptr.read(8)
-                (box_length,) = struct.unpack(">Q", read_buffer)
-
-            return self._get_codestream(fptr, box_length - 8, header_only)
-
-    def _get_codestream(self, fptr, length, header_only):
-        """
-        Parsing errors can make for confusing errors sometimes, so catch any
-        such error and add context to it.
-        """
+                length = self.length
+            else:
 
-        try:
-            codestream = Codestream(fptr, length, header_only=header_only)
-        except Exception:
-            _, value, traceback = sys.exc_info()
-            msg = (
-                f"The file is invalid "
-                f'because the codestream could not be parsed:  "{value}"'
-            )
-            raise InvalidJp2kError(msg).with_traceback(traceback)
-        else:
-            return codestream
+                # continue assuming JP2, must seek to the JP2C box and past its
+                # header
+                box = next(
+                    filter(lambda x: x.box_id == "jp2c", self.box),
+                    None
+                )
 
-    def _validate_nonzero_image_size(self, nrows, ncols, component_index):
-        """The image cannot have area of zero."""
-        if nrows == 0 or ncols == 0:
-            # Letting this situation continue would segfault openjpeg.
-            msg = (
-                f"Component {component_index} has dimensions "
-                f"{nrows} x {ncols}"
-            )
-            raise InvalidJp2kError(msg)
+                fptr.seek(box.offset)
+                read_buffer = fptr.read(8)
+                (box_length, _) = struct.unpack(">I4s", read_buffer)
+                if box_length == 0:
+                    # The length of the box is presumed to last until the end
+                    # of the file.  Compute the effective length of the box.
+                    box_length = self.path.stat().st_size - fptr.tell() + 8
+                elif box_length == 1:
+                    # Seek past the XL field.
+                    read_buffer = fptr.read(8)
+                    (box_length,) = struct.unpack(">Q", read_buffer)
+                length = box_length - 8
+
+            try:
+                codestream = Codestream(fptr, length, header_only=header_only)
+            except Exception:
+                _, value, traceback = sys.exc_info()
+                msg = (
+                    f"The file is invalid "
+                    f'because the codestream could not be parsed:  "{value}"'
+                )
+                raise InvalidJp2kError(msg).with_traceback(traceback)
+            else:
+                return codestream


=====================================
glymur/version.py
=====================================
@@ -20,7 +20,7 @@ from .lib import _tiff as tiff
 
 # Do not change the format of this next line!  Doing so risks breaking
 # setup.py
-version = "0.14.6"
+version = "0.14.7"
 
 version_tuple = parse(version).release
 


=====================================
pyproject.toml
=====================================
@@ -22,7 +22,7 @@ license = 'MIT'
 name = 'Glymur'
 readme = 'README.md'
 requires-python = '>=3.11'
-version = '0.14.6'
+version = '0.14.7'
 
 [project.scripts]
 jp2dump = 'glymur.command_line:main'


=====================================
tests/test_jp2k.py
=====================================
@@ -1056,10 +1056,7 @@ class TestParsing(unittest.TestCase):
         glymur.set_option("parse.full_codestream", False)
 
     def test_main_header(self):
-        """verify that the main header isn't loaded during normal parsing"""
-        # The hidden _main_header attribute should show up after accessing it.
+        """verify that the main header is loaded during normal parsing"""
         jp2 = Jp2k(self.jp2file)
         jp2c = jp2.box[3]
-        self.assertIsNone(jp2c._codestream)
-        jp2c.codestream
-        self.assertIsNotNone(jp2c._codestream)
+        self.assertIsNotNone(jp2c.codestream)


=====================================
tests/test_jp2kr.py
=====================================
@@ -973,10 +973,7 @@ class TestParsing(unittest.TestCase):
         glymur.set_option('parse.full_codestream', False)
 
     def test_main_header(self):
-        """verify that the main header isn't loaded during normal parsing"""
-        # The hidden _main_header attribute should show up after accessing it.
+        """verify that the main header is loaded during normal parsing"""
         jp2 = Jp2kr(self.jp2file)
         jp2c = jp2.box[-1]
-        self.assertIsNone(jp2c._codestream)
-        jp2c.codestream
-        self.assertIsNotNone(jp2c._codestream)
+        self.assertIsNotNone(jp2c.codestream)


=====================================
tests/test_printing.py
=====================================
@@ -1580,8 +1580,8 @@ class TestPrinting(fixtures.TestCommon):
         """
         Verify printing with the full blown codestream
         """
-        jp2 = Jp2k(self.jp2file)
         glymur.set_option('parse.full_codestream', True)
+        jp2 = Jp2k(self.jp2file)
 
         # Get rid of the file line
         actual = '\n'.join(str(jp2).splitlines()[1:])



View it on GitLab: https://salsa.debian.org/debian-gis-team/glymur/-/commit/e0efc97c51819ae44e7ddb531a3dc9fe737c4d86

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/glymur/-/commit/e0efc97c51819ae44e7ddb531a3dc9fe737c4d86
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/20260206/829bfeaa/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list