Glymur 0.13.1__tar.gz → 0.13.2.post1__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.1 → glymur-0.13.2.post1}/CHANGES.txt +11 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/PKG-INFO +1 -2
- {glymur-0.13.1 → glymur-0.13.2.post1}/PKG-INFO +1 -2
- {glymur-0.13.1 → glymur-0.13.2.post1}/README.md +1 -1
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/codestream.py +10 -10
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/config.py +3 -12
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/data/__init__.py +4 -14
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/jp2box.py +4 -8
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/jp2k.py +5 -9
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/jp2kr.py +3 -8
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/lib/openjp2.py +6 -7
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/lib/tiff.py +34 -38
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/options.py +5 -82
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/tiff.py +0 -14
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/version.py +1 -1
- {glymur-0.13.1 → glymur-0.13.2.post1}/pyproject.toml +0 -1
- {glymur-0.13.1 → glymur-0.13.2.post1}/setup.cfg +1 -2
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_config.py +57 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_geo.py +5 -1
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2box.py +19 -7
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2k.py +10 -24
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2k_writes.py +64 -24
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2kr.py +18 -24
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_libtiff.py +91 -1
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_printing.py +4 -6
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_threading.py +54 -2
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_tiff2jp2.py +23 -32
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/SOURCES.txt +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/dependency_links.txt +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/entry_points.txt +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/not-zip-safe +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/requires.txt +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/Glymur.egg-info/top_level.txt +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/LICENSE.txt +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/MANIFEST.in +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/__init__.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/_iccprofile.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/command_line.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/core.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/data/goodstuff.j2k +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/data/heliov.jpx +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/data/nemo.jp2 +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/glymur/lib/__init__.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_callbacks.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_cinema.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_codestream.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_colour_specification_box.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2box_jpx.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2box_uuid.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_jp2box_xml.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_openjp2.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_set_decoded_components.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_slicing.py +0 -0
- {glymur-0.13.1 → glymur-0.13.2.post1}/tests/test_warnings.py +0 -0
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
May 07, 2024 - v0.13.2.post1
|
|
2
|
+
Fix big endian test issue
|
|
3
|
+
|
|
4
|
+
May 07, 2024 - v0.13.2
|
|
5
|
+
Improve doctesting, fix broken libtiff doctest
|
|
6
|
+
Increase code coverage
|
|
7
|
+
Remove python 3.8 anachronisms
|
|
8
|
+
Fix repr for Jp2kr
|
|
9
|
+
Clean up ci directory
|
|
10
|
+
Change parsing of precinct sizes due to numpy 2.0
|
|
11
|
+
|
|
1
12
|
Apr 22, 2024 - v0.13.1
|
|
2
13
|
Remove debugging code
|
|
3
14
|
Improve code coverage
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Glymur
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2.post1
|
|
4
4
|
Home-page: https://github.com/quintusdias/glymur
|
|
5
5
|
Author: 'John Evans'
|
|
6
6
|
Author-email: "John Evans" <jevans667cc@proton.me>
|
|
7
7
|
License: 'MIT'
|
|
8
8
|
Classifier: Programming Language :: Python
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Glymur
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2.post1
|
|
4
4
|
Home-page: https://github.com/quintusdias/glymur
|
|
5
5
|
Author: 'John Evans'
|
|
6
6
|
Author-email: "John Evans" <jevans667cc@proton.me>
|
|
7
7
|
License: 'MIT'
|
|
8
8
|
Classifier: Programming Language :: Python
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -3,6 +3,6 @@ glymur: a Python interface for JPEG 2000
|
|
|
3
3
|
|
|
4
4
|
**glymur** contains a Python interface to the OpenJPEG library which
|
|
5
5
|
allows one to read and write JPEG 2000 files. **glymur** works on
|
|
6
|
-
Python 3.
|
|
6
|
+
Python 3.9, 3.10, 3.11, and 3.12.
|
|
7
7
|
|
|
8
8
|
Please read the docs, https://glymur.readthedocs.org/en/latest/
|
|
@@ -951,8 +951,8 @@ class COCsegment(Segment):
|
|
|
951
951
|
Coding style for this component.
|
|
952
952
|
spcoc : byte array
|
|
953
953
|
Coding style parameters for this component.
|
|
954
|
-
precinct_size :
|
|
955
|
-
Dimensions of
|
|
954
|
+
precinct_size : nx2 array
|
|
955
|
+
Dimensions of precincts.
|
|
956
956
|
|
|
957
957
|
References
|
|
958
958
|
----------
|
|
@@ -971,7 +971,7 @@ class COCsegment(Segment):
|
|
|
971
971
|
if len(self.spcoc) > 5:
|
|
972
972
|
self.precinct_size = _parse_precinct_size(self.spcoc[5:])
|
|
973
973
|
else:
|
|
974
|
-
self.precinct_size = ((32768, 32768))
|
|
974
|
+
self.precinct_size = np.array(((32768, 32768)))
|
|
975
975
|
|
|
976
976
|
self.length = length
|
|
977
977
|
self.offset = offset
|
|
@@ -993,7 +993,7 @@ class COCsegment(Segment):
|
|
|
993
993
|
f' Number of decomposition levels: {self.spcoc[0]}\n'
|
|
994
994
|
f' Code block height, width: ({width} x {height})\n'
|
|
995
995
|
f' Wavelet transform: {xform}\n'
|
|
996
|
-
f' Precinct size: {self.precinct_size}\n'
|
|
996
|
+
f' Precinct size: {self.precinct_size.tolist()}\n'
|
|
997
997
|
f' {_context_string(self.spcoc[3])}'
|
|
998
998
|
)
|
|
999
999
|
|
|
@@ -1028,8 +1028,8 @@ class CODsegment(Segment):
|
|
|
1028
1028
|
Wavelet transform used
|
|
1029
1029
|
cstyle : int
|
|
1030
1030
|
Style of the code-block passes
|
|
1031
|
-
precinct_size :
|
|
1032
|
-
|
|
1031
|
+
precinct_size : nx2 array
|
|
1032
|
+
Array of precinct sizes.
|
|
1033
1033
|
|
|
1034
1034
|
References
|
|
1035
1035
|
----------
|
|
@@ -1071,9 +1071,9 @@ class CODsegment(Segment):
|
|
|
1071
1071
|
self.code_block_size = 4 * 2 ** ycb, 4 * 2 ** xcb
|
|
1072
1072
|
|
|
1073
1073
|
if precinct_size is None:
|
|
1074
|
-
self.precinct_size = ((2 ** 15, 2 ** 15))
|
|
1074
|
+
self.precinct_size = np.array(((2 ** 15, 2 ** 15)))
|
|
1075
1075
|
else:
|
|
1076
|
-
self.precinct_size = precinct_size
|
|
1076
|
+
self.precinct_size = np.array(precinct_size)
|
|
1077
1077
|
|
|
1078
1078
|
def __str__(self):
|
|
1079
1079
|
msg = Segment.__str__(self)
|
|
@@ -1123,7 +1123,7 @@ class CODsegment(Segment):
|
|
|
1123
1123
|
cbh=int(self.code_block_size[0]),
|
|
1124
1124
|
cbw=int(self.code_block_size[1]),
|
|
1125
1125
|
xform=xform,
|
|
1126
|
-
precinct_size=self.precinct_size,
|
|
1126
|
+
precinct_size=self.precinct_size.tolist(),
|
|
1127
1127
|
code_block_context=_context_string(self.cstyle)
|
|
1128
1128
|
)
|
|
1129
1129
|
|
|
@@ -1898,7 +1898,7 @@ def _parse_precinct_size(spcod):
|
|
|
1898
1898
|
ep2 = (item & 0xF0) >> 4
|
|
1899
1899
|
ep1 = item & 0x0F
|
|
1900
1900
|
precinct_size.append((2 ** ep1, 2 ** ep2))
|
|
1901
|
-
return
|
|
1901
|
+
return np.array(precinct_size)
|
|
1902
1902
|
|
|
1903
1903
|
|
|
1904
1904
|
def _context_string(context):
|
|
@@ -57,13 +57,9 @@ def _determine_full_path(libname):
|
|
|
57
57
|
if platform.system().startswith('CYGWIN'):
|
|
58
58
|
g = pathlib.Path('/usr/bin').glob('cygopenjp2*.dll')
|
|
59
59
|
try:
|
|
60
|
-
|
|
60
|
+
return list(g)[0]
|
|
61
61
|
except IndexError:
|
|
62
|
-
|
|
63
|
-
pass
|
|
64
|
-
else:
|
|
65
|
-
if path.exists():
|
|
66
|
-
return path
|
|
62
|
+
return None
|
|
67
63
|
|
|
68
64
|
# No joy on config file and not Cygwin. Can ctypes find it anyway?
|
|
69
65
|
path = find_library(libname)
|
|
@@ -132,12 +128,7 @@ def glymur_config(libname):
|
|
|
132
128
|
|
|
133
129
|
loader = ctypes.windll.LoadLibrary if os.name == 'nt' else ctypes.CDLL
|
|
134
130
|
try:
|
|
135
|
-
opj_lib = loader(path)
|
|
136
|
-
except TypeError:
|
|
137
|
-
# This can happen on Windows. Apparently ctypes.windll.LoadLibrary
|
|
138
|
-
# is no longer taking a WindowsPath
|
|
139
|
-
path = str(path)
|
|
140
|
-
opj_lib = loader(path)
|
|
131
|
+
opj_lib = loader(str(path))
|
|
141
132
|
except OSError:
|
|
142
133
|
msg = f'The {libname} library at {path} could not be loaded.'
|
|
143
134
|
warnings.warn(msg, UserWarning)
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
These include:
|
|
4
4
|
nemo.jp2: converted from the original JPEG photo of the aftermath of NEMO,
|
|
5
5
|
the nor'easter that shutdown Boston in February of 2013.
|
|
6
|
-
goodstuff.j2k: my favorite
|
|
6
|
+
goodstuff.j2k: my favorite beverage.
|
|
7
7
|
|
|
8
8
|
"""
|
|
9
9
|
import importlib.resources as ir
|
|
10
|
-
import sys
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
def nemo():
|
|
@@ -18,7 +17,7 @@ def nemo():
|
|
|
18
17
|
file : str
|
|
19
18
|
Platform-independent path to nemo.jp2.
|
|
20
19
|
"""
|
|
21
|
-
return
|
|
20
|
+
return str(ir.files('glymur.data').joinpath('nemo.jp2'))
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
def goodstuff():
|
|
@@ -29,7 +28,7 @@ def goodstuff():
|
|
|
29
28
|
file : str
|
|
30
29
|
Platform-independent path to goodstuff.j2k.
|
|
31
30
|
"""
|
|
32
|
-
return
|
|
31
|
+
return str(ir.files('glymur.data').joinpath('goodstuff.j2k'))
|
|
33
32
|
|
|
34
33
|
|
|
35
34
|
def jpxfile():
|
|
@@ -40,13 +39,4 @@ def jpxfile():
|
|
|
40
39
|
file : str
|
|
41
40
|
Platform-independent path to heliov.jpx
|
|
42
41
|
"""
|
|
43
|
-
return
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def _str_path_to(filename):
|
|
47
|
-
"""Hide differences between 3.9.0 and below."""
|
|
48
|
-
if sys.version_info[1] >= 9:
|
|
49
|
-
return str(ir.files('glymur.data').joinpath(filename))
|
|
50
|
-
else:
|
|
51
|
-
with ir.path('glymur.data', filename) as path:
|
|
52
|
-
return str(path)
|
|
42
|
+
return str(ir.files('glymur.data').joinpath('heliov.jpx'))
|
|
@@ -28,7 +28,7 @@ import warnings
|
|
|
28
28
|
try:
|
|
29
29
|
from osgeo import gdal
|
|
30
30
|
_HAVE_GDAL = True
|
|
31
|
-
except (ImportError, ModuleNotFoundError):
|
|
31
|
+
except (ImportError, ModuleNotFoundError): # pragma: no cover
|
|
32
32
|
_HAVE_GDAL = False
|
|
33
33
|
else:
|
|
34
34
|
gdal.UseExceptions()
|
|
@@ -1675,7 +1675,6 @@ class ImageHeaderBox(Jp2kBox):
|
|
|
1675
1675
|
):
|
|
1676
1676
|
"""Examples
|
|
1677
1677
|
--------
|
|
1678
|
-
>>> import glymur
|
|
1679
1678
|
>>> box = glymur.jp2box.ImageHeaderBox(height=512, width=256)
|
|
1680
1679
|
"""
|
|
1681
1680
|
super().__init__()
|
|
@@ -3510,11 +3509,8 @@ class UUIDBox(Jp2kBox):
|
|
|
3510
3509
|
lst.append(text)
|
|
3511
3510
|
elif self.uuid == _GEOTIFF_UUID:
|
|
3512
3511
|
|
|
3513
|
-
if self.data is None:
|
|
3514
|
-
return 'UUID Data: corrupt'
|
|
3515
|
-
|
|
3516
3512
|
options = gdal.InfoOptions(showColorTable=False)
|
|
3517
|
-
txt = gdal.Info(self.
|
|
3513
|
+
txt = gdal.Info(self._fptr.name, options=options)
|
|
3518
3514
|
txt = textwrap.indent(txt, ' ' * 4).rstrip()
|
|
3519
3515
|
|
|
3520
3516
|
txt = f'UUID Data:\n{txt}'
|
|
@@ -3559,7 +3555,7 @@ class UUIDBox(Jp2kBox):
|
|
|
3559
3555
|
the_uuid = UUID(bytes=read_buffer[0:16])
|
|
3560
3556
|
|
|
3561
3557
|
o = cls(the_uuid, read_buffer[16:], length=length, offset=offset)
|
|
3562
|
-
o.
|
|
3558
|
+
o._fptr = fptr
|
|
3563
3559
|
|
|
3564
3560
|
return o
|
|
3565
3561
|
|
|
@@ -3608,7 +3604,7 @@ def decompose_resolution(value: Number) -> Tuple[int, int, int]:
|
|
|
3608
3604
|
value:
|
|
3609
3605
|
A number to be represented as a fraction.
|
|
3610
3606
|
Returns:
|
|
3611
|
-
A tuple of the form (numerator, denominator
|
|
3607
|
+
A tuple of the form (exponent, numerator, denominator).
|
|
3612
3608
|
"""
|
|
3613
3609
|
frac = Fraction(value)
|
|
3614
3610
|
max_allowed_frac = Fraction(2**15 - 1)
|
|
@@ -107,7 +107,6 @@ class Jp2k(Jp2kr):
|
|
|
107
107
|
|
|
108
108
|
Examples
|
|
109
109
|
--------
|
|
110
|
-
>>> import glymur
|
|
111
110
|
>>> jfile = glymur.data.nemo()
|
|
112
111
|
>>> jp2 = glymur.Jp2k(jfile)
|
|
113
112
|
>>> jp2.shape
|
|
@@ -124,7 +123,6 @@ class Jp2k(Jp2kr):
|
|
|
124
123
|
|
|
125
124
|
Make use of OpenJPEG's thread support
|
|
126
125
|
|
|
127
|
-
>>> import glymur
|
|
128
126
|
>>> import time
|
|
129
127
|
>>> if glymur.version.openjpeg_version >= '2.2.0':
|
|
130
128
|
... jp2file = glymur.data.nemo()
|
|
@@ -229,6 +227,10 @@ class Jp2k(Jp2kr):
|
|
|
229
227
|
# contained in memory.
|
|
230
228
|
self[:] = data
|
|
231
229
|
|
|
230
|
+
def __repr__(self):
|
|
231
|
+
msg = f"glymur.Jp2k('{self.path}')"
|
|
232
|
+
return msg
|
|
233
|
+
|
|
232
234
|
def finalize(self, force_parse=False):
|
|
233
235
|
"""For now, the only remaining tasks are to possibly parse the file
|
|
234
236
|
and to possibly write out a ResolutionBox. There could be other
|
|
@@ -351,10 +353,6 @@ class Jp2k(Jp2kr):
|
|
|
351
353
|
)
|
|
352
354
|
raise RuntimeError(msg)
|
|
353
355
|
|
|
354
|
-
def __repr__(self):
|
|
355
|
-
msg = f"glymur.Jp2k('{self.path}')"
|
|
356
|
-
return msg
|
|
357
|
-
|
|
358
356
|
def get_tilewriters(self):
|
|
359
357
|
"""Return an object that facilitates writing tile by tile."""
|
|
360
358
|
|
|
@@ -805,11 +803,9 @@ class Jp2k(Jp2kr):
|
|
|
805
803
|
|
|
806
804
|
Examples
|
|
807
805
|
--------
|
|
808
|
-
>>> import glymur, tempfile
|
|
809
806
|
>>> jfile = glymur.data.goodstuff()
|
|
810
807
|
>>> j2k = glymur.Jp2k(jfile)
|
|
811
|
-
>>>
|
|
812
|
-
>>> jp2 = j2k.wrap(tfile.name)
|
|
808
|
+
>>> jp2 = j2k.wrap('jp2_from_j2k.jp2')
|
|
813
809
|
"""
|
|
814
810
|
if boxes is None:
|
|
815
811
|
boxes = self._get_default_jp2_boxes()
|
|
@@ -42,7 +42,6 @@ class Jp2kr(Jp2kBox):
|
|
|
42
42
|
|
|
43
43
|
Examples
|
|
44
44
|
--------
|
|
45
|
-
>>> import glymur
|
|
46
45
|
>>> jfile = glymur.data.nemo()
|
|
47
46
|
>>> jp2 = glymur.Jp2kr(jfile)
|
|
48
47
|
>>> jp2.shape
|
|
@@ -265,7 +264,7 @@ class Jp2kr(Jp2kBox):
|
|
|
265
264
|
self._shape = shape
|
|
266
265
|
|
|
267
266
|
def __repr__(self):
|
|
268
|
-
msg = f"glymur.
|
|
267
|
+
msg = f"glymur.Jp2kr('{self.path}')"
|
|
269
268
|
return msg
|
|
270
269
|
|
|
271
270
|
def __str__(self):
|
|
@@ -277,6 +276,7 @@ class Jp2kr(Jp2kBox):
|
|
|
277
276
|
# No codestream either. Empty file? We are done.
|
|
278
277
|
return metadata[0]
|
|
279
278
|
else:
|
|
279
|
+
# Just a codestream, so J2K
|
|
280
280
|
metadata.append(str(self.codestream))
|
|
281
281
|
return '\n'.join(metadata)
|
|
282
282
|
|
|
@@ -419,9 +419,6 @@ class Jp2kr(Jp2kBox):
|
|
|
419
419
|
|
|
420
420
|
def __getitem__(self, pargs):
|
|
421
421
|
"""Slicing protocol."""
|
|
422
|
-
if not self.path.exists():
|
|
423
|
-
msg = f"Cannot read from {self.filename}, it does not yet exist."
|
|
424
|
-
raise FileNotFoundError(msg)
|
|
425
422
|
if len(self.shape) == 2:
|
|
426
423
|
numrows, numcols = self.shape
|
|
427
424
|
numbands = 1
|
|
@@ -750,7 +747,6 @@ class Jp2kr(Jp2kBox):
|
|
|
750
747
|
|
|
751
748
|
Examples
|
|
752
749
|
--------
|
|
753
|
-
>>> import glymur
|
|
754
750
|
>>> jfile = glymur.data.nemo()
|
|
755
751
|
>>> jp = glymur.Jp2k(jfile)
|
|
756
752
|
>>> components_lst = jp.read_bands(rlevel=1)
|
|
@@ -878,12 +874,11 @@ class Jp2kr(Jp2kBox):
|
|
|
878
874
|
|
|
879
875
|
Examples
|
|
880
876
|
--------
|
|
881
|
-
>>> import glymur
|
|
882
877
|
>>> jfile = glymur.data.nemo()
|
|
883
878
|
>>> jp2 = glymur.Jp2k(jfile)
|
|
884
879
|
>>> codestream = jp2.get_codestream()
|
|
885
880
|
>>> print(codestream.segment[1])
|
|
886
|
-
SIZ marker segment @ (
|
|
881
|
+
SIZ marker segment @ (87, 47)
|
|
887
882
|
Profile: no profile
|
|
888
883
|
Reference Grid Height, Width: (1456 x 2592)
|
|
889
884
|
Vertical, Horizontal Reference Grid Offset: (0 x 0)
|
|
@@ -33,10 +33,7 @@ def version():
|
|
|
33
33
|
return v.decode('utf-8')
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
_MAJOR, _MINOR, _PATCH = [int(x) for x in version().split('.')]
|
|
38
|
-
else:
|
|
39
|
-
_MAJOR, _MINOR, _PATCH = 0, 0, 0
|
|
36
|
+
_MAJOR, _MINOR, _PATCH = [int(x) for x in version().split('.')]
|
|
40
37
|
|
|
41
38
|
ERROR_MSG_LST = queue.Queue()
|
|
42
39
|
|
|
@@ -973,13 +970,15 @@ def encoder_set_extra_options(codec, plt=False, tlm=False):
|
|
|
973
970
|
OPENJP2.opj_encoder_set_extra_options.argtypes = ARGTYPES
|
|
974
971
|
OPENJP2.opj_encoder_set_extra_options.restype = check_error
|
|
975
972
|
|
|
973
|
+
# Send the library a null terminated array of char instructions. As of
|
|
974
|
+
# version 2.4.0, there is only a single instruction possible. As of 2.5.0,
|
|
975
|
+
# there are two possible instructions.
|
|
976
976
|
arr = (ctypes.c_char_p * 3)()
|
|
977
|
+
arr[0] = arr[1] = arr[2] = None
|
|
978
|
+
|
|
977
979
|
arr[0] = 'PLT=YES'.encode('utf-8') if plt else 'PLT=NO'.encode('utf-8')
|
|
978
980
|
if version() >= '2.5.0':
|
|
979
981
|
arr[1] = 'TLM=YES'.encode('utf-8') if tlm else 'TLM=NO'.encode('utf-8')
|
|
980
|
-
arr[2] = None
|
|
981
|
-
else:
|
|
982
|
-
arr[1] = None
|
|
983
982
|
|
|
984
983
|
OPENJP2.opj_encoder_set_extra_options(codec, arr)
|
|
985
984
|
|
|
@@ -119,41 +119,27 @@ class Photometric(IntEnum):
|
|
|
119
119
|
this if you do not also specify YCbCr as the photometric interpretation.
|
|
120
120
|
|
|
121
121
|
>>> w, h, nz = image.shape
|
|
122
|
-
>>>
|
|
123
|
-
>>>
|
|
124
|
-
>>>
|
|
125
|
-
>>>
|
|
126
|
-
>>>
|
|
127
|
-
>>>
|
|
128
|
-
>>>
|
|
129
|
-
>>>
|
|
130
|
-
>>>
|
|
131
|
-
>>>
|
|
132
|
-
>>>
|
|
133
|
-
>>>
|
|
134
|
-
>>>
|
|
135
|
-
>>>
|
|
136
|
-
>>>
|
|
137
|
-
>>>
|
|
138
|
-
>>>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
Compression Scheme: JPEG
|
|
144
|
-
Photometric Interpretation: YCbCr
|
|
145
|
-
YCbCr Subsampling: 1, 1
|
|
146
|
-
Samples/Pixel: 3
|
|
147
|
-
Planar Configuration: single image plane
|
|
148
|
-
Reference Black/White:
|
|
149
|
-
0: 0 255
|
|
150
|
-
1: 128 255
|
|
151
|
-
2: 128 255
|
|
152
|
-
Software: LIBTIFF, Version 4.0.9
|
|
153
|
-
Copyright (c) 1988-1996 Sam Leffler
|
|
154
|
-
Copyright (c) 1991-1996 Silicon Graphics, Inc.
|
|
155
|
-
JPEG Tables: (574 bytes)
|
|
156
|
-
<BLANKLINE>
|
|
122
|
+
>>> tw, th = w // 2, h // 2
|
|
123
|
+
>>> from glymur.lib import tiff as libtiff
|
|
124
|
+
>>> fp = libtiff.open('astronaut-jpeg.tif', mode='w8')
|
|
125
|
+
>>> libtiff.setField(fp, 'Photometric', libtiff.Photometric.YCBCR)
|
|
126
|
+
>>> libtiff.setField(fp, 'Compression', libtiff.Compression.JPEG)
|
|
127
|
+
>>> libtiff.setField(fp, 'JPEGColorMode', libtiff.JPEGColorMode.RGB)
|
|
128
|
+
>>> libtiff.setField(fp, 'PlanarConfig', libtiff.PlanarConfig.CONTIG)
|
|
129
|
+
>>> libtiff.setField(fp, 'JPEGQuality', 90)
|
|
130
|
+
>>> libtiff.setField(fp, 'YCbCrSubsampling', 1, 1)
|
|
131
|
+
>>> libtiff.setField(fp, 'ImageWidth', w)
|
|
132
|
+
>>> libtiff.setField(fp, 'ImageLength', h)
|
|
133
|
+
>>> libtiff.setField(fp, 'TileWidth', tw)
|
|
134
|
+
>>> libtiff.setField(fp, 'TileLength', th)
|
|
135
|
+
>>> libtiff.setField(fp, 'BitsPerSample', 8)
|
|
136
|
+
>>> libtiff.setField(fp, 'SamplesPerPixel', nz)
|
|
137
|
+
>>> libtiff.setField(fp, 'Software', libtiff.getVersion())
|
|
138
|
+
>>> libtiff.writeEncodedTile(fp, 0, image[:th, :tw].copy())
|
|
139
|
+
>>> libtiff.writeEncodedTile(fp, 1, image[:th, tw:w].copy())
|
|
140
|
+
>>> libtiff.writeEncodedTile(fp, 2, image[th:h, :tw].copy())
|
|
141
|
+
>>> libtiff.writeEncodedTile(fp, 3, image[th:h, tw:w].copy())
|
|
142
|
+
>>> libtiff.close(fp)
|
|
157
143
|
"""
|
|
158
144
|
MINISWHITE = 0 # value is white
|
|
159
145
|
MINISBLACK = 1 # value is black
|
|
@@ -588,7 +574,7 @@ def setErrorHandler(func=_ERROR_HANDLER):
|
|
|
588
574
|
return old_error_handler
|
|
589
575
|
|
|
590
576
|
|
|
591
|
-
def setField(fp, tag, value):
|
|
577
|
+
def setField(fp, tag, *value):
|
|
592
578
|
"""Corresponds to TIFFSetField"""
|
|
593
579
|
err_handler, warn_handler = _set_error_warning_handlers()
|
|
594
580
|
|
|
@@ -598,11 +584,21 @@ def setField(fp, tag, value):
|
|
|
598
584
|
tag_num = TAGS[tag]['number']
|
|
599
585
|
tag_type = TAGS[tag]['type']
|
|
600
586
|
|
|
601
|
-
|
|
587
|
+
try:
|
|
588
|
+
for ttype in tag_type:
|
|
589
|
+
ARGTYPES.append(ttype)
|
|
590
|
+
except TypeError:
|
|
591
|
+
ARGTYPES.append(tag_type)
|
|
592
|
+
|
|
602
593
|
_LIBTIFF.TIFFSetField.argtypes = ARGTYPES
|
|
603
594
|
_LIBTIFF.TIFFSetField.restype = check_error
|
|
604
595
|
|
|
605
|
-
|
|
596
|
+
if len(value) == 1 and tag_type == ctypes.c_char_p:
|
|
597
|
+
_LIBTIFF.TIFFSetField(fp, tag_num, ctypes.c_char_p(value[0].encode()))
|
|
598
|
+
elif len(value) == 1:
|
|
599
|
+
_LIBTIFF.TIFFSetField(fp, tag_num, value[0])
|
|
600
|
+
else:
|
|
601
|
+
_LIBTIFF.TIFFSetField(fp, tag_num, *value)
|
|
606
602
|
|
|
607
603
|
_reset_error_warning_handlers(err_handler, warn_handler)
|
|
608
604
|
|
|
@@ -57,6 +57,11 @@ def set_option(key, value):
|
|
|
57
57
|
When False, printing of the XML contents of any XML boxes or UUID XMP
|
|
58
58
|
boxes is suppressed. [default: True]
|
|
59
59
|
|
|
60
|
+
Examples
|
|
61
|
+
--------
|
|
62
|
+
>>> glymur.set_option('print.short', True)
|
|
63
|
+
>>> glymur.reset_option('all')
|
|
64
|
+
|
|
60
65
|
See also
|
|
61
66
|
--------
|
|
62
67
|
get_option
|
|
@@ -132,83 +137,18 @@ def reset_option(key):
|
|
|
132
137
|
|
|
133
138
|
|
|
134
139
|
def set_parseoptions(full_codestream=True):
|
|
135
|
-
"""Set parsing options.
|
|
136
|
-
|
|
137
|
-
These options determine the way JPEG 2000 boxes are parsed.
|
|
138
|
-
|
|
139
|
-
Parameters
|
|
140
|
-
----------
|
|
141
|
-
full_codestream : bool, defaults to True
|
|
142
|
-
When False, only the codestream header is parsed for metadata. This
|
|
143
|
-
can results in faster JP2/JPX parsing. When True, the entire
|
|
144
|
-
codestream is parsed for metadata.
|
|
145
|
-
|
|
146
|
-
See also
|
|
147
|
-
--------
|
|
148
|
-
get_parseoptions
|
|
149
|
-
|
|
150
|
-
Examples
|
|
151
|
-
--------
|
|
152
|
-
To put back the default options, you can use:
|
|
153
|
-
|
|
154
|
-
>>> import glymur
|
|
155
|
-
>>> glymur.set_parseoptions(full_codestream=True)
|
|
156
|
-
"""
|
|
157
140
|
warnings.warn('Use set_option instead of set_parseoptions.',
|
|
158
141
|
DeprecationWarning)
|
|
159
142
|
set_option('parse.full_codestream', full_codestream)
|
|
160
143
|
|
|
161
144
|
|
|
162
145
|
def get_parseoptions():
|
|
163
|
-
"""Return the current parsing options.
|
|
164
|
-
|
|
165
|
-
Returns
|
|
166
|
-
-------
|
|
167
|
-
dict
|
|
168
|
-
Dictionary of current print options with keys
|
|
169
|
-
|
|
170
|
-
- codestream : bool
|
|
171
|
-
|
|
172
|
-
For a full description of these options, see `set_parseoptions`.
|
|
173
|
-
|
|
174
|
-
See also
|
|
175
|
-
--------
|
|
176
|
-
set_parseoptions
|
|
177
|
-
"""
|
|
178
146
|
warnings.warn('Use set_option instead of set_parseoptions.',
|
|
179
147
|
DeprecationWarning)
|
|
180
148
|
return {'full_codestream': get_option('parse.full_codestream')}
|
|
181
149
|
|
|
182
150
|
|
|
183
151
|
def set_printoptions(**kwargs):
|
|
184
|
-
"""Set printing options.
|
|
185
|
-
|
|
186
|
-
These options determine the way JPEG 2000 boxes are displayed.
|
|
187
|
-
|
|
188
|
-
Parameters
|
|
189
|
-
----------
|
|
190
|
-
short : bool, optional
|
|
191
|
-
When True, only the box ID, offset, and length are displayed. Useful
|
|
192
|
-
for displaying only the basic structure or skeleton of a JPEG 2000
|
|
193
|
-
file.
|
|
194
|
-
xml : bool, optional
|
|
195
|
-
When False, printing of the XML contents of any XML boxes or UUID XMP
|
|
196
|
-
boxes is suppressed.
|
|
197
|
-
codestream : bool, optional
|
|
198
|
-
When False, the codestream segments are not printed. Otherwise the
|
|
199
|
-
segments are printed depending on how set_parseoptions has been used.
|
|
200
|
-
|
|
201
|
-
See also
|
|
202
|
-
--------
|
|
203
|
-
get_printoptions
|
|
204
|
-
|
|
205
|
-
Examples
|
|
206
|
-
--------
|
|
207
|
-
To put back the default options, you can use:
|
|
208
|
-
|
|
209
|
-
>>> import glymur
|
|
210
|
-
>>> glymur.set_printoptions(short=False, xml=True, codestream=True)
|
|
211
|
-
"""
|
|
212
152
|
warnings.warn('Use set_option instead of set_printoptions.',
|
|
213
153
|
DeprecationWarning)
|
|
214
154
|
for key, value in kwargs.items():
|
|
@@ -218,23 +158,6 @@ def set_printoptions(**kwargs):
|
|
|
218
158
|
|
|
219
159
|
|
|
220
160
|
def get_printoptions():
|
|
221
|
-
"""Return the current print options.
|
|
222
|
-
|
|
223
|
-
Returns
|
|
224
|
-
-------
|
|
225
|
-
dict
|
|
226
|
-
Dictionary of current print options with keys
|
|
227
|
-
|
|
228
|
-
- short : bool
|
|
229
|
-
- xml : bool
|
|
230
|
-
- codestream : bool
|
|
231
|
-
|
|
232
|
-
For a full description of these options, see `set_printoptions`.
|
|
233
|
-
|
|
234
|
-
See also
|
|
235
|
-
--------
|
|
236
|
-
set_printoptions
|
|
237
|
-
"""
|
|
238
161
|
warnings.warn('Use get_option instead of get_printoptions.',
|
|
239
162
|
DeprecationWarning)
|
|
240
163
|
d = {}
|
|
@@ -754,20 +754,6 @@ class Tiff2Jp2k(object):
|
|
|
754
754
|
)
|
|
755
755
|
self.logger.info(msg)
|
|
756
756
|
|
|
757
|
-
if self.photo not in [
|
|
758
|
-
libtiff.Photometric.MINISWHITE,
|
|
759
|
-
libtiff.Photometric.MINISBLACK,
|
|
760
|
-
libtiff.Photometric.PALETTE,
|
|
761
|
-
libtiff.Photometric.YCBCR,
|
|
762
|
-
libtiff.Photometric.RGB
|
|
763
|
-
]:
|
|
764
|
-
photostr = self.tagvalue2str(libtiff.Photometric, self.photo)
|
|
765
|
-
msg = (
|
|
766
|
-
"Beware, the RGBA interface is attempting to read this TIFF "
|
|
767
|
-
f"when it has a PhotometricInterpretation of {photostr}."
|
|
768
|
-
)
|
|
769
|
-
warnings.warn(msg)
|
|
770
|
-
|
|
771
757
|
image = libtiff.readRGBAImageOriented(
|
|
772
758
|
self.tiff_fp, self.imagewidth, self.imageheight
|
|
773
759
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = Glymur
|
|
3
|
-
version = 0.13.
|
|
3
|
+
version = 0.13.2.post1
|
|
4
4
|
author = 'John Evans'
|
|
5
5
|
author_email = "John Evans" <jevans667cc@proton.me>
|
|
6
6
|
license = 'MIT'
|
|
@@ -11,7 +11,6 @@ long_description =
|
|
|
11
11
|
url = https://github.com/quintusdias/glymur
|
|
12
12
|
classifiers =
|
|
13
13
|
Programming Language :: Python
|
|
14
|
-
Programming Language :: Python :: 3.9
|
|
15
14
|
Programming Language :: Python :: 3.10
|
|
16
15
|
Programming Language :: Python :: 3.11
|
|
17
16
|
Programming Language :: Python :: 3.12
|