Glymur 0.13.3__tar.gz → 0.13.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {glymur-0.13.3 → glymur-0.13.5}/CHANGES.txt +9 -0
  2. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/PKG-INFO +1 -1
  3. {glymur-0.13.3 → glymur-0.13.5}/PKG-INFO +1 -1
  4. {glymur-0.13.3 → glymur-0.13.5}/glymur/codestream.py +84 -3
  5. {glymur-0.13.3 → glymur-0.13.5}/glymur/jp2box.py +7 -4
  6. {glymur-0.13.3 → glymur-0.13.5}/glymur/jp2k.py +9 -45
  7. {glymur-0.13.3 → glymur-0.13.5}/glymur/jp2kr.py +22 -2
  8. {glymur-0.13.3 → glymur-0.13.5}/glymur/version.py +1 -1
  9. {glymur-0.13.3 → glymur-0.13.5}/setup.cfg +1 -1
  10. {glymur-0.13.3 → glymur-0.13.5}/tests/test_codestream.py +13 -0
  11. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2box.py +11 -1
  12. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2k.py +16 -2
  13. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2kr.py +2 -2
  14. {glymur-0.13.3 → glymur-0.13.5}/tests/test_printing.py +37 -0
  15. {glymur-0.13.3 → glymur-0.13.5}/tests/test_threading.py +3 -3
  16. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/SOURCES.txt +0 -0
  17. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/dependency_links.txt +0 -0
  18. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/entry_points.txt +0 -0
  19. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/not-zip-safe +0 -0
  20. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/requires.txt +0 -0
  21. {glymur-0.13.3 → glymur-0.13.5}/Glymur.egg-info/top_level.txt +0 -0
  22. {glymur-0.13.3 → glymur-0.13.5}/LICENSE.txt +0 -0
  23. {glymur-0.13.3 → glymur-0.13.5}/MANIFEST.in +0 -0
  24. {glymur-0.13.3 → glymur-0.13.5}/README.md +0 -0
  25. {glymur-0.13.3 → glymur-0.13.5}/glymur/__init__.py +0 -0
  26. {glymur-0.13.3 → glymur-0.13.5}/glymur/_iccprofile.py +0 -0
  27. {glymur-0.13.3 → glymur-0.13.5}/glymur/command_line.py +0 -0
  28. {glymur-0.13.3 → glymur-0.13.5}/glymur/config.py +0 -0
  29. {glymur-0.13.3 → glymur-0.13.5}/glymur/core.py +0 -0
  30. {glymur-0.13.3 → glymur-0.13.5}/glymur/data/__init__.py +0 -0
  31. {glymur-0.13.3 → glymur-0.13.5}/glymur/data/goodstuff.j2k +0 -0
  32. {glymur-0.13.3 → glymur-0.13.5}/glymur/data/heliov.jpx +0 -0
  33. {glymur-0.13.3 → glymur-0.13.5}/glymur/data/nemo.jp2 +0 -0
  34. {glymur-0.13.3 → glymur-0.13.5}/glymur/lib/__init__.py +0 -0
  35. {glymur-0.13.3 → glymur-0.13.5}/glymur/lib/openjp2.py +0 -0
  36. {glymur-0.13.3 → glymur-0.13.5}/glymur/lib/tiff.py +0 -0
  37. {glymur-0.13.3 → glymur-0.13.5}/glymur/options.py +0 -0
  38. {glymur-0.13.3 → glymur-0.13.5}/glymur/tiff.py +0 -0
  39. {glymur-0.13.3 → glymur-0.13.5}/pyproject.toml +0 -0
  40. {glymur-0.13.3 → glymur-0.13.5}/tests/test_callbacks.py +0 -0
  41. {glymur-0.13.3 → glymur-0.13.5}/tests/test_cinema.py +0 -0
  42. {glymur-0.13.3 → glymur-0.13.5}/tests/test_colour_specification_box.py +0 -0
  43. {glymur-0.13.3 → glymur-0.13.5}/tests/test_config.py +0 -0
  44. {glymur-0.13.3 → glymur-0.13.5}/tests/test_geo.py +0 -0
  45. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2box_jpx.py +0 -0
  46. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2box_uuid.py +0 -0
  47. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2box_xml.py +0 -0
  48. {glymur-0.13.3 → glymur-0.13.5}/tests/test_jp2k_writes.py +0 -0
  49. {glymur-0.13.3 → glymur-0.13.5}/tests/test_libtiff.py +0 -0
  50. {glymur-0.13.3 → glymur-0.13.5}/tests/test_openjp2.py +0 -0
  51. {glymur-0.13.3 → glymur-0.13.5}/tests/test_set_decoded_components.py +0 -0
  52. {glymur-0.13.3 → glymur-0.13.5}/tests/test_slicing.py +0 -0
  53. {glymur-0.13.3 → glymur-0.13.5}/tests/test_tiff2jp2.py +0 -0
  54. {glymur-0.13.3 → glymur-0.13.5}/tests/test_warnings.py +0 -0
@@ -1,3 +1,12 @@
1
+ July 26, 2024 - v0.13.5
2
+ Add support for parsing the CAP segment.
3
+ End official support for OpenJPEG 2.3.x.
4
+ Fix issue preventing API docs from building.
5
+
6
+ July 4, 2024 - v0.13.4
7
+ Don't reset openjpeg codec in Jp2k if already set in Jp2kr.
8
+ Update CI configuration to specify openjpeg versions.
9
+
1
10
  June 30, 2024 - v0.13.3
2
11
  Refactor parsing errors and warnings.
3
12
  Update CI configuration for numpy 2.0.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Glymur
3
- Version: 0.13.3
3
+ Version: 0.13.5
4
4
  Home-page: https://github.com/quintusdias/glymur
5
5
  Author: 'John Evans'
6
6
  Author-email: "John Evans" <jevans667cc@proton.me>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Glymur
3
- Version: 0.13.3
3
+ Version: 0.13.5
4
4
  Home-page: https://github.com/quintusdias/glymur
5
5
  Author: 'John Evans'
6
6
  Author-email: "John Evans" <jevans667cc@proton.me>
@@ -189,7 +189,7 @@ class Codestream(object):
189
189
  0xff3f: self._parse_reserved_marker,
190
190
 
191
191
  # 0xff4f: SOC (already encountered by the time we get here)
192
- 0xff50: self._parse_reserved_segment,
192
+ 0xff50: self._parse_cap_segment,
193
193
  0xff51: self._parse_siz_segment,
194
194
  0xff52: self._parse_cod_segment,
195
195
  0xff53: self._parse_coc_segment,
@@ -713,6 +713,37 @@ class Codestream(object):
713
713
 
714
714
  return RGNsegment(crgn, srgn, sprgn, length, offset)
715
715
 
716
+ @classmethod
717
+ def _parse_cap_segment(cls, fptr):
718
+ """Parse the SIZ segment.
719
+
720
+ Parameters
721
+ ----------
722
+ fptr : file
723
+ Open file object.
724
+
725
+ Returns
726
+ -------
727
+ SIZSegment
728
+ The current SIZ segment.
729
+ """
730
+ offset = fptr.tell() - 2
731
+
732
+ read_buffer = fptr.read(2)
733
+ length, = struct.unpack('>H', read_buffer)
734
+ read_buffer = fptr.read(length - 2)
735
+
736
+ pcap, = struct.unpack('>I', read_buffer[:4])
737
+
738
+ n = (length - 6) // 2
739
+ ccap = struct.unpack('>' + 'H' * n, read_buffer[4:])
740
+
741
+ segment = CAPsegment(
742
+ pcap=pcap, ccap=ccap, length=length, offset=offset,
743
+ )
744
+
745
+ return segment
746
+
716
747
  @classmethod
717
748
  def _parse_siz_segment(cls, fptr):
718
749
  """Parse the SIZ segment.
@@ -736,7 +767,9 @@ class Codestream(object):
736
767
  data = struct.unpack_from('>HIIIIIIIIH', read_buffer)
737
768
 
738
769
  rsiz = data[0]
739
- if rsiz not in _KNOWN_PROFILES:
770
+
771
+ # Bit 14 (16384) signifies HTJ2K (JPH)
772
+ if rsiz not in _KNOWN_PROFILES and not np.bitwise_and(rsiz, 16384):
740
773
  msg = f"Invalid profile: (Rsiz={rsiz})."
741
774
  warnings.warn(msg, UserWarning)
742
775
 
@@ -932,6 +965,49 @@ class Segment(object):
932
965
  return msg
933
966
 
934
967
 
968
+ class CAPsegment(Segment):
969
+ """CAP (Extended Capabilities) segment information.
970
+
971
+ Attributes
972
+ ----------
973
+ marker_id : str
974
+ Identifier for the segment.
975
+ offset : int
976
+ Offset of marker segment in bytes from beginning of file.
977
+ length : int
978
+ Length of marker segment in bytes. This number does not include the
979
+ two bytes constituting the marker.
980
+ pcap : 32-bit unsigned int
981
+ bitmask where the kth 1 represents use of capabilities in Part k of
982
+ ISO/IEC 15444-k.
983
+ ccap : 16-bit unsigned int
984
+ The precise meaning depends on the related parts of ISO/IEC 15444-k.
985
+ """
986
+ def __init__(self, pcap, ccap, length, offset):
987
+ super().__init__(marker_id='CAP')
988
+ self.pcap = pcap
989
+ self.ccap = ccap
990
+ self.length = length
991
+ self.offset = offset
992
+
993
+ def __str__(self):
994
+ msg = Segment.__str__(self)
995
+
996
+ msg += '\n'
997
+
998
+ # have to cast to uint64 because, you know, stupid windows
999
+ parts = [
1000
+ k for k in range(32)
1001
+ if np.bitwise_and(np.uint64(self.pcap), np.uint64(1 << (32 - k)))
1002
+ ]
1003
+
1004
+ for b in parts:
1005
+ msg += f' Pcap: Part {b} (ISO/IEC 15444-{b})\n'
1006
+ msg += f' Ccap: {self.ccap}'
1007
+
1008
+ return msg
1009
+
1010
+
935
1011
  class COCsegment(Segment):
936
1012
  """COC (Coding style Component) segment information.
937
1013
 
@@ -1666,7 +1742,12 @@ class SIZsegment(Segment):
1666
1742
  try:
1667
1743
  profile = _CAPABILITIES_DISPLAY[self.rsiz]
1668
1744
  except KeyError:
1669
- profile = f'{self.rsiz} (invalid)'
1745
+ if np.bitwise_and(self.rsiz, 16384):
1746
+ # HTJ2K profile that is uninterpreted
1747
+ profile = f'{self.rsiz}'
1748
+ else:
1749
+ # profile unknown
1750
+ profile = f'{self.rsiz} (invalid)'
1670
1751
  msg = msg.format(
1671
1752
  profile=profile,
1672
1753
  height=self.ysiz, width=self.xsiz,
@@ -1259,7 +1259,7 @@ class FileTypeBox(Jp2kBox):
1259
1259
  """
1260
1260
  box_id = 'ftyp'
1261
1261
  longname = 'File Type'
1262
- _valid_cls = ['jp2 ', 'jpx ', 'jpxb']
1262
+ _valid_cls = ['jp2 ', 'jph ', 'jpx ', 'jpxb']
1263
1263
 
1264
1264
  def __init__(
1265
1265
  self, brand='jp2 ', minor_version=0, compatibility_list=None,
@@ -1304,16 +1304,19 @@ class FileTypeBox(Jp2kBox):
1304
1304
  return text
1305
1305
 
1306
1306
  def _validate(self, writing=False):
1307
- """Validate the box before writing to file."""
1308
- if self.brand not in ['jp2 ', 'jpx ']:
1307
+ """
1308
+ Validate the box before writing to file.
1309
+ """
1310
+ if self.brand not in ['jp2 ', 'jpx ', 'jph ']:
1309
1311
  msg = (
1310
1312
  f"The file type brand was '{self.brand}'. "
1311
- f"It should be either 'jp2 ' or 'jpx '."
1313
+ f"It should be either 'jp2 ', 'jpx ', or 'jph '."
1312
1314
  )
1313
1315
  if writing:
1314
1316
  raise InvalidJp2kError(msg)
1315
1317
  else:
1316
1318
  warnings.warn(msg, UserWarning)
1319
+
1317
1320
  for item in self.compatibility_list:
1318
1321
  if item not in self._valid_cls:
1319
1322
  msg = (
@@ -34,13 +34,12 @@ from .lib import openjp2 as opj2
34
34
 
35
35
 
36
36
  class Jp2k(Jp2kr):
37
- """Write JPEG 2000 files.
37
+ """Write JPEG 2000 files (and optionally read them as well).
38
38
 
39
39
  Parameters
40
40
  ----------
41
41
  filename : str or path
42
- The path to JPEG 2000 file. If you are only reading JPEG 2000 files,
43
- this is the only argument you need to supply.
42
+ The path to JPEG 2000 file.
44
43
  data : np.ndarray, optional
45
44
  Image data to be written to file.
46
45
  shape : Tuple[int, int, ...], optional
@@ -105,35 +104,6 @@ class Jp2k(Jp2kr):
105
104
  verbose : bool, optional
106
105
  Print informational messages produced by the OpenJPEG library.
107
106
 
108
- Examples
109
- --------
110
- >>> jfile = glymur.data.nemo()
111
- >>> jp2 = glymur.Jp2k(jfile)
112
- >>> jp2.shape
113
- (1456, 2592, 3)
114
- >>> image = jp2[:]
115
- >>> image.shape
116
- (1456, 2592, 3)
117
-
118
- Read a lower resolution thumbnail.
119
-
120
- >>> thumbnail = jp2[::2, ::2]
121
- >>> thumbnail.shape
122
- (728, 1296, 3)
123
-
124
- Make use of OpenJPEG's thread support
125
-
126
- >>> import time
127
- >>> if glymur.version.openjpeg_version >= '2.2.0':
128
- ... jp2file = glymur.data.nemo()
129
- ... jp2 = glymur.Jp2k(jp2file)
130
- ... t0 = time.time(); data = jp2[:]; t1 = time.time()
131
- ... t1 - t0 #doctest: +SKIP
132
- 0.9024193286895752
133
- ... glymur.set_options('lib.num_threads', 4)
134
- ... t0 = time.time(); data = jp2[:]; t1 = time.time()
135
- ... t1 - t0 #doctest: +SKIP
136
- 0.4060473537445068
137
107
  """
138
108
 
139
109
  def __init__(
@@ -206,13 +176,13 @@ class Jp2k(Jp2kr):
206
176
  # Must be determined when writing.
207
177
  self._shape = None
208
178
 
209
- # If there already was a shape attribute, then don't mess with it,
210
- # it was set by the reader superclass.
211
-
212
- if self.filename[-4:].endswith(('.jp2', '.JP2', '.jpx', 'JPX')):
213
- self._codec_format = opj2.CODEC_JP2
214
- else:
215
- self._codec_format = opj2.CODEC_J2K
179
+ if not hasattr(self, '_codec_format'):
180
+ # Only set codec format if the superclass has not done so, i.e.
181
+ # we are writing instead of reading.
182
+ if self.filename[-4:].endswith(('.jp2', '.JP2', '.jpx', 'JPX')):
183
+ self._codec_format = opj2.CODEC_JP2
184
+ else:
185
+ self._codec_format = opj2.CODEC_J2K
216
186
 
217
187
  self._validate_kwargs()
218
188
 
@@ -800,12 +770,6 @@ class Jp2k(Jp2kr):
800
770
  -------
801
771
  Jp2k
802
772
  Newly wrapped Jp2k object.
803
-
804
- Examples
805
- --------
806
- >>> jfile = glymur.data.goodstuff()
807
- >>> j2k = glymur.Jp2k(jfile)
808
- >>> jp2 = j2k.wrap('jp2_from_j2k.jp2')
809
773
  """
810
774
  if boxes is None:
811
775
  boxes = self._get_default_jp2_boxes()
@@ -55,6 +55,19 @@ class Jp2kr(Jp2kBox):
55
55
  >>> thumbnail = jp2[::2, ::2]
56
56
  >>> thumbnail.shape
57
57
  (728, 1296, 3)
58
+
59
+ Make use of OpenJPEG's thread support
60
+
61
+ >>> import time
62
+ >>> jp2file = glymur.data.nemo()
63
+ >>> jp2 = glymur.Jp2k(jp2file)
64
+ >>> t0 = time.time(); data = jp2[:]; t1 = time.time()
65
+ >>> t1 - t0 #doctest: +SKIP
66
+ 0.9024193286895752
67
+ >>> glymur.set_option('lib.num_threads', 4)
68
+ >>> t0 = time.time(); data = jp2[:]; t1 = time.time()
69
+ >>> t1 - t0 #doctest: +SKIP
70
+ 0.4060473537445068
58
71
  """
59
72
 
60
73
  def __init__(
@@ -233,7 +246,7 @@ class Jp2kr(Jp2kBox):
233
246
 
234
247
  @property
235
248
  def codestream(self):
236
- """Metadata for JP2 or J2K codestream (header only)."""
249
+ """Metadata for JP2 or J2K codestream header."""
237
250
  if self._codestream is None:
238
251
  self._codestream = self.get_codestream(header_only=True)
239
252
  return self._codestream
@@ -523,6 +536,9 @@ class Jp2kr(Jp2kBox):
523
536
  def read(self, **kwargs):
524
537
  """Read a JPEG 2000 image.
525
538
 
539
+ .. deprecated:: 0.13.5
540
+ Use numpy-style slicing instead.
541
+
526
542
  Returns
527
543
  -------
528
544
  img_array : ndarray
@@ -724,7 +740,7 @@ class Jp2kr(Jp2kBox):
724
740
  verbose=False, ignore_pclr_cmap_cdef=False):
725
741
  """Read a JPEG 2000 image.
726
742
 
727
- The only time you should use this method is when the image has
743
+ The only time you should ever use this method is when the image has
728
744
  different subsampling factors across components. Otherwise you should
729
745
  use the read method.
730
746
 
@@ -870,6 +886,10 @@ class Jp2kr(Jp2kBox):
870
886
  def get_codestream(self, header_only=True):
871
887
  """Retrieve codestream.
872
888
 
889
+ This differs from the codestream property in that segment
890
+ metadata that lies past the end of the codestream header
891
+ can be retrieved.
892
+
873
893
  Parameters
874
894
  ----------
875
895
  header_only : bool, optional
@@ -20,7 +20,7 @@ from .lib import tiff
20
20
 
21
21
  # Do not change the format of this next line! Doing so risks breaking
22
22
  # setup.py
23
- version = "0.13.3"
23
+ version = "0.13.5"
24
24
 
25
25
  version_tuple = parse(version).release
26
26
 
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = Glymur
3
- version = 0.13.3
3
+ version = 0.13.5
4
4
  author = 'John Evans'
5
5
  author_email = "John Evans" <jevans667cc@proton.me>
6
6
  license = 'MIT'
@@ -30,6 +30,19 @@ class TestSuite(fixtures.TestCommon):
30
30
  self.p1_06 = ir.files('tests.data').joinpath('p1_06.j2k')
31
31
  self.issue142 = ir.files('tests.data').joinpath('issue142.j2k')
32
32
  self.edf_c2_1178956 = ir.files('tests.data').joinpath('edf_c2_1178956.jp2') # noqa : E501
33
+ self.htj2k = ir.files('tests.data').joinpath('oj-ht-byte.jph')
34
+
35
+ def test_cap_marker_segment(self):
36
+ """
37
+ SCENARIO: the file has a CAP marker segment for the 3rd segment
38
+
39
+ EXPECTED RESULT: the segment metadata is verified
40
+ """
41
+ j = Jp2k(self.htj2k)
42
+ cap = j.codestream.segment[2]
43
+
44
+ self.assertEqual(cap.pcap, 131072)
45
+ self.assertEqual(cap.ccap, (3,))
33
46
 
34
47
  def test_unrecognized_marker(self):
35
48
  """
@@ -20,7 +20,7 @@ import numpy as np
20
20
 
21
21
  # Local imports ...
22
22
  import glymur
23
- from glymur import Jp2k
23
+ from glymur import Jp2k, Jp2kr
24
24
  from glymur.jp2box import (
25
25
  ColourSpecificationBox, ContiguousCodestreamBox, FileTypeBox,
26
26
  ImageHeaderBox, JP2HeaderBox, JPEG2000SignatureBox, BitsPerComponentBox,
@@ -356,6 +356,16 @@ class TestChannelDefinition(fixtures.TestCommon):
356
356
  class TestFileTypeBox(fixtures.TestCommon):
357
357
  """Test suite for ftyp box issues."""
358
358
 
359
+ def test_jph(self):
360
+ """
361
+ SCENARIO: JPH box
362
+
363
+ EXPECTED RESULT: The brand is verified.
364
+ """
365
+ path = ir.files('tests.data').joinpath('oj-ht-byte.jph')
366
+ j = Jp2kr(path)
367
+ self.assertEqual(j.box[1].brand, 'jph ')
368
+
359
369
  def test_bad_brand_on_parse(self):
360
370
  """
361
371
  SCENARIO: The JP2 file file type box does not contain a valid brand.
@@ -29,8 +29,8 @@ from . import fixtures
29
29
 
30
30
 
31
31
  @unittest.skipIf(OPENJPEG_NOT_AVAILABLE, OPENJPEG_NOT_AVAILABLE_MSG)
32
- @unittest.skipIf(glymur.version.openjpeg_version < '2.3.0',
33
- "Requires as least v2.3.0")
32
+ @unittest.skipIf(glymur.version.openjpeg_version < '2.4.0',
33
+ "Requires as least v2.4.0")
34
34
  class TestJp2k(fixtures.TestCommon):
35
35
  """These tests should be run by just about all configuration."""
36
36
 
@@ -38,6 +38,20 @@ class TestJp2k(fixtures.TestCommon):
38
38
  super().setUp()
39
39
  glymur.reset_option('all')
40
40
 
41
+ @unittest.skipIf(
42
+ glymur.version.openjpeg_version < '2.5.0', "Requires as least v2.5.0"
43
+ )
44
+ def test_read_htj2k(self):
45
+ """
46
+ Scenario: read an HTJ2K (JPH) file using Jp2k
47
+
48
+ Expected response: The size of the image read is verified.
49
+ """
50
+ path = ir.files('tests.data').joinpath('oj-ht-byte.jph')
51
+ j = Jp2k(path)
52
+ d = j[:]
53
+ self.assertEqual(d.shape, (20, 20))
54
+
41
55
  def test_repr(self):
42
56
  """
43
57
  Scenario: run repr on Jp2k object
@@ -29,8 +29,8 @@ from . import fixtures
29
29
 
30
30
 
31
31
  @unittest.skipIf(OPENJPEG_NOT_AVAILABLE, OPENJPEG_NOT_AVAILABLE_MSG)
32
- @unittest.skipIf(glymur.version.openjpeg_version < '2.3.0',
33
- "Requires as least v2.3.0")
32
+ @unittest.skipIf(glymur.version.openjpeg_version < '2.4.0',
33
+ "Requires as least v2.4.0")
34
34
  class TestJp2kr(fixtures.TestCommon):
35
35
  """These tests should be run by just about all configuration."""
36
36
 
@@ -42,6 +42,22 @@ class TestPrinting(fixtures.TestCommon):
42
42
  super().tearDown()
43
43
  glymur.reset_option('all')
44
44
 
45
+ def test_cap_segment(self):
46
+ """
47
+ Scenario: Print a CAP segment
48
+
49
+ Expected Result: segment is verified
50
+ """
51
+ htj2k_file = ir.files('tests.data').joinpath('oj-ht-byte.jph')
52
+ j = glymur.Jp2kr(htj2k_file)
53
+ actual = str(j.codestream.segment[2])
54
+ expected = (
55
+ 'CAP marker segment @ (467, 8)\n'
56
+ ' Pcap: Part 15 (ISO/IEC 15444-15)\n'
57
+ ' Ccap: (3,)'
58
+ )
59
+ self.assertEqual(actual, expected)
60
+
45
61
  def test_empty_file(self):
46
62
  """
47
63
  SCENARIO: Print the file after with object is constructed, but
@@ -1607,6 +1623,27 @@ class TestPrinting(fixtures.TestCommon):
1607
1623
  )
1608
1624
  self.assertEqual(actual, expected)
1609
1625
 
1626
+ def test_jph_rsiz(self):
1627
+ """
1628
+ Scenario: parse a JPH file, print the SIZ segment
1629
+
1630
+ Expected result: no warnings, the output is verified
1631
+ """
1632
+ path = ir.files('tests.data').joinpath('oj-ht-byte.jph')
1633
+
1634
+ with warnings.catch_warnings():
1635
+ warnings.simplefilter('error')
1636
+ j = Jp2k(path)
1637
+ actual = str(j.codestream.segment[1])
1638
+
1639
+ expected = (
1640
+ ir.files('tests.data')
1641
+ .joinpath('jph_siz.txt')
1642
+ .read_text()
1643
+ .rstrip()
1644
+ )
1645
+ self.assertEqual(actual, expected)
1646
+
1610
1647
 
1611
1648
  class TestJp2dump(fixtures.TestCommon):
1612
1649
  """Tests for verifying how jp2dump console script works."""
@@ -22,8 +22,8 @@ from . import fixtures
22
22
 
23
23
  @unittest.skipIf(os.cpu_count() < 2, "makes no sense if 2 cores not there")
24
24
  @unittest.skipIf(OPENJPEG_NOT_AVAILABLE, OPENJPEG_NOT_AVAILABLE_MSG)
25
- @unittest.skipIf(glymur.version.openjpeg_version < '2.3.0',
26
- "Requires as least v2.3.0")
25
+ @unittest.skipIf(glymur.version.openjpeg_version < '2.4.0',
26
+ "Requires as least v2.4.0")
27
27
  class TestSuite(fixtures.TestCommon):
28
28
  """Test behavior when multiple threads are possible."""
29
29
 
@@ -79,7 +79,7 @@ class TestSuite(fixtures.TestCommon):
79
79
  glymur.set_option('lib.num_threads', 2)
80
80
 
81
81
  @unittest.skipIf(
82
- glymur.version.openjpeg_version < '2.4.0', "Requires as least v2.3.0"
82
+ glymur.version.openjpeg_version < '2.4.0', "Requires as least v2.4.0"
83
83
  )
84
84
  def test_threads_write_support__ge_2p4(self):
85
85
  """
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes