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.
- {glymur-0.13.0 → glymur-0.13.1}/CHANGES.txt +4 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/PKG-INFO +1 -1
- {glymur-0.13.0 → glymur-0.13.1}/PKG-INFO +1 -1
- {glymur-0.13.0 → glymur-0.13.1}/glymur/jp2box.py +0 -3
- {glymur-0.13.0 → glymur-0.13.1}/glymur/jp2kr.py +0 -56
- {glymur-0.13.0 → glymur-0.13.1}/glymur/lib/tiff.py +0 -18
- {glymur-0.13.0 → glymur-0.13.1}/glymur/version.py +1 -1
- {glymur-0.13.0 → glymur-0.13.1}/setup.cfg +1 -1
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2k.py +9 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_libtiff.py +45 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_printing.py +62 -1
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_set_decoded_components.py +1 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/SOURCES.txt +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/dependency_links.txt +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/entry_points.txt +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/not-zip-safe +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/requires.txt +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/Glymur.egg-info/top_level.txt +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/LICENSE.txt +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/MANIFEST.in +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/README.md +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/__init__.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/_iccprofile.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/codestream.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/command_line.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/config.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/core.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/data/__init__.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/data/goodstuff.j2k +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/data/heliov.jpx +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/data/nemo.jp2 +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/jp2k.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/lib/__init__.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/lib/openjp2.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/options.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/glymur/tiff.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/pyproject.toml +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_callbacks.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_cinema.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_codestream.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_colour_specification_box.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_config.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_geo.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box_jpx.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box_uuid.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2box_xml.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2k_writes.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_jp2kr.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_openjp2.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_slicing.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_threading.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_tiff2jp2.py +0 -0
- {glymur-0.13.0 → glymur-0.13.1}/tests/test_warnings.py +0 -0
|
@@ -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
|
|
|
@@ -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)
|
|
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
|
|
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
|