Glymur 0.13.0__tar.gz → 0.13.1__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.0 → glymur-0.13.1}/CHANGES.txt +4 -0
  2. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/PKG-INFO +1 -1
  3. {glymur-0.13.0 → glymur-0.13.1}/PKG-INFO +1 -1
  4. {glymur-0.13.0 → glymur-0.13.1}/glymur/jp2box.py +0 -3
  5. {glymur-0.13.0 → glymur-0.13.1}/glymur/jp2kr.py +0 -56
  6. {glymur-0.13.0 → glymur-0.13.1}/glymur/lib/tiff.py +0 -18
  7. {glymur-0.13.0 → glymur-0.13.1}/glymur/version.py +1 -1
  8. {glymur-0.13.0 → glymur-0.13.1}/setup.cfg +1 -1
  9. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2k.py +9 -0
  10. {glymur-0.13.0 → glymur-0.13.1}/tests/test_libtiff.py +45 -0
  11. {glymur-0.13.0 → glymur-0.13.1}/tests/test_printing.py +62 -1
  12. {glymur-0.13.0 → glymur-0.13.1}/tests/test_set_decoded_components.py +1 -0
  13. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/SOURCES.txt +0 -0
  14. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/dependency_links.txt +0 -0
  15. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/entry_points.txt +0 -0
  16. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/not-zip-safe +0 -0
  17. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/requires.txt +0 -0
  18. {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/top_level.txt +0 -0
  19. {glymur-0.13.0 → glymur-0.13.1}/LICENSE.txt +0 -0
  20. {glymur-0.13.0 → glymur-0.13.1}/MANIFEST.in +0 -0
  21. {glymur-0.13.0 → glymur-0.13.1}/README.md +0 -0
  22. {glymur-0.13.0 → glymur-0.13.1}/glymur/__init__.py +0 -0
  23. {glymur-0.13.0 → glymur-0.13.1}/glymur/_iccprofile.py +0 -0
  24. {glymur-0.13.0 → glymur-0.13.1}/glymur/codestream.py +0 -0
  25. {glymur-0.13.0 → glymur-0.13.1}/glymur/command_line.py +0 -0
  26. {glymur-0.13.0 → glymur-0.13.1}/glymur/config.py +0 -0
  27. {glymur-0.13.0 → glymur-0.13.1}/glymur/core.py +0 -0
  28. {glymur-0.13.0 → glymur-0.13.1}/glymur/data/__init__.py +0 -0
  29. {glymur-0.13.0 → glymur-0.13.1}/glymur/data/goodstuff.j2k +0 -0
  30. {glymur-0.13.0 → glymur-0.13.1}/glymur/data/heliov.jpx +0 -0
  31. {glymur-0.13.0 → glymur-0.13.1}/glymur/data/nemo.jp2 +0 -0
  32. {glymur-0.13.0 → glymur-0.13.1}/glymur/jp2k.py +0 -0
  33. {glymur-0.13.0 → glymur-0.13.1}/glymur/lib/__init__.py +0 -0
  34. {glymur-0.13.0 → glymur-0.13.1}/glymur/lib/openjp2.py +0 -0
  35. {glymur-0.13.0 → glymur-0.13.1}/glymur/options.py +0 -0
  36. {glymur-0.13.0 → glymur-0.13.1}/glymur/tiff.py +0 -0
  37. {glymur-0.13.0 → glymur-0.13.1}/pyproject.toml +0 -0
  38. {glymur-0.13.0 → glymur-0.13.1}/tests/test_callbacks.py +0 -0
  39. {glymur-0.13.0 → glymur-0.13.1}/tests/test_cinema.py +0 -0
  40. {glymur-0.13.0 → glymur-0.13.1}/tests/test_codestream.py +0 -0
  41. {glymur-0.13.0 → glymur-0.13.1}/tests/test_colour_specification_box.py +0 -0
  42. {glymur-0.13.0 → glymur-0.13.1}/tests/test_config.py +0 -0
  43. {glymur-0.13.0 → glymur-0.13.1}/tests/test_geo.py +0 -0
  44. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box.py +0 -0
  45. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box_jpx.py +0 -0
  46. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box_uuid.py +0 -0
  47. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box_xml.py +0 -0
  48. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2k_writes.py +0 -0
  49. {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2kr.py +0 -0
  50. {glymur-0.13.0 → glymur-0.13.1}/tests/test_openjp2.py +0 -0
  51. {glymur-0.13.0 → glymur-0.13.1}/tests/test_slicing.py +0 -0
  52. {glymur-0.13.0 → glymur-0.13.1}/tests/test_threading.py +0 -0
  53. {glymur-0.13.0 → glymur-0.13.1}/tests/test_tiff2jp2.py +0 -0
  54. {glymur-0.13.0 → glymur-0.13.1}/tests/test_warnings.py +0 -0
@@ -1,3 +1,7 @@
1
+ Apr 22, 2024 - v0.13.1
2
+ Remove debugging code
3
+ Improve code coverage
4
+
1
5
  Apr 19, 2024 - v0.13.0
2
6
  Refactor Jp2k class into Jp2k, Jp2kr
3
7
  Simplify example file nemo.jp2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Glymur
3
- Version: 0.13.0
3
+ Version: 0.13.1
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.0
3
+ Version: 0.13.1
4
4
  Home-page: https://github.com/quintusdias/glymur
5
5
  Author: 'John Evans'
6
6
  Author-email: "John Evans" <jevans667cc@proton.me>
@@ -179,9 +179,6 @@ class Jp2kBox(object):
179
179
  Jp2kBox
180
180
  Object corresponding to the current box.
181
181
  """
182
- if fptr.tell() == 1392953:
183
- # breakpoint()
184
- pass
185
182
  try:
186
183
  parser = _BOX_WITH_ID[box_id].parse
187
184
 
@@ -915,62 +915,6 @@ class Jp2kr(Jp2kBox):
915
915
 
916
916
  return codestream
917
917
 
918
- def _populate_image_struct(
919
- self, image, imgdata, tile_x_factor=1, tile_y_factor=1
920
- ):
921
- """Populates image struct needed for compression.
922
-
923
- Parameters
924
- ----------
925
- image : ImageType(ctypes.Structure)
926
- Corresponds to image_t type in openjp2 headers.
927
- imgdata : ndarray
928
- Image data to be written to file.
929
- tile_x_factor, tile_y_factor: int
930
- Used only when writing tile-by-tile. In this case, the image data
931
- that we have is only the size of a single tile.
932
- """
933
-
934
- if len(self.shape) < 3:
935
- (numrows, numcols), num_comps = self.shape, 1
936
- else:
937
- numrows, numcols, num_comps = self.shape
938
-
939
- for k in range(num_comps):
940
- self._validate_nonzero_image_size(numrows, numcols, k)
941
-
942
- # set image offset and reference grid
943
- image.contents.x0 = self._cparams.image_offset_x0
944
- image.contents.y0 = self._cparams.image_offset_y0
945
- image.contents.x1 = (
946
- image.contents.x0
947
- + (numcols - 1) * self._cparams.subsampling_dx * tile_x_factor
948
- + 1
949
- )
950
- image.contents.y1 = (
951
- image.contents.y0
952
- + (numrows - 1) * self._cparams.subsampling_dy * tile_y_factor
953
- + 1
954
- )
955
-
956
- if tile_x_factor != 1 or tile_y_factor != 1:
957
- # don't stage the data if writing tiles
958
- return image
959
-
960
- # Stage the image data to the openjpeg data structure.
961
- for k in range(0, num_comps):
962
- if self._cparams.rsiz in (core.OPJ_PROFILE_CINEMA_2K,
963
- core.OPJ_PROFILE_CINEMA_4K):
964
- image.contents.comps[k].prec = 12
965
- image.contents.comps[k].bpp = 12
966
-
967
- layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32)
968
- dest = image.contents.comps[k].data
969
- src = layer.ctypes.data
970
- ctypes.memmove(dest, src, layer.nbytes)
971
-
972
- return image
973
-
974
918
  def _validate_nonzero_image_size(self, nrows, ncols, component_index):
975
919
  """The image cannot have area of zero."""
976
920
  if nrows == 0 or ncols == 0:
@@ -552,24 +552,6 @@ def getVersion():
552
552
  return m.group('version')
553
553
 
554
554
 
555
- def printDirectory(tiff_fp, ofp, mode=0):
556
- """Corresponds to TIFFPrintDirectory
557
-
558
- Parameters
559
- ----------
560
- filename : path or str
561
- Path to TIFF
562
- """
563
- err_handler, warn_handler = _set_error_warning_handlers()
564
-
565
- ARGTYPES = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_long]
566
- _LIBTIFF.TIFFPrintDirectory.argtypes = ARGTYPES
567
- _LIBTIFF.TIFFPrintDirectory.restype = ctypes.c_void_p
568
- _LIBTIFF.TIFFPrintDirectory(tiff_fp, ofp, mode)
569
-
570
- _reset_error_warning_handlers(err_handler, warn_handler)
571
-
572
-
573
555
  def open(filename, mode='r'):
574
556
  """Corresponds to TIFFOpen
575
557
 
@@ -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.0"
23
+ version = "0.13.1"
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.0
3
+ version = 0.13.1
4
4
  author = 'John Evans'
5
5
  author_email = "John Evans" <jevans667cc@proton.me>
6
6
  license = 'MIT'
@@ -57,6 +57,15 @@ class TestJp2k(fixtures.TestCommon):
57
57
  super().setUp()
58
58
  glymur.reset_option('all')
59
59
 
60
+ def test_repr(self):
61
+ """
62
+ Scenario: run repr on Jp2k object
63
+
64
+ Expected response: the representation is verified
65
+ """
66
+ j = Jp2k(self.j2kfile)
67
+ self.assertRegex(repr(j), 'glymur.Jp2k(.*?)')
68
+
60
69
  def test_write_using_slicing(self):
61
70
  """
62
71
  Scenario: write to a file using slicing then read it back
@@ -79,3 +79,48 @@ class TestSuite(fixtures.TestCommon):
79
79
  self.assertEqual(actual_tw, tw)
80
80
 
81
81
  libtiff.close(fp)
82
+
83
+ def test_simple_strip(self):
84
+ """
85
+ SCENARIO: create a simple monochromatic 2 strip image
86
+
87
+ Expected result: The image matches. The number of tiles checks out.
88
+ The tile width and height checks out.
89
+ """
90
+ data = fixtures.skimage.data.moon()
91
+ h, w = data.shape
92
+ rps = h // 2
93
+
94
+ fp = libtiff.open(self.temp_tiff_filename, mode='w')
95
+
96
+ libtiff.setField(fp, 'Photometric', libtiff.Photometric.MINISBLACK)
97
+ libtiff.setField(fp, 'Compression', libtiff.Compression.ADOBE_DEFLATE)
98
+ libtiff.setField(fp, 'ImageLength', data.shape[0])
99
+ libtiff.setField(fp, 'ImageWidth', data.shape[1])
100
+ libtiff.setField(fp, 'RowsPerStrip', rps)
101
+ libtiff.setField(fp, 'BitsPerSample', 8)
102
+ libtiff.setField(fp, 'SamplesPerPixel', 1)
103
+ libtiff.setField(fp, 'PlanarConfig', libtiff.PlanarConfig.CONTIG)
104
+
105
+ libtiff.writeEncodedStrip(fp, 0, data[:rps, :].copy())
106
+ libtiff.writeEncodedStrip(fp, 1, data[rps:h, :].copy())
107
+
108
+ libtiff.close(fp)
109
+
110
+ fp = libtiff.open(self.temp_tiff_filename)
111
+
112
+ strip = np.zeros((rps, w), dtype=np.uint8)
113
+ actual_data = np.zeros((h, w), dtype=np.uint8)
114
+
115
+ libtiff.readEncodedStrip(fp, 0, strip)
116
+ actual_data[:rps, :] = strip
117
+
118
+ libtiff.readEncodedStrip(fp, 1, strip)
119
+ actual_data[rps:h, :] = strip
120
+
121
+ np.testing.assert_array_equal(data, actual_data)
122
+
123
+ n = libtiff.numberOfStrips(fp)
124
+ self.assertEqual(n, 2)
125
+
126
+ libtiff.close(fp)
@@ -21,7 +21,7 @@ import glymur
21
21
  from glymur.codestream import LRCP, WAVELET_XFORM_5X3_REVERSIBLE
22
22
  from glymur.core import COLOR, RED, GREEN, BLUE, RESTRICTED_ICC_PROFILE
23
23
  from glymur.jp2box import BitsPerComponentBox, ColourSpecificationBox
24
- from glymur.jp2box import LabelBox
24
+ from glymur.jp2box import LabelBox, UUIDBox
25
25
  from glymur import Jp2k, command_line
26
26
  from glymur.lib import openjp2 as opj2
27
27
  from . import fixtures
@@ -1849,3 +1849,64 @@ class TestJp2dump(fixtures.TestCommon):
1849
1849
  ''' alpha: 0\n'''
1850
1850
  )
1851
1851
  self.assertRegex(actual, expected)
1852
+
1853
+ def test_xmp_uuid_short(self):
1854
+ """
1855
+ SCENARIO: Append an XMP UUID box to an existing JP2 file, print it
1856
+ with the short option.
1857
+
1858
+ EXPECTED RESULT: strings are validated
1859
+ """
1860
+ the_uuid = UUID('be7acfcb-97a9-42e8-9c71-999491e3afac')
1861
+ raw_data = (
1862
+ ir.files('tests.data')
1863
+ .joinpath('simple_rdf.txt')
1864
+ .read_text()
1865
+ .encode('utf-8')
1866
+ )
1867
+
1868
+ shutil.copyfile(self.jp2file, self.temp_jp2_filename)
1869
+
1870
+ jp2 = Jp2k(self.temp_jp2_filename)
1871
+ ubox = glymur.jp2box.UUIDBox(the_uuid=the_uuid, raw_data=raw_data)
1872
+ jp2.append(ubox)
1873
+
1874
+ glymur.set_option('print.short', True)
1875
+
1876
+ actual = str(jp2.box[-1])
1877
+ expected = 'UUID Box (uuid) @ (1132373, 434)'
1878
+
1879
+ self.assertEqual(actual, expected)
1880
+
1881
+ # now invoke print.xml, answer should be nearly the same.
1882
+ glymur.reset_option('all')
1883
+ glymur.set_option('print.xml', False)
1884
+
1885
+ actual = str(jp2.box[-1])
1886
+ expected = 'UUID Box (uuid) @ (1132373, 434)\n UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)' # noqa : E501
1887
+
1888
+ self.assertEqual(actual, expected)
1889
+
1890
+ def test__print_malformed_exif_uuid(self):
1891
+ """
1892
+ SCENARIO: Parse a JpgTiffExif->Jp2 UUID that is not only missing the
1893
+ 'EXIF\0\0' lead-in, but even the TIFF header is malformed. Then print
1894
+ it.
1895
+
1896
+ EXPECTED RESULT: a UUIDBox string showing that it is invalid
1897
+ """
1898
+ box_data = ir.files('tests.data').joinpath('issue549.dat').read_bytes()
1899
+ bf = BytesIO(box_data[:16] + box_data[20:])
1900
+ with warnings.catch_warnings():
1901
+ warnings.simplefilter("ignore")
1902
+ box = UUIDBox.parse(bf, 0, 37700)
1903
+
1904
+ actual = str(box)
1905
+ expected = [
1906
+ "UUID Box (uuid) @ (0, 37700)",
1907
+ " UUID: 4a706754-6966-6645-7869-662d3e4a5032 (EXIF)",
1908
+ " UUID Data: Invalid Exif UUID",
1909
+ ]
1910
+ expected = '\n'.join(expected)
1911
+
1912
+ self.assertEqual(actual, expected)
@@ -50,6 +50,7 @@ class TestSuite(unittest.TestCase):
50
50
  j2k.decoded_components = 0
51
51
  actual = j2k[:]
52
52
 
53
+ self.assertEqual(j2k.decoded_components, [0])
53
54
  np.testing.assert_array_equal(actual, expected)
54
55
 
55
56
  # restore the original configuration
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
File without changes
File without changes
File without changes