Merge branch 'issue71' into devel
This commit is contained in:
commit
37cf486719
21 changed files with 4945 additions and 4871 deletions
|
|
@ -6,13 +6,13 @@ How do I...?
|
||||||
Read the lowest resolution thumbnail?
|
Read the lowest resolution thumbnail?
|
||||||
=====================================
|
=====================================
|
||||||
Printing the Jp2k object should reveal the number of resolutions (look in the
|
Printing the Jp2k object should reveal the number of resolutions (look in the
|
||||||
COD segment section), but you can take a shortcut by supplying -1 as the reduce
|
COD segment section), but you can take a shortcut by supplying -1 as the
|
||||||
level. ::
|
resolution level. ::
|
||||||
|
|
||||||
>>> import glymur
|
>>> import glymur
|
||||||
>>> file = glymur.data.nemo()
|
>>> file = glymur.data.nemo()
|
||||||
>>> j = glymur.Jp2k(file)
|
>>> j = glymur.Jp2k(file)
|
||||||
>>> thumbnail = j.read(reduce=-1)
|
>>> thumbnail = j.read(rlevel=-1)
|
||||||
|
|
||||||
Display metadata?
|
Display metadata?
|
||||||
=================
|
=================
|
||||||
|
|
|
||||||
1847
glymur/codestream.py
1847
glymur/codestream.py
File diff suppressed because it is too large
Load diff
140
glymur/core.py
140
glymur/core.py
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Core definitions to be shared amongst the modules.
|
||||||
|
"""
|
||||||
# Progression order
|
# Progression order
|
||||||
LRCP = 0
|
LRCP = 0
|
||||||
RLCP = 1
|
RLCP = 1
|
||||||
|
|
@ -5,44 +7,21 @@ RPCL = 2
|
||||||
PCRL = 3
|
PCRL = 3
|
||||||
CPRL = 4
|
CPRL = 4
|
||||||
|
|
||||||
_progression_order_display = {
|
PROGRESSION_ORDER = {
|
||||||
LRCP: 'LRCP',
|
|
||||||
RLCP: 'RLCP',
|
|
||||||
RPCL: 'RPCL',
|
|
||||||
PCRL: 'PCRL',
|
|
||||||
CPRL: 'CPRL'}
|
|
||||||
|
|
||||||
progression_order = {
|
|
||||||
'LRCP': LRCP,
|
'LRCP': LRCP,
|
||||||
'RLCP': RLCP,
|
'RLCP': RLCP,
|
||||||
'RPCL': RPCL,
|
'RPCL': RPCL,
|
||||||
'PCRL': PCRL,
|
'PCRL': PCRL,
|
||||||
'CPRL': CPRL}
|
'CPRL': CPRL}
|
||||||
|
|
||||||
WAVELET_TRANSFORM_9x7_IRREVERSIBLE = 0
|
WAVELET_XFORM_9X7_IRREVERSIBLE = 0
|
||||||
WAVELET_TRANSFORM_5x3_REVERSIBLE = 1
|
WAVELET_XFORM_5X3_REVERSIBLE = 1
|
||||||
|
|
||||||
_wavelet_transform_display = {
|
|
||||||
WAVELET_TRANSFORM_9x7_IRREVERSIBLE: '9-7 irreversible',
|
|
||||||
WAVELET_TRANSFORM_5x3_REVERSIBLE: '5-3 reversible'}
|
|
||||||
|
|
||||||
ENUMERATED_COLORSPACE = 1
|
ENUMERATED_COLORSPACE = 1
|
||||||
RESTRICTED_ICC_PROFILE = 2
|
RESTRICTED_ICC_PROFILE = 2
|
||||||
ANY_ICC_PROFILE = 3
|
ANY_ICC_PROFILE = 3
|
||||||
VENDOR_COLOR_METHOD = 4
|
VENDOR_COLOR_METHOD = 4
|
||||||
|
|
||||||
_method_display = {
|
|
||||||
ENUMERATED_COLORSPACE: 'enumerated colorspace',
|
|
||||||
RESTRICTED_ICC_PROFILE: 'restricted ICC profile',
|
|
||||||
ANY_ICC_PROFILE: 'any ICC profile',
|
|
||||||
VENDOR_COLOR_METHOD: 'vendor color method'}
|
|
||||||
|
|
||||||
_ = {1: 'accurately represents correct colorspace definition',
|
|
||||||
2: 'approximates correct colorspace definition, exceptional quality',
|
|
||||||
3: 'approximates correct colorspace definition, reasonable quality',
|
|
||||||
4: 'approximates correct colorspace definition, poor quality'}
|
|
||||||
_approximation_display = _
|
|
||||||
|
|
||||||
# Registration values for comment markers.
|
# Registration values for comment markers.
|
||||||
RCME_BINARY = 0 # binary value comments
|
RCME_BINARY = 0 # binary value comments
|
||||||
RCME_ISO_8859_1 = 1 # comments in latin-1 codec
|
RCME_ISO_8859_1 = 1 # comments in latin-1 codec
|
||||||
|
|
@ -55,7 +34,7 @@ YCC = 18
|
||||||
E_SRGB = 20
|
E_SRGB = 20
|
||||||
ROMM_RGB = 21
|
ROMM_RGB = 21
|
||||||
|
|
||||||
_colorspace_map_display = {
|
_COLORSPACE_MAP_DISPLAY = {
|
||||||
CMYK: 'CMYK',
|
CMYK: 'CMYK',
|
||||||
SRGB: 'sRGB',
|
SRGB: 'sRGB',
|
||||||
GREYSCALE: 'greyscale',
|
GREYSCALE: 'greyscale',
|
||||||
|
|
@ -68,7 +47,7 @@ _COLOR = 0
|
||||||
_OPACITY = 1
|
_OPACITY = 1
|
||||||
_PRE_MULTIPLIED_OPACITY = 2
|
_PRE_MULTIPLIED_OPACITY = 2
|
||||||
_UNSPECIFIED = 65535
|
_UNSPECIFIED = 65535
|
||||||
_color_type_map_display = {
|
_COLOR_TYPE_MAP_DISPLAY = {
|
||||||
_COLOR: 'color',
|
_COLOR: 'color',
|
||||||
_OPACITY: 'opacity',
|
_OPACITY: 'opacity',
|
||||||
_PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
|
_PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
|
||||||
|
|
@ -81,108 +60,15 @@ BLUE = 3
|
||||||
GREY = 1
|
GREY = 1
|
||||||
|
|
||||||
# enumerated color channel associations
|
# enumerated color channel associations
|
||||||
_rgb_colorspace = {"R": 1, "G": 2, "B": 3}
|
_COLORSPACE = {SRGB: {"R": 1, "G": 2, "B": 3},
|
||||||
_greyscale_colorspace = {"Y": 1}
|
GREYSCALE: {"Y": 1},
|
||||||
_ycbcr_colorspace = {"Y": 1, "Cb": 2, "Cr": 3}
|
YCC: {"Y": 1, "Cb": 2, "Cr": 3},
|
||||||
_colorspace = {SRGB: _rgb_colorspace,
|
E_SRGB: {"R": 1, "G": 2, "B": 3},
|
||||||
GREYSCALE: _greyscale_colorspace,
|
ROMM_RGB: {"R": 1, "G": 2, "B": 3}}
|
||||||
YCC: _ycbcr_colorspace,
|
|
||||||
E_SRGB: _rgb_colorspace,
|
|
||||||
ROMM_RGB: _rgb_colorspace}
|
|
||||||
|
|
||||||
# How to display the codestream profile.
|
# How to display the codestream profile.
|
||||||
_capabilities_display = {
|
_CAPABILITIES_DISPLAY = {
|
||||||
0: '2',
|
0: '2',
|
||||||
1: '0',
|
1: '0',
|
||||||
2: '1',
|
2: '1',
|
||||||
3: '3'}
|
3: '3'}
|
||||||
|
|
||||||
# Reader requirements
|
|
||||||
#RREQ_UNRESTRICTED_JPEG2000_PART_1 = 5
|
|
||||||
#RREQ_UNRESTRICTED_JPEG2000_PART_2 = 6
|
|
||||||
#RREQ_CMYK_ENUMERATED_COLORSPACE = 55
|
|
||||||
#RREQ_E_SRGB_ENUMERATED_COLORSPACE = 60
|
|
||||||
#RREQ_ROMM_RGB_ENUMERATED_COLORSPACE = 61
|
|
||||||
_reader_requirements_display = {
|
|
||||||
0: 'File not completely understood',
|
|
||||||
1: 'Deprecated',
|
|
||||||
2: 'Contains multiple composition layers',
|
|
||||||
3: 'Deprecated',
|
|
||||||
4: 'JPEG 2000 Part 1 Profile 1 codestream',
|
|
||||||
5: 'Unrestricted JPEG 2000 Part 1 codestream, ITU-T Rec. T.800 '
|
|
||||||
+ '| ISO/IEC 15444-1',
|
|
||||||
6: 'Unrestricted JPEG 2000 Part 2 codestream',
|
|
||||||
7: 'JPEG codestream as defined in ISO/IEC 10918-1',
|
|
||||||
8: 'Deprecated',
|
|
||||||
9: 'Non-premultiplied opacity channel',
|
|
||||||
10: 'Premultiplied opacity channel',
|
|
||||||
11: 'Chroma-key based opacity',
|
|
||||||
12: 'Deprecated',
|
|
||||||
13: 'Fragmented codestream where all fragments are in file and in order',
|
|
||||||
14: 'Fragmented codestream where all fragments are in file '
|
|
||||||
+ 'but are out of order',
|
|
||||||
15: 'Fragmented codestream where not all fragments are within the file '
|
|
||||||
+ 'but are all in locally accessible files',
|
|
||||||
16: 'Fragmented codestream where some fragments may be accessible '
|
|
||||||
+ 'only through a URL specified network connection',
|
|
||||||
17: 'Compositing required to produce rendered result from multiple '
|
|
||||||
+ 'compositing layers',
|
|
||||||
18: 'Deprecated',
|
|
||||||
19: 'Deprecated',
|
|
||||||
20: 'Deprecated',
|
|
||||||
21: 'At least one compositing layer consists of multiple codestreams',
|
|
||||||
22: 'Deprecated',
|
|
||||||
23: 'Colourspace transformations are required to combine compositing '
|
|
||||||
+ 'layers; not all compositing layers are in the same colourspace',
|
|
||||||
24: 'Deprecated',
|
|
||||||
25: 'Deprecated',
|
|
||||||
26: 'First animation layer does not cover entire rendered result',
|
|
||||||
27: 'Deprecated',
|
|
||||||
28: 'Reuse of animation layers',
|
|
||||||
29: 'Deprecated',
|
|
||||||
30: 'Some animated frames are non-persistent',
|
|
||||||
31: 'Deprecated',
|
|
||||||
32: 'Rendered result involves scaling within a layer',
|
|
||||||
33: 'Rendered result involves scaling between layers',
|
|
||||||
34: 'ROI metadata',
|
|
||||||
35: 'IPR metadata',
|
|
||||||
36: 'Content metadata',
|
|
||||||
37: 'History metadata',
|
|
||||||
38: 'Creation metadata',
|
|
||||||
39: 'JPX digital signatures',
|
|
||||||
40: 'JPX checksums',
|
|
||||||
41: 'Desires Graphics Arts Reproduction specified',
|
|
||||||
42: 'Deprecated',
|
|
||||||
43: '(Deprecated) compositing layer uses restricted ICC profile',
|
|
||||||
44: 'Compositing layer uses Any ICC profile',
|
|
||||||
45: 'Deprecated',
|
|
||||||
46: 'Deprecated',
|
|
||||||
47: 'BiLevel 1 enumerated colourspace',
|
|
||||||
48: 'BiLevel 2 enumerated colourspace',
|
|
||||||
49: 'YCbCr 1 enumerated colourspace',
|
|
||||||
50: 'YCbCr 2 enumerated colourspace',
|
|
||||||
51: 'YCbCr 3 enumerated colourspace',
|
|
||||||
52: 'PhotoYCC enumerated colourspace',
|
|
||||||
53: 'YCCK enumerated colourspace',
|
|
||||||
54: 'CMY enumerated colourspace',
|
|
||||||
55: 'CMYK enumerated colorspace',
|
|
||||||
56: 'CIELab enumerated colourspace with default parameters',
|
|
||||||
57: 'CIELab enumerated colourspace with non-default parameters',
|
|
||||||
58: 'CIEJab enumerated colourspace with default parameters',
|
|
||||||
59: 'CIEJab enumerated colourspace with non-default parameters',
|
|
||||||
60: 'e-sRGB enumerated colorspace',
|
|
||||||
61: 'ROMM_RGB enumerated colorspace',
|
|
||||||
62: 'Non-square samples',
|
|
||||||
63: 'Deprecated',
|
|
||||||
64: 'Deprecated',
|
|
||||||
65: 'Deprecated',
|
|
||||||
66: 'Deprecated',
|
|
||||||
67: 'GIS metadata XML box',
|
|
||||||
68: 'JPSEC extensions in codestream as specified by ISO/IEC 15444-8',
|
|
||||||
69: 'JP3D extensions in codestream as specified by ISO/IEC 15444-10',
|
|
||||||
70: 'Deprecated',
|
|
||||||
71: 'e-sYCC enumerated colourspace',
|
|
||||||
72: 'JPEG 2000 Part 2 codestream as restricted by baseline conformance '
|
|
||||||
+ 'requirements in M.9.2.3',
|
|
||||||
73: 'YPbPr(1125/60) enumerated colourspace',
|
|
||||||
74: 'YPbPr(1250/50) enumerated colourspace'}
|
|
||||||
|
|
|
||||||
1311
glymur/jp2box.py
1311
glymur/jp2box.py
File diff suppressed because it is too large
Load diff
358
glymur/jp2k.py
358
glymur/jp2k.py
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# pylint: disable=C0302
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
if sys.hexversion >= 0x03030000:
|
if sys.hexversion >= 0x03030000:
|
||||||
from contextlib import ExitStack
|
from contextlib import ExitStack
|
||||||
|
|
@ -16,15 +19,23 @@ import warnings
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from .codestream import Codestream
|
from .codestream import Codestream
|
||||||
from .core import *
|
from .core import SRGB
|
||||||
from .jp2box import *
|
from .core import GREYSCALE
|
||||||
from .lib import openjpeg as opj
|
from .core import PROGRESSION_ORDER
|
||||||
from .lib import openjp2 as opj2
|
from .jp2box import Jp2kBox
|
||||||
|
from .jp2box import JPEG2000SignatureBox
|
||||||
|
from .jp2box import FileTypeBox
|
||||||
|
from .jp2box import JP2HeaderBox
|
||||||
|
from .jp2box import ContiguousCodestreamBox
|
||||||
|
from .jp2box import ImageHeaderBox
|
||||||
|
from .jp2box import ColourSpecificationBox
|
||||||
|
from .lib import _openjpeg as _opj
|
||||||
|
from .lib import _openjp2 as _opj2
|
||||||
|
|
||||||
_cspace_map = {'rgb': opj2._CLRSPC_SRGB,
|
_COLORSPACE_MAP = {'rgb': _opj2.CLRSPC_SRGB,
|
||||||
'gray': opj2._CLRSPC_GRAY,
|
'gray': _opj2.CLRSPC_GRAY,
|
||||||
'grey': opj2._CLRSPC_GRAY,
|
'grey': _opj2.CLRSPC_GRAY,
|
||||||
'ycc': opj2._CLRSPC_YCC}
|
'ycc': _opj2.CLRSPC_YCC}
|
||||||
|
|
||||||
# Setup the default callback handlers. See the callback functions subsection
|
# Setup the default callback handlers. See the callback functions subsection
|
||||||
# in the ctypes section of the Python documentation for a solid explanation of
|
# in the ctypes section of the Python documentation for a solid explanation of
|
||||||
|
|
@ -32,23 +43,26 @@ _cspace_map = {'rgb': opj2._CLRSPC_SRGB,
|
||||||
_CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p)
|
_CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p)
|
||||||
|
|
||||||
|
|
||||||
def _default_error_handler(msg, client_data):
|
def _default_error_handler(msg, _):
|
||||||
|
"""Default error handler callback for openjpeg library."""
|
||||||
msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip())
|
msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip())
|
||||||
opj2._set_error_message(msg)
|
_opj2.set_error_message(msg)
|
||||||
|
|
||||||
|
|
||||||
def _default_info_handler(msg, client_data):
|
def _default_info_handler(msg, _):
|
||||||
|
"""Default info handler callback for openjpeg library."""
|
||||||
print("[INFO] {0}".format(msg.decode('utf-8').rstrip()))
|
print("[INFO] {0}".format(msg.decode('utf-8').rstrip()))
|
||||||
|
|
||||||
|
|
||||||
def _default_warning_handler(library_msg, client_data):
|
def _default_warning_handler(library_msg, _):
|
||||||
|
"""Default warning handler callback for openjpeg library."""
|
||||||
library_msg = library_msg.decode('utf-8').rstrip()
|
library_msg = library_msg.decode('utf-8').rstrip()
|
||||||
msg = "OpenJPEG library warning: {0}".format(library_msg)
|
msg = "OpenJPEG library warning: {0}".format(library_msg)
|
||||||
warnings.warn(msg)
|
warnings.warn(msg)
|
||||||
|
|
||||||
_error_callback = _CMPFUNC(_default_error_handler)
|
_ERROR_CALLBACK = _CMPFUNC(_default_error_handler)
|
||||||
_info_callback = _CMPFUNC(_default_info_handler)
|
_INFO_CALLBACK = _CMPFUNC(_default_info_handler)
|
||||||
_warning_callback = _CMPFUNC(_default_warning_handler)
|
_WARNING_CALLBACK = _CMPFUNC(_default_warning_handler)
|
||||||
|
|
||||||
|
|
||||||
class Jp2k(Jp2kBox):
|
class Jp2k(Jp2kBox):
|
||||||
|
|
@ -75,10 +89,12 @@ class Jp2k(Jp2kBox):
|
||||||
mode : str, optional
|
mode : str, optional
|
||||||
The mode used to open the file.
|
The mode used to open the file.
|
||||||
"""
|
"""
|
||||||
|
Jp2kBox.__init__(self)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.box = []
|
self.box = []
|
||||||
self.offset = 0
|
self._codec_format = None
|
||||||
|
self._file_size = 0
|
||||||
|
|
||||||
# Parse the file for JP2/JPX contents only if we are reading it.
|
# Parse the file for JP2/JPX contents only if we are reading it.
|
||||||
if mode == 'rb':
|
if mode == 'rb':
|
||||||
|
|
@ -90,8 +106,8 @@ class Jp2k(Jp2kBox):
|
||||||
for box in self.box:
|
for box in self.box:
|
||||||
metadata.append(str(box))
|
metadata.append(str(box))
|
||||||
else:
|
else:
|
||||||
c = self.get_codestream()
|
codestream = self.get_codestream()
|
||||||
metadata.append(str(c))
|
metadata.append(str(codestream))
|
||||||
return '\n'.join(metadata)
|
return '\n'.join(metadata)
|
||||||
|
|
||||||
def _parse(self):
|
def _parse(self):
|
||||||
|
|
@ -106,39 +122,41 @@ class Jp2k(Jp2kBox):
|
||||||
self.length = stat.st_size
|
self.length = stat.st_size
|
||||||
self._file_size = stat.st_size
|
self._file_size = stat.st_size
|
||||||
|
|
||||||
with open(self.filename, 'rb') as f:
|
with open(self.filename, 'rb') as fptr:
|
||||||
|
|
||||||
# Make sure we have a JPEG2000 file. It could be either JP2 or
|
# Make sure we have a JPEG2000 file. It could be either JP2 or
|
||||||
# J2C. Check for J2C first, single box in that case.
|
# J2C. Check for J2C first, single box in that case.
|
||||||
buffer = f.read(2)
|
read_buffer = fptr.read(2)
|
||||||
signature, = struct.unpack('>H', buffer)
|
signature, = struct.unpack('>H', read_buffer)
|
||||||
if signature == 0xff4f:
|
if signature == 0xff4f:
|
||||||
self._codec_format = opj2._CODEC_J2K
|
self._codec_format = _opj2.CODEC_J2K
|
||||||
# That's it, we're done. The codestream object is only
|
# That's it, we're done. The codestream object is only
|
||||||
# produced upon explicit request.
|
# produced upon explicit request.
|
||||||
return
|
return
|
||||||
|
|
||||||
self._codec_format = opj2._CODEC_JP2
|
self._codec_format = _opj2.CODEC_JP2
|
||||||
|
|
||||||
# Should be JP2.
|
# Should be JP2.
|
||||||
# First 4 bytes should be 12, the length of the 'jP ' box.
|
# First 4 bytes should be 12, the length of the 'jP ' box.
|
||||||
# 2nd 4 bytes should be the box ID ('jP ').
|
# 2nd 4 bytes should be the box ID ('jP ').
|
||||||
# 3rd 4 bytes should be the box signature (13, 10, 135, 10).
|
# 3rd 4 bytes should be the box signature (13, 10, 135, 10).
|
||||||
f.seek(0)
|
fptr.seek(0)
|
||||||
buffer = f.read(12)
|
read_buffer = fptr.read(12)
|
||||||
values = struct.unpack('>I4s4B', buffer)
|
values = struct.unpack('>I4s4B', read_buffer)
|
||||||
L = values[0]
|
box_length = values[0]
|
||||||
T = values[1]
|
box_id = values[1]
|
||||||
signature = values[2:]
|
signature = values[2:]
|
||||||
if L != 12 or T != b'jP ' or signature != (13, 10, 135, 10):
|
if (((box_length != 12) or (box_id != b'jP ') or
|
||||||
|
(signature != (13, 10, 135, 10)))):
|
||||||
msg = '{0} is not a JPEG 2000 file.'.format(self.filename)
|
msg = '{0} is not a JPEG 2000 file.'.format(self.filename)
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
# Back up and start again, we know we have a superbox (box of
|
# Back up and start again, we know we have a superbox (box of
|
||||||
# boxes) here.
|
# boxes) here.
|
||||||
f.seek(0)
|
fptr.seek(0)
|
||||||
self.box = self._parse_superbox(f)
|
self.box = self.parse_superbox(fptr)
|
||||||
|
|
||||||
|
# pylint: disable-msg=W0221
|
||||||
def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None,
|
def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None,
|
||||||
cbsize=None, psizes=None, grid_offset=None, sop=False,
|
cbsize=None, psizes=None, grid_offset=None, sop=False,
|
||||||
subsam=None, tilesize=None, prog=None, modesw=None,
|
subsam=None, tilesize=None, prog=None, modesw=None,
|
||||||
|
|
@ -203,24 +221,24 @@ class Jp2k(Jp2kBox):
|
||||||
>>> import glymur
|
>>> import glymur
|
||||||
>>> jfile = glymur.data.nemo()
|
>>> jfile = glymur.data.nemo()
|
||||||
>>> jp2 = glymur.Jp2k(jfile)
|
>>> jp2 = glymur.Jp2k(jfile)
|
||||||
>>> data = jp2.read(reduce=1)
|
>>> data = jp2.read(rlevel=1)
|
||||||
>>> from tempfile import NamedTemporaryFile
|
>>> from tempfile import NamedTemporaryFile
|
||||||
>>> tfile = NamedTemporaryFile(suffix='.jp2', delete=False)
|
>>> tfile = NamedTemporaryFile(suffix='.jp2', delete=False)
|
||||||
>>> j = Jp2k(tfile.name, mode='wb')
|
>>> j = Jp2k(tfile.name, mode='wb')
|
||||||
>>> j.write(data.astype(np.uint8))
|
>>> j.write(data.astype(np.uint8))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cparams = opj2._set_default_encoder_parameters()
|
cparams = _opj2.set_default_encoder_parameters()
|
||||||
|
|
||||||
outfile = self.filename.encode()
|
outfile = self.filename.encode()
|
||||||
n = opj2._PATH_LEN - len(outfile)
|
num_pad_bytes = _opj2.PATH_LEN - len(outfile)
|
||||||
outfile += b'0' * n
|
outfile += b'0' * num_pad_bytes
|
||||||
cparams.outfile = outfile
|
cparams.outfile = outfile
|
||||||
|
|
||||||
if self.filename[-4:].lower() == '.jp2':
|
if self.filename[-4:].lower() == '.jp2':
|
||||||
codec_fmt = opj2._CODEC_JP2
|
codec_fmt = _opj2.CODEC_JP2
|
||||||
else:
|
else:
|
||||||
codec_fmt = opj2._CODEC_J2K
|
codec_fmt = _opj2.CODEC_J2K
|
||||||
|
|
||||||
cparams.cod_format = codec_fmt
|
cparams.cod_format = codec_fmt
|
||||||
|
|
||||||
|
|
@ -230,19 +248,19 @@ class Jp2k(Jp2kBox):
|
||||||
cparams.cp_disto_alloc = 1
|
cparams.cp_disto_alloc = 1
|
||||||
|
|
||||||
if cbsize is not None:
|
if cbsize is not None:
|
||||||
w = cbsize[1]
|
width = cbsize[1]
|
||||||
h = cbsize[0]
|
height = cbsize[0]
|
||||||
if h * w > 4096 or h < 4 or w < 4:
|
if height * width > 4096 or height < 4 or width < 4:
|
||||||
msg = "Code block area cannot exceed 4096. "
|
msg = "Code block area cannot exceed 4096. "
|
||||||
msg += "Code block height and width must be larger than 4."
|
msg += "Code block height and width must be larger than 4."
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
if ((math.log(h, 2) != math.floor(math.log(h, 2)) or
|
if ((math.log(height, 2) != math.floor(math.log(height, 2)) or
|
||||||
math.log(w, 2) != math.floor(math.log(w, 2)))):
|
math.log(width, 2) != math.floor(math.log(width, 2)))):
|
||||||
msg = "Bad code block size ({0}, {1}), "
|
msg = "Bad code block size ({0}, {1}), "
|
||||||
msg += "must be powers of 2."
|
msg += "must be powers of 2."
|
||||||
raise IOError(msg.format(h, w))
|
raise IOError(msg.format(height, width))
|
||||||
cparams.cblockw_init = w
|
cparams.cblockw_init = width
|
||||||
cparams.cblockh_init = h
|
cparams.cblockh_init = height
|
||||||
|
|
||||||
if cratios is not None:
|
if cratios is not None:
|
||||||
cparams.tcp_numlayers = len(cratios)
|
cparams.tcp_numlayers = len(cratios)
|
||||||
|
|
@ -258,16 +276,17 @@ class Jp2k(Jp2kBox):
|
||||||
cparams.image_offset_y0 = grid_offset[0]
|
cparams.image_offset_y0 = grid_offset[0]
|
||||||
|
|
||||||
if modesw is not None:
|
if modesw is not None:
|
||||||
for x in range(6):
|
for shift in range(6):
|
||||||
if modesw & (1 << x):
|
power_of_two = 1 << shift
|
||||||
cparams.mode |= (1 << x)
|
if modesw & power_of_two:
|
||||||
|
cparams.mode |= power_of_two
|
||||||
|
|
||||||
if numres is not None:
|
if numres is not None:
|
||||||
cparams.numresolution = numres
|
cparams.numresolution = numres
|
||||||
|
|
||||||
if prog is not None:
|
if prog is not None:
|
||||||
prog = prog.upper()
|
prog = prog.upper()
|
||||||
cparams.prog_order = progression_order[prog]
|
cparams.prog_order = PROGRESSION_ORDER[prog]
|
||||||
|
|
||||||
if psnr is not None:
|
if psnr is not None:
|
||||||
cparams.tcp_numlayers = len(psnr)
|
cparams.tcp_numlayers = len(psnr)
|
||||||
|
|
@ -304,7 +323,7 @@ class Jp2k(Jp2kBox):
|
||||||
if tilesize is not None:
|
if tilesize is not None:
|
||||||
cparams.cp_tdx = tilesize[1]
|
cparams.cp_tdx = tilesize[1]
|
||||||
cparams.cp_tdy = tilesize[0]
|
cparams.cp_tdy = tilesize[0]
|
||||||
cparams.tile_size_on = opj2._TRUE
|
cparams.tile_size_on = _opj2.TRUE
|
||||||
|
|
||||||
if cratios is not None and psnr is not None:
|
if cratios is not None and psnr is not None:
|
||||||
msg = "Cannot specify cratios and psnr together."
|
msg = "Cannot specify cratios and psnr together."
|
||||||
|
|
@ -323,12 +342,12 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
if colorspace is None:
|
if colorspace is None:
|
||||||
if img_array.shape[2] == 1 or img_array.shape[2] == 2:
|
if img_array.shape[2] == 1 or img_array.shape[2] == 2:
|
||||||
colorspace = opj2._CLRSPC_GRAY
|
colorspace = _opj2.CLRSPC_GRAY
|
||||||
else:
|
else:
|
||||||
# No YCC unless specifically told to do so.
|
# No YCC unless specifically told to do so.
|
||||||
colorspace = opj2._CLRSPC_SRGB
|
colorspace = _opj2.CLRSPC_SRGB
|
||||||
else:
|
else:
|
||||||
if codec_fmt == opj2._CODEC_J2K:
|
if codec_fmt == _opj2.CODEC_J2K:
|
||||||
raise IOError('Do not specify a colorspace with J2K.')
|
raise IOError('Do not specify a colorspace with J2K.')
|
||||||
colorspace = colorspace.lower()
|
colorspace = colorspace.lower()
|
||||||
if colorspace not in ('rgb', 'grey', 'gray'):
|
if colorspace not in ('rgb', 'grey', 'gray'):
|
||||||
|
|
@ -338,15 +357,15 @@ class Jp2k(Jp2kBox):
|
||||||
msg = 'RGB colorspace requires at least 3 components.'
|
msg = 'RGB colorspace requires at least 3 components.'
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
else:
|
else:
|
||||||
colorspace = _cspace_map[colorspace]
|
colorspace = _COLORSPACE_MAP[colorspace]
|
||||||
|
|
||||||
if mct is None:
|
if mct is None:
|
||||||
if colorspace == opj2._CLRSPC_SRGB:
|
if colorspace == _opj2.CLRSPC_SRGB:
|
||||||
cparams.tcp_mct = 1
|
cparams.tcp_mct = 1
|
||||||
else:
|
else:
|
||||||
cparams.tcp_mct = 0
|
cparams.tcp_mct = 0
|
||||||
else:
|
else:
|
||||||
if mct and colorspace == opj2._CLRSPC_GRAY:
|
if mct and colorspace == _opj2.CLRSPC_GRAY:
|
||||||
msg = "Cannot specify usage of the multi component transform "
|
msg = "Cannot specify usage of the multi component transform "
|
||||||
msg += "if the colorspace is gray."
|
msg += "if the colorspace is gray."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
@ -359,7 +378,7 @@ class Jp2k(Jp2kBox):
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("unhandled datatype")
|
raise RuntimeError("unhandled datatype")
|
||||||
|
|
||||||
comptparms = (opj2._image_comptparm_t * num_comps)()
|
comptparms = (_opj2.ImageComptParmType * num_comps)()
|
||||||
for j in range(num_comps):
|
for j in range(num_comps):
|
||||||
comptparms[j].dx = cparams.subsampling_dx
|
comptparms[j].dx = cparams.subsampling_dx
|
||||||
comptparms[j].dy = cparams.subsampling_dy
|
comptparms[j].dy = cparams.subsampling_dy
|
||||||
|
|
@ -371,7 +390,7 @@ class Jp2k(Jp2kBox):
|
||||||
comptparms[j].bpp = comp_prec
|
comptparms[j].bpp = comp_prec
|
||||||
comptparms[j].sgnd = 0
|
comptparms[j].sgnd = 0
|
||||||
|
|
||||||
image = opj2._image_create(comptparms, colorspace)
|
image = _opj2.image_create(comptparms, colorspace)
|
||||||
|
|
||||||
# set image offset and reference grid
|
# set image offset and reference grid
|
||||||
image.contents.x0 = cparams.image_offset_x0
|
image.contents.x0 = cparams.image_offset_x0
|
||||||
|
|
@ -388,23 +407,23 @@ class Jp2k(Jp2kBox):
|
||||||
src = layer.ctypes.data
|
src = layer.ctypes.data
|
||||||
ctypes.memmove(dest, src, layer.nbytes)
|
ctypes.memmove(dest, src, layer.nbytes)
|
||||||
|
|
||||||
codec = opj2._create_compress(codec_fmt)
|
codec = _opj2.create_compress(codec_fmt)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
opj2._set_info_handler(codec, _info_callback)
|
_opj2.set_info_handler(codec, _INFO_CALLBACK)
|
||||||
else:
|
else:
|
||||||
opj2._set_info_handler(codec, None)
|
_opj2.set_info_handler(codec, None)
|
||||||
|
|
||||||
opj2._set_warning_handler(codec, _warning_callback)
|
_opj2.set_warning_handler(codec, _WARNING_CALLBACK)
|
||||||
opj2._set_error_handler(codec, _error_callback)
|
_opj2.set_error_handler(codec, _ERROR_CALLBACK)
|
||||||
opj2._setup_encoder(codec, cparams, image)
|
_opj2.setup_encoder(codec, cparams, image)
|
||||||
strm = opj2._stream_create_default_file_stream_v3(self.filename, False)
|
strm = _opj2.stream_create_default_file_stream_v3(self.filename, False)
|
||||||
opj2._start_compress(codec, image, strm)
|
_opj2.start_compress(codec, image, strm)
|
||||||
opj2._encode(codec, strm)
|
_opj2.encode(codec, strm)
|
||||||
opj2._end_compress(codec, strm)
|
_opj2.end_compress(codec, strm)
|
||||||
opj2._stream_destroy_v3(strm)
|
_opj2.stream_destroy_v3(strm)
|
||||||
opj2._destroy_codec(codec)
|
_opj2.destroy_codec(codec)
|
||||||
opj2._image_destroy(image)
|
_opj2.image_destroy(image)
|
||||||
|
|
||||||
self._parse()
|
self._parse()
|
||||||
|
|
||||||
|
|
@ -439,10 +458,10 @@ class Jp2k(Jp2kBox):
|
||||||
FileTypeBox(),
|
FileTypeBox(),
|
||||||
JP2HeaderBox(),
|
JP2HeaderBox(),
|
||||||
ContiguousCodestreamBox()]
|
ContiguousCodestreamBox()]
|
||||||
c = self.get_codestream()
|
codestream = self.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = codestream.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = codestream.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(codestream.segment[1].xrsiz)
|
||||||
boxes[2].box = [ImageHeaderBox(height=height,
|
boxes[2].box = [ImageHeaderBox(height=height,
|
||||||
width=width,
|
width=width,
|
||||||
num_components=num_components),
|
num_components=num_components),
|
||||||
|
|
@ -450,15 +469,17 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
# Check for a bad sequence of boxes.
|
# Check for a bad sequence of boxes.
|
||||||
# 1st two boxes must be 'jP ' and 'ftyp'
|
# 1st two boxes must be 'jP ' and 'ftyp'
|
||||||
if boxes[0].id != 'jP ' or boxes[1].id != 'ftyp':
|
if boxes[0].box_id != 'jP ' or boxes[1].box_id != 'ftyp':
|
||||||
msg = "The first box must be the signature box and the second "
|
msg = "The first box must be the signature box and the second "
|
||||||
msg += "must be the file type box."
|
msg += "must be the file type box."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
# jp2c must be preceeded by jp2h
|
# jp2c must be preceeded by jp2h
|
||||||
jp2h_lst = [idx for (idx, box) in enumerate(boxes) if box.id == 'jp2h']
|
jp2h_lst = [idx for (idx, box) in enumerate(boxes)
|
||||||
|
if box.box_id == 'jp2h']
|
||||||
jp2h_idx = jp2h_lst[0]
|
jp2h_idx = jp2h_lst[0]
|
||||||
jp2c_lst = [idx for (idx, box) in enumerate(boxes) if box.id == 'jp2c']
|
jp2c_lst = [idx for (idx, box) in enumerate(boxes)
|
||||||
|
if box.box_id == 'jp2c']
|
||||||
if len(jp2c_lst) == 0:
|
if len(jp2c_lst) == 0:
|
||||||
msg = "A codestream box must be defined in the outermost "
|
msg = "A codestream box must be defined in the outermost "
|
||||||
msg += "list of boxes."
|
msg += "list of boxes."
|
||||||
|
|
@ -471,27 +492,28 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
# 1st jp2 header box must be ihdr
|
# 1st jp2 header box must be ihdr
|
||||||
jp2h = boxes[jp2h_idx]
|
jp2h = boxes[jp2h_idx]
|
||||||
if jp2h.box[0].id != 'ihdr':
|
if jp2h.box[0].box_id != 'ihdr':
|
||||||
msg = "The first box in the jp2 header box must be the image "
|
msg = "The first box in the jp2 header box must be the image "
|
||||||
msg += "header box."
|
msg += "header box."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
# colr must be present in jp2 header box.
|
# colr must be present in jp2 header box.
|
||||||
jp2hb = jp2h.box
|
colr_lst = [j for (j, box) in enumerate(jp2h.box)
|
||||||
colr_lst = [j for (j, box) in enumerate(jp2h.box) if box.id == 'colr']
|
if box.box_id == 'colr']
|
||||||
if len(colr_lst) == 0:
|
if len(colr_lst) == 0:
|
||||||
msg = "The jp2 header box must contain a color definition box."
|
msg = "The jp2 header box must contain a color definition box."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
colr = jp2h.box[colr_lst[0]]
|
colr = jp2h.box[colr_lst[0]]
|
||||||
|
|
||||||
# Any cdef box must be in the jp2 header following the image header.
|
# Any cdef box must be in the jp2 header following the image header.
|
||||||
cdef_lst = [j for (j, box) in enumerate(boxes) if box.id == 'cdef']
|
cdef_lst = [j for (j, box) in enumerate(boxes) if box.box_id == 'cdef']
|
||||||
if len(cdef_lst) != 0:
|
if len(cdef_lst) != 0:
|
||||||
msg = "Any channel defintion box must be in the JP2 header "
|
msg = "Any channel defintion box must be in the JP2 header "
|
||||||
msg += "following the image header."
|
msg += "following the image header."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
cdef_lst = [j for (j, box) in enumerate(jp2h.box) if box.id == 'cdef']
|
cdef_lst = [j for (j, box) in enumerate(jp2h.box)
|
||||||
|
if box.box_id == 'cdef']
|
||||||
if len(cdef_lst) > 1:
|
if len(cdef_lst) > 1:
|
||||||
msg = "Only one channel definition box is allowed in the "
|
msg = "Only one channel definition box is allowed in the "
|
||||||
msg += "JP2 header."
|
msg += "JP2 header."
|
||||||
|
|
@ -500,7 +522,6 @@ class Jp2k(Jp2kBox):
|
||||||
cdef = jp2h.box[cdef_lst[0]]
|
cdef = jp2h.box[cdef_lst[0]]
|
||||||
assn = cdef.association
|
assn = cdef.association
|
||||||
typ = cdef.channel_type
|
typ = cdef.channel_type
|
||||||
index = cdef.index
|
|
||||||
if colr.colorspace == SRGB:
|
if colr.colorspace == SRGB:
|
||||||
if any([chan + 1 not in assn or typ[chan] != 0
|
if any([chan + 1 not in assn or typ[chan] != 0
|
||||||
for chan in [0, 1, 2]]):
|
for chan in [0, 1, 2]]):
|
||||||
|
|
@ -515,8 +536,8 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
with open(filename, 'wb') as ofile:
|
with open(filename, 'wb') as ofile:
|
||||||
for box in boxes:
|
for box in boxes:
|
||||||
if box.id != 'jp2c':
|
if box.box_id != 'jp2c':
|
||||||
box._write(ofile)
|
box.write(ofile)
|
||||||
else:
|
else:
|
||||||
# The codestream gets written last.
|
# The codestream gets written last.
|
||||||
if len(self.box) == 0:
|
if len(self.box) == 0:
|
||||||
|
|
@ -530,7 +551,8 @@ class Jp2k(Jp2kBox):
|
||||||
else:
|
else:
|
||||||
# OK, I'm a jp2 file. Need to find out where the
|
# OK, I'm a jp2 file. Need to find out where the
|
||||||
# raw codestream actually starts.
|
# raw codestream actually starts.
|
||||||
jp2c = [box for box in self.box if box.id == 'jp2c']
|
jp2c = [box for box in self.box
|
||||||
|
if box.box_id == 'jp2c']
|
||||||
jp2c = jp2c[0]
|
jp2c = jp2c[0]
|
||||||
ofile.write(struct.pack('>I', jp2c.length + 8))
|
ofile.write(struct.pack('>I', jp2c.length + 8))
|
||||||
ofile.write('jp2c'.encode())
|
ofile.write('jp2c'.encode())
|
||||||
|
|
@ -550,8 +572,8 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
reduce : int, optional
|
rlevel : int, optional
|
||||||
Factor by which to reduce output resolution. Use -1 to get the
|
Factor by which to rlevel output resolution. Use -1 to get the
|
||||||
lowest resolution thumbnail. This is the only keyword option
|
lowest resolution thumbnail. This is the only keyword option
|
||||||
available to use when only OpenJPEG version 1.5.1 is present.
|
available to use when only OpenJPEG version 1.5.1 is present.
|
||||||
layer : int, optional
|
layer : int, optional
|
||||||
|
|
@ -585,23 +607,23 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
Read the lowest resolution thumbnail.
|
Read the lowest resolution thumbnail.
|
||||||
|
|
||||||
>>> thumbnail = jp.read(reduce=-1)
|
>>> thumbnail = jp.read(rlevel=-1)
|
||||||
>>> thumbnail.shape
|
>>> thumbnail.shape
|
||||||
(728, 1296, 3)
|
(728, 1296, 3)
|
||||||
"""
|
"""
|
||||||
if opj2._OPENJP2 is not None:
|
if _opj2.OPENJP2 is not None:
|
||||||
img = self._read_openjp2(**kwargs)
|
img = self._read_openjp2(**kwargs)
|
||||||
else:
|
else:
|
||||||
img = self._read_openjpeg(**kwargs)
|
img = self._read_openjpeg(**kwargs)
|
||||||
return img
|
return img
|
||||||
|
|
||||||
def _read_openjpeg(self, reduce=0, verbose=False):
|
def _read_openjpeg(self, rlevel=0, verbose=False):
|
||||||
"""Read a JPEG 2000 image using libopenjpeg.
|
"""Read a JPEG 2000 image using libopenjpeg.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
reduce : int, optional
|
rlevel : int, optional
|
||||||
Factor by which to reduce output resolution. Use -1 to get the
|
Factor by which to rlevel output resolution. Use -1 to get the
|
||||||
lowest resolution thumbnail.
|
lowest resolution thumbnail.
|
||||||
verbose : bool, optional
|
verbose : bool, optional
|
||||||
Print informational messages produced by the OpenJPEG library.
|
Print informational messages produced by the OpenJPEG library.
|
||||||
|
|
@ -618,49 +640,48 @@ class Jp2k(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
# Check for differing subsample factors.
|
# Check for differing subsample factors.
|
||||||
codestream = self.get_codestream(header_only=True)
|
codestream = self.get_codestream(header_only=True)
|
||||||
dxs = np.array(codestream.segment[1].XRsiz)
|
dxs = np.array(codestream.segment[1].xrsiz)
|
||||||
dys = np.array(codestream.segment[1].YRsiz)
|
dys = np.array(codestream.segment[1].yrsiz)
|
||||||
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
|
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
|
||||||
msg = "Components must all have the same subsampling factors "
|
msg = "Components must all have the same subsampling factors "
|
||||||
msg += "to use this method with OpenJPEG 1.5.1. Please consider "
|
msg += "to use this method with OpenJPEG 1.5.1. Please consider "
|
||||||
msg += "using OPENJP2 instead."
|
msg += "using OPENJP2 instead."
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
# Set decoding parameters.
|
# Set decoding parameters.
|
||||||
dparameters = opj.dparameters_t()
|
dparameters = _opj.DecompressionParametersType()
|
||||||
opj._set_default_decoder_parameters(ctypes.byref(dparameters))
|
_opj.set_default_decoder_parameters(ctypes.byref(dparameters))
|
||||||
dparameters.cp_reduce = reduce
|
dparameters.cp_reduce = rlevel
|
||||||
dparameters.decod_format = self._codec_format
|
dparameters.decod_format = self._codec_format
|
||||||
|
|
||||||
infile = self.filename.encode()
|
infile = self.filename.encode()
|
||||||
nelts = opj._PATH_LEN - len(infile)
|
nelts = _opj.PATH_LEN - len(infile)
|
||||||
infile += b'0' * nelts
|
infile += b'0' * nelts
|
||||||
dparameters.infile = infile
|
dparameters.infile = infile
|
||||||
|
|
||||||
dinfo = opj._create_decompress(dparameters.decod_format)
|
dinfo = _opj.create_decompress(dparameters.decod_format)
|
||||||
|
|
||||||
event_mgr = opj.event_mgr_t()
|
event_mgr = _opj.EventMgrType()
|
||||||
info_handler = ctypes.cast(_info_callback, ctypes.c_void_p)
|
info_handler = ctypes.cast(_INFO_CALLBACK, ctypes.c_void_p)
|
||||||
event_mgr.info_handler = info_handler if verbose else None
|
event_mgr.info_handler = info_handler if verbose else None
|
||||||
event_mgr.warning_handler = ctypes.cast(_warning_callback,
|
event_mgr.warning_handler = ctypes.cast(_WARNING_CALLBACK,
|
||||||
ctypes.c_void_p)
|
ctypes.c_void_p)
|
||||||
event_mgr.error_handler = ctypes.cast(_error_callback,
|
event_mgr.error_handler = ctypes.cast(_ERROR_CALLBACK,
|
||||||
ctypes.c_void_p)
|
ctypes.c_void_p)
|
||||||
opj._set_event_mgr(dinfo, ctypes.byref(event_mgr))
|
_opj.set_event_mgr(dinfo, ctypes.byref(event_mgr))
|
||||||
|
|
||||||
opj._setup_decoder(dinfo, dparameters)
|
_opj.setup_decoder(dinfo, dparameters)
|
||||||
|
|
||||||
with open(self.filename, 'rb') as fp:
|
with open(self.filename, 'rb') as fptr:
|
||||||
src = fp.read()
|
src = fptr.read()
|
||||||
cio = opj._cio_open(dinfo, src)
|
cio = _opj.cio_open(dinfo, src)
|
||||||
|
|
||||||
image = opj._decode(dinfo, cio)
|
image = _opj.decode(dinfo, cio)
|
||||||
|
|
||||||
stack.callback(opj._image_destroy, image)
|
stack.callback(_opj.image_destroy, image)
|
||||||
stack.callback(opj._destroy_decompress, dinfo)
|
stack.callback(_opj.destroy_decompress, dinfo)
|
||||||
stack.callback(opj._cio_close, cio)
|
stack.callback(_opj.cio_close, cio)
|
||||||
|
|
||||||
ncomps = image.contents.numcomps
|
ncomps = image.contents.numcomps
|
||||||
component = image.contents.comps[0]
|
component = image.contents.comps[0]
|
||||||
|
|
@ -700,8 +721,10 @@ class Jp2k(Jp2kBox):
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
nelts = nrows * ncols
|
nelts = nrows * ncols
|
||||||
x = np.ctypeslib.as_array((ctypes.c_int32 * nelts).from_address(addr))
|
band = np.ctypeslib.as_array(
|
||||||
data[:, :, k] = np.reshape(x.astype(dtype), (nrows, ncols))
|
(ctypes.c_int32 * nelts).from_address(addr))
|
||||||
|
data[:, :, k] = np.reshape(band.astype(dtype),
|
||||||
|
(nrows, ncols))
|
||||||
|
|
||||||
if data.shape[2] == 1:
|
if data.shape[2] == 1:
|
||||||
data = data.view()
|
data = data.view()
|
||||||
|
|
@ -709,7 +732,7 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _read_openjp2(self, reduce=0, layer=0, area=None, tile=None,
|
def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None,
|
||||||
verbose=False):
|
verbose=False):
|
||||||
"""Read a JPEG 2000 image using libopenjp2.
|
"""Read a JPEG 2000 image using libopenjp2.
|
||||||
|
|
||||||
|
|
@ -717,8 +740,8 @@ class Jp2k(Jp2kBox):
|
||||||
----------
|
----------
|
||||||
layer : int, optional
|
layer : int, optional
|
||||||
Number of quality layer to decode.
|
Number of quality layer to decode.
|
||||||
reduce : int, optional
|
rlevel : int, optional
|
||||||
Factor by which to reduce output resolution. Use -1 to get the
|
Factor by which to rlevel output resolution. Use -1 to get the
|
||||||
lowest resolution thumbnail.
|
lowest resolution thumbnail.
|
||||||
area : tuple, optional
|
area : tuple, optional
|
||||||
Specifies decoding image area,
|
Specifies decoding image area,
|
||||||
|
|
@ -740,13 +763,13 @@ class Jp2k(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
# Check for differing subsample factors.
|
# Check for differing subsample factors.
|
||||||
codestream = self.get_codestream(header_only=True)
|
codestream = self.get_codestream(header_only=True)
|
||||||
dxs = np.array(codestream.segment[1].XRsiz)
|
dxs = np.array(codestream.segment[1].xrsiz)
|
||||||
dys = np.array(codestream.segment[1].YRsiz)
|
dys = np.array(codestream.segment[1].yrsiz)
|
||||||
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
|
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
|
||||||
msg = "Components must all have the same subsampling factors."
|
msg = "Components must all have the same subsampling factors."
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
img_array = self._read_common(reduce=reduce,
|
img_array = self._read_common(rlevel=rlevel,
|
||||||
layer=layer,
|
layer=layer,
|
||||||
area=area,
|
area=area,
|
||||||
tile=tile,
|
tile=tile,
|
||||||
|
|
@ -759,7 +782,7 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
return img_array
|
return img_array
|
||||||
|
|
||||||
def _read_common(self, reduce=0, layer=0, area=None, tile=None,
|
def _read_common(self, rlevel=0, layer=0, area=None, tile=None,
|
||||||
verbose=False, as_bands=False):
|
verbose=False, as_bands=False):
|
||||||
"""Read a JPEG 2000 image.
|
"""Read a JPEG 2000 image.
|
||||||
|
|
||||||
|
|
@ -767,8 +790,8 @@ class Jp2k(Jp2kBox):
|
||||||
----------
|
----------
|
||||||
layer : int, optional
|
layer : int, optional
|
||||||
Number of quality layer to decode.
|
Number of quality layer to decode.
|
||||||
reduce : int, optional
|
rlevel : int, optional
|
||||||
Factor by which to reduce output resolution.
|
Factor by which to rlevel output resolution.
|
||||||
area : tuple, optional
|
area : tuple, optional
|
||||||
Specifies decoding image area,
|
Specifies decoding image area,
|
||||||
(first_row, first_col, last_row, last_col)
|
(first_row, first_col, last_row, last_col)
|
||||||
|
|
@ -784,10 +807,10 @@ class Jp2k(Jp2kBox):
|
||||||
img_array : ndarray
|
img_array : ndarray
|
||||||
The individual image components or a single array.
|
The individual image components or a single array.
|
||||||
"""
|
"""
|
||||||
dparam = opj2._set_default_decoder_parameters()
|
dparam = _opj2.set_default_decoder_parameters()
|
||||||
|
|
||||||
infile = self.filename.encode()
|
infile = self.filename.encode()
|
||||||
nelts = opj2._PATH_LEN - len(infile)
|
nelts = _opj2.PATH_LEN - len(infile)
|
||||||
infile += b'0' * nelts
|
infile += b'0' * nelts
|
||||||
dparam.infile = infile
|
dparam.infile = infile
|
||||||
|
|
||||||
|
|
@ -795,12 +818,12 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
dparam.cp_layer = layer
|
dparam.cp_layer = layer
|
||||||
|
|
||||||
if reduce == -1:
|
if rlevel == -1:
|
||||||
# Get the lowest resolution thumbnail.
|
# Get the lowest resolution thumbnail.
|
||||||
codestream = self.get_codestream()
|
codestream = self.get_codestream()
|
||||||
reduce = codestream.segment[2].SPcod[4]
|
rlevel = codestream.segment[2].spcod[4]
|
||||||
|
|
||||||
dparam.cp_reduce = reduce
|
dparam.cp_reduce = rlevel
|
||||||
if area is not None:
|
if area is not None:
|
||||||
if area[0] < 0 or area[1] < 0:
|
if area[0] < 0 or area[1] < 0:
|
||||||
msg = "Upper left corner coordinates must be nonnegative: {0}"
|
msg = "Upper left corner coordinates must be nonnegative: {0}"
|
||||||
|
|
@ -820,31 +843,31 @@ class Jp2k(Jp2kBox):
|
||||||
dparam.nb_tile_to_decode = 1
|
dparam.nb_tile_to_decode = 1
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
stream = opj2._stream_create_default_file_stream_v3(self.filename,
|
stream = _opj2.stream_create_default_file_stream_v3(self.filename,
|
||||||
True)
|
True)
|
||||||
stack.callback(opj2._stream_destroy_v3, stream)
|
stack.callback(_opj2.stream_destroy_v3, stream)
|
||||||
codec = opj2._create_decompress(self._codec_format)
|
codec = _opj2.create_decompress(self._codec_format)
|
||||||
stack.callback(opj2._destroy_codec, codec)
|
stack.callback(_opj2.destroy_codec, codec)
|
||||||
|
|
||||||
opj2._set_error_handler(codec, _error_callback)
|
_opj2.set_error_handler(codec, _ERROR_CALLBACK)
|
||||||
opj2._set_warning_handler(codec, _warning_callback)
|
_opj2.set_warning_handler(codec, _WARNING_CALLBACK)
|
||||||
if verbose:
|
if verbose:
|
||||||
opj2._set_info_handler(codec, _info_callback)
|
_opj2.set_info_handler(codec, _INFO_CALLBACK)
|
||||||
else:
|
else:
|
||||||
opj2._set_info_handler(codec, None)
|
_opj2.set_info_handler(codec, None)
|
||||||
|
|
||||||
opj2._setup_decoder(codec, dparam)
|
_opj2.setup_decoder(codec, dparam)
|
||||||
image = opj2._read_header(stream, codec)
|
image = _opj2.read_header(stream, codec)
|
||||||
stack.callback(opj2._image_destroy, image)
|
stack.callback(_opj2.image_destroy, image)
|
||||||
|
|
||||||
if dparam.nb_tile_to_decode:
|
if dparam.nb_tile_to_decode:
|
||||||
opj2._get_decoded_tile(codec, stream, image, dparam.tile_index)
|
_opj2.get_decoded_tile(codec, stream, image, dparam.tile_index)
|
||||||
else:
|
else:
|
||||||
opj2._set_decode_area(codec, image,
|
_opj2.set_decode_area(codec, image,
|
||||||
dparam.DA_x0, dparam.DA_y0,
|
dparam.DA_x0, dparam.DA_y0,
|
||||||
dparam.DA_x1, dparam.DA_y1)
|
dparam.DA_x1, dparam.DA_y1)
|
||||||
opj2._decode(codec, stream, image)
|
_opj2.decode(codec, stream, image)
|
||||||
opj2._end_decompress(codec, stream)
|
_opj2.end_decompress(codec, stream)
|
||||||
|
|
||||||
component = image.contents.comps[0]
|
component = image.contents.comps[0]
|
||||||
if component.sgnd:
|
if component.sgnd:
|
||||||
|
|
@ -885,16 +908,17 @@ class Jp2k(Jp2kBox):
|
||||||
addr = ctypes.addressof(component.data.contents)
|
addr = ctypes.addressof(component.data.contents)
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
x = np.ctypeslib.as_array(
|
band = np.ctypeslib.as_array(
|
||||||
(ctypes.c_int32 * nrows * ncols).from_address(addr))
|
(ctypes.c_int32 * nrows * ncols).from_address(addr))
|
||||||
if as_bands:
|
if as_bands:
|
||||||
data.append(np.reshape(x.astype(dtype), (nrows, ncols)))
|
data.append(np.reshape(band.astype(dtype), (nrows, ncols)))
|
||||||
else:
|
else:
|
||||||
data[:, :, k] = np.reshape(x.astype(dtype), (nrows, ncols))
|
data[:, :, k] = np.reshape(band.astype(dtype),
|
||||||
|
(nrows, ncols))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def read_bands(self, reduce=0, layer=0, area=None, tile=None,
|
def read_bands(self, rlevel=0, layer=0, area=None, tile=None,
|
||||||
verbose=False):
|
verbose=False):
|
||||||
"""Read a JPEG 2000 image.
|
"""Read a JPEG 2000 image.
|
||||||
|
|
||||||
|
|
@ -906,8 +930,8 @@ class Jp2k(Jp2kBox):
|
||||||
----------
|
----------
|
||||||
layer : int, optional
|
layer : int, optional
|
||||||
Number of quality layer to decode.
|
Number of quality layer to decode.
|
||||||
reduce : int, optional
|
rlevel : int, optional
|
||||||
Factor by which to reduce output resolution.
|
Factor by which to rlevel output resolution.
|
||||||
area : tuple, optional
|
area : tuple, optional
|
||||||
Specifies decoding image area,
|
Specifies decoding image area,
|
||||||
(first_row, first_col, last_row, last_col)
|
(first_row, first_col, last_row, last_col)
|
||||||
|
|
@ -930,18 +954,18 @@ class Jp2k(Jp2kBox):
|
||||||
>>> import glymur
|
>>> import glymur
|
||||||
>>> jfile = glymur.data.nemo()
|
>>> jfile = glymur.data.nemo()
|
||||||
>>> jp = glymur.Jp2k(jfile)
|
>>> jp = glymur.Jp2k(jfile)
|
||||||
>>> components_lst = jp.read_bands(reduce=1)
|
>>> components_lst = jp.read_bands(rlevel=1)
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
------
|
------
|
||||||
NotImplementedError
|
NotImplementedError
|
||||||
If the openjp2 library is not available.
|
If the openjp2 library is not available.
|
||||||
"""
|
"""
|
||||||
if opj2._OPENJP2 is None:
|
if _opj2.OPENJP2 is None:
|
||||||
msg = "Requires openjp2 library."
|
msg = "Requires openjp2 library."
|
||||||
raise NotImplementedError(msg)
|
raise NotImplementedError(msg)
|
||||||
|
|
||||||
lst = self._read_common(reduce=reduce,
|
lst = self._read_common(rlevel=rlevel,
|
||||||
layer=layer,
|
layer=layer,
|
||||||
area=area,
|
area=area,
|
||||||
tile=tile,
|
tile=tile,
|
||||||
|
|
@ -985,20 +1009,20 @@ class Jp2k(Jp2kBox):
|
||||||
IOError
|
IOError
|
||||||
If the file is JPX with more than one codestream.
|
If the file is JPX with more than one codestream.
|
||||||
"""
|
"""
|
||||||
with open(self.filename, 'rb') as fp:
|
with open(self.filename, 'rb') as fptr:
|
||||||
if self._codec_format == opj2._CODEC_J2K:
|
if self._codec_format == _opj2.CODEC_J2K:
|
||||||
codestream = Codestream(fp, header_only=header_only)
|
codestream = Codestream(fptr, header_only=header_only)
|
||||||
else:
|
else:
|
||||||
box = [x for x in self.box if x.id == 'jp2c']
|
box = [x for x in self.box if x.box_id == 'jp2c']
|
||||||
if len(box) != 1:
|
if len(box) != 1:
|
||||||
msg = "JP2 files must have a single codestream."
|
msg = "JP2 files must have a single codestream."
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
fp.seek(box[0].offset)
|
fptr.seek(box[0].offset)
|
||||||
buffer = fp.read(8)
|
read_buffer = fptr.read(8)
|
||||||
(L, T) = struct.unpack('>I4s', buffer)
|
(box_length, _) = struct.unpack('>I4s', read_buffer)
|
||||||
if L == 1:
|
if box_length == 1:
|
||||||
# Seek past the XL field.
|
# Seek past the XL field.
|
||||||
buffer = fp.read(8)
|
read_buffer = fptr.read(8)
|
||||||
codestream = Codestream(fp, header_only=header_only)
|
codestream = Codestream(fptr, header_only=header_only)
|
||||||
|
|
||||||
return codestream
|
return codestream
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
"""This package organizes individual libraries employed by glymur."""
|
"""This package organizes individual libraries employed by glymur."""
|
||||||
from . import openjp2
|
from . import openjp2 as _openjp2
|
||||||
from . import openjpeg
|
from . import openjpeg as _openjpeg
|
||||||
#from . import test
|
#from . import test
|
||||||
|
|
|
||||||
133
glymur/lib/config.py
Normal file
133
glymur/lib/config.py
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
"""
|
||||||
|
Configure glymur to use installed libraries if possible.
|
||||||
|
"""
|
||||||
|
import ctypes
|
||||||
|
from ctypes.util import find_library
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if sys.hexversion <= 0x03000000:
|
||||||
|
from ConfigParser import SafeConfigParser as ConfigParser
|
||||||
|
else:
|
||||||
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
|
||||||
|
def glymurrc_fname():
|
||||||
|
"""Return the path to the configuration file.
|
||||||
|
|
||||||
|
Search order:
|
||||||
|
1) current working directory
|
||||||
|
2) environ var XDG_CONFIG_HOME
|
||||||
|
3) $HOME/.config/glymur/glymurrc
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Current directory.
|
||||||
|
fname = os.path.join(os.getcwd(), 'glymurrc')
|
||||||
|
if os.path.exists(fname):
|
||||||
|
return fname
|
||||||
|
|
||||||
|
# Either GLYMURCONFIGDIR/glymurrc or $HOME/.glymur/glymurrc
|
||||||
|
confdir = get_configdir()
|
||||||
|
if confdir is not None:
|
||||||
|
fname = os.path.join(confdir, 'glymurrc')
|
||||||
|
if os.path.exists(fname):
|
||||||
|
return fname
|
||||||
|
|
||||||
|
# didn't find a configuration file.
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_openjpeg_config():
|
||||||
|
""" Try to find openjpeg library on the system path first.
|
||||||
|
"""
|
||||||
|
libopenjpeg_path = find_library('openjpeg')
|
||||||
|
|
||||||
|
# If we could not find it, then look in some likely locations.
|
||||||
|
if libopenjpeg_path is None:
|
||||||
|
if platform.system() == 'Darwin':
|
||||||
|
path = '/opt/local/lib/libopenjpeg.dylib'
|
||||||
|
if os.path.exists(path):
|
||||||
|
libopenjpeg_path = path
|
||||||
|
elif os.name == 'nt':
|
||||||
|
path = os.path.join('C:\\', 'Program files', 'OpenJPEG 1.5',
|
||||||
|
'bin', 'openjpeg.dll')
|
||||||
|
if os.path.exists(path):
|
||||||
|
libopenjpeg_path = path
|
||||||
|
|
||||||
|
try:
|
||||||
|
if os.name == "nt":
|
||||||
|
openjpeg_lib = ctypes.windll.LoadLibrary(libopenjpeg_path)
|
||||||
|
else:
|
||||||
|
openjpeg_lib = ctypes.CDLL(libopenjpeg_path)
|
||||||
|
except OSError:
|
||||||
|
openjpeg_lib = None
|
||||||
|
|
||||||
|
if openjpeg_lib is not None:
|
||||||
|
# Must be at least 1.5.0
|
||||||
|
openjpeg_lib.opj_version.restype = ctypes.c_char_p
|
||||||
|
version = openjpeg_lib.opj_version().decode('utf-8')
|
||||||
|
_, minor, _ = version.split('.')
|
||||||
|
if minor != '5':
|
||||||
|
openjpeg_lib = None
|
||||||
|
return openjpeg_lib
|
||||||
|
|
||||||
|
|
||||||
|
def get_openjp2_config():
|
||||||
|
"""
|
||||||
|
We expect to not find openjp2 on the system path since the only version
|
||||||
|
that we currently care about is still in the svn trunk at openjpeg.org.
|
||||||
|
We must use a configuration file that the user must write.
|
||||||
|
"""
|
||||||
|
filename = glymurrc_fname()
|
||||||
|
if filename is not None:
|
||||||
|
# Read the configuration file for the library location.
|
||||||
|
parser = ConfigParser()
|
||||||
|
parser.read(filename)
|
||||||
|
libopenjp2_path = parser.get('library', 'openjp2')
|
||||||
|
else:
|
||||||
|
# No help from the config file, try to find it ourselves.
|
||||||
|
libopenjp2_path = find_library('openjp2')
|
||||||
|
|
||||||
|
if libopenjp2_path is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
if os.name == "nt":
|
||||||
|
openjp2_lib = ctypes.windll.LoadLibrary(libopenjp2_path)
|
||||||
|
else:
|
||||||
|
openjp2_lib = ctypes.CDLL(libopenjp2_path)
|
||||||
|
except OSError:
|
||||||
|
msg = '"Library {0}" could not be loaded. Operating in degraded mode.'
|
||||||
|
msg = msg.format(libopenjp2_path)
|
||||||
|
warnings.warn(msg, UserWarning)
|
||||||
|
openjp2_lib = None
|
||||||
|
return openjp2_lib
|
||||||
|
|
||||||
|
|
||||||
|
def glymur_config():
|
||||||
|
"""Try to ascertain locations of openjp2, openjpeg libraries.
|
||||||
|
"""
|
||||||
|
openjp2_lib = get_openjp2_config()
|
||||||
|
openjpeg_lib = get_openjpeg_config()
|
||||||
|
return openjp2_lib, openjpeg_lib
|
||||||
|
|
||||||
|
|
||||||
|
def get_configdir():
|
||||||
|
"""Return string representing the configuration directory.
|
||||||
|
|
||||||
|
Default is $HOME/.config/glymur. You can override this with the
|
||||||
|
XDG_CONFIG_HOME environment variable.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if 'XDG_CONFIG_HOME' in os.environ:
|
||||||
|
return os.path.join(os.environ['XDG_CONFIG_HOME'], 'glymur')
|
||||||
|
|
||||||
|
if 'HOME' in os.environ:
|
||||||
|
return os.path.join(os.environ['HOME'], '.config', 'glymur')
|
||||||
|
|
||||||
|
if 'USERPROFILE' in os.environ:
|
||||||
|
# Windows?
|
||||||
|
return os.path.join(os.environ['USERPROFILE'], 'Application Data',
|
||||||
|
'glymur')
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,35 +1,30 @@
|
||||||
"""Wraps library calls to openjpeg.
|
"""Wraps library calls to openjpeg.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# pylint: disable=R0903
|
||||||
|
|
||||||
import ctypes
|
import ctypes
|
||||||
from ctypes.util import find_library
|
|
||||||
import platform
|
|
||||||
import os
|
|
||||||
|
|
||||||
if os.name == "nt":
|
from .config import glymur_config
|
||||||
path = os.path.join('C:\\', 'Program files', 'OpenJPEG 1.5',
|
_, OPENJPEG = glymur_config()
|
||||||
'bin', 'openjpeg.dll')
|
|
||||||
_OPENJPEG = ctypes.windll.LoadLibrary(path)
|
|
||||||
else:
|
|
||||||
if platform.system() == 'Darwin':
|
|
||||||
_OPENJPEG = ctypes.CDLL('/opt/local/lib/libopenjpeg.dylib')
|
|
||||||
elif platform.system() == 'Linux':
|
|
||||||
_OPENJPEG = ctypes.CDLL(find_library('openjpeg'))
|
|
||||||
|
|
||||||
_PATH_LEN = 4096 # maximum allowed size for filenames
|
PATH_LEN = 4096 # maximum allowed size for filenames
|
||||||
|
|
||||||
|
|
||||||
class event_mgr_t(ctypes.Structure):
|
class EventMgrType(ctypes.Structure):
|
||||||
"""Message handler object.
|
"""Message handler object.
|
||||||
|
|
||||||
|
Corresponds to event_mgr_t type in openjpeg headers.
|
||||||
"""
|
"""
|
||||||
_fields_ = [("error_handler", ctypes.c_void_p),
|
_fields_ = [("error_handler", ctypes.c_void_p),
|
||||||
("warning_handler", ctypes.c_void_p),
|
("warning_handler", ctypes.c_void_p),
|
||||||
("info_handler", ctypes.c_void_p)]
|
("info_handler", ctypes.c_void_p)]
|
||||||
|
|
||||||
class common_struct_t(ctypes.Structure):
|
|
||||||
|
class CommonStructType(ctypes.Structure):
|
||||||
"""Common fields between JPEG 2000 compression and decompression contextx.
|
"""Common fields between JPEG 2000 compression and decompression contextx.
|
||||||
"""
|
"""
|
||||||
_fields_ = [("event_mgr", ctypes.POINTER(event_mgr_t)),
|
_fields_ = [("event_mgr", ctypes.POINTER(EventMgrType)),
|
||||||
("client_data", ctypes.c_void_p),
|
("client_data", ctypes.c_void_p),
|
||||||
("is_decompressor", ctypes.c_bool),
|
("is_decompressor", ctypes.c_bool),
|
||||||
("codec_format", ctypes.c_int),
|
("codec_format", ctypes.c_int),
|
||||||
|
|
@ -38,16 +33,20 @@ class common_struct_t(ctypes.Structure):
|
||||||
("mj2_handle", ctypes.c_void_p)]
|
("mj2_handle", ctypes.c_void_p)]
|
||||||
|
|
||||||
|
|
||||||
class dinfo_t(ctypes.Structure):
|
class DecompressionInfoType(ctypes.Structure):
|
||||||
"""Common fields between JPEG 2000 compression and decompression contextx.
|
"""This is for decompression contexts.
|
||||||
This is for decompression contexts.
|
|
||||||
|
Corresponds to dinfo_t type in openjpeg headers.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class cio_t(ctypes.Structure):
|
class CioType(ctypes.Structure):
|
||||||
_fields_ = [# codec context
|
"""Byte input-output stream (CIO)
|
||||||
("cinfo", ctypes.POINTER(common_struct_t)),
|
|
||||||
|
Corresponds to cio_t in openjpeg headers.
|
||||||
|
"""
|
||||||
|
_fields_ = [("cinfo", ctypes.POINTER(CommonStructType)), # codec context
|
||||||
# STREAM_READ or STREAM_WRITE
|
# STREAM_READ or STREAM_WRITE
|
||||||
("openmode", ctypes.c_int),
|
("openmode", ctypes.c_int),
|
||||||
# pointer to start of buffer
|
# pointer to start of buffer
|
||||||
|
|
@ -62,15 +61,19 @@ class cio_t(ctypes.Structure):
|
||||||
("bp", ctypes.c_char_p)]
|
("bp", ctypes.c_char_p)]
|
||||||
|
|
||||||
|
|
||||||
class dparameters_t(ctypes.Structure):
|
class DecompressionParametersType(ctypes.Structure):
|
||||||
|
"""Decompression parameters.
|
||||||
|
|
||||||
|
Corresponds to dparameters_t type in openjpeg headers.
|
||||||
|
"""
|
||||||
# cp_reduce: the number of highest resolution levels to be discarded
|
# cp_reduce: the number of highest resolution levels to be discarded
|
||||||
_fields_ = [("cp_reduce", ctypes.c_int),
|
_fields_ = [("cp_reduce", ctypes.c_int),
|
||||||
# cp_layer: the maximum number of quality layers to decode
|
# cp_layer: the maximum number of quality layers to decode
|
||||||
("cp_layer", ctypes.c_int),
|
("cp_layer", ctypes.c_int),
|
||||||
# infile: input file name
|
# infile: input file name
|
||||||
("infile", ctypes.c_char * _PATH_LEN),
|
("infile", ctypes.c_char * PATH_LEN),
|
||||||
# outfile: output file name
|
# outfile: output file name
|
||||||
("outfile", ctypes.c_char * _PATH_LEN),
|
("outfile", ctypes.c_char * PATH_LEN),
|
||||||
# decod_format: input file format 0: J2K, 1: JP2, 2: JPT
|
# decod_format: input file format 0: J2K, 1: JP2, 2: JPT
|
||||||
("decod_format", ctypes.c_int),
|
("decod_format", ctypes.c_int),
|
||||||
# cod_format: output file format 0: PGX, 1: PxM, 2: BMP
|
# cod_format: output file format 0: PGX, 1: PxM, 2: BMP
|
||||||
|
|
@ -87,8 +90,11 @@ class dparameters_t(ctypes.Structure):
|
||||||
("flags", ctypes.c_uint)]
|
("flags", ctypes.c_uint)]
|
||||||
|
|
||||||
|
|
||||||
class image_comp_t(ctypes.Structure):
|
class ImageCompType(ctypes.Structure):
|
||||||
"""Defines a single image component. """
|
"""Defines a single image component.
|
||||||
|
|
||||||
|
Corresponds to image_comp_t type in openjpeg.
|
||||||
|
"""
|
||||||
_fields_ = [("dx", ctypes.c_int),
|
_fields_ = [("dx", ctypes.c_int),
|
||||||
("dy", ctypes.c_int),
|
("dy", ctypes.c_int),
|
||||||
("w", ctypes.c_int),
|
("w", ctypes.c_int),
|
||||||
|
|
@ -103,87 +109,105 @@ class image_comp_t(ctypes.Structure):
|
||||||
("data", ctypes.POINTER(ctypes.c_int))]
|
("data", ctypes.POINTER(ctypes.c_int))]
|
||||||
|
|
||||||
|
|
||||||
class image_t(ctypes.Structure):
|
class ImageType(ctypes.Structure):
|
||||||
"""Defines image data and characteristics."""
|
"""Defines image data and characteristics.
|
||||||
|
|
||||||
|
Corresponds to image_t type in openjpeg headers.
|
||||||
|
"""
|
||||||
_fields_ = [("x0", ctypes.c_int),
|
_fields_ = [("x0", ctypes.c_int),
|
||||||
("y0", ctypes.c_int),
|
("y0", ctypes.c_int),
|
||||||
("x1", ctypes.c_int),
|
("x1", ctypes.c_int),
|
||||||
("y1", ctypes.c_int),
|
("y1", ctypes.c_int),
|
||||||
("numcomps", ctypes.c_int),
|
("numcomps", ctypes.c_int),
|
||||||
("color_space", ctypes.c_int),
|
("color_space", ctypes.c_int),
|
||||||
("comps", ctypes.POINTER(image_comp_t)),
|
("comps", ctypes.POINTER(ImageCompType)),
|
||||||
("icc_profile_buf", ctypes.c_char_p),
|
("icc_profile_buf", ctypes.c_char_p),
|
||||||
("icc_profile_len", ctypes.c_int)]
|
("icc_profile_len", ctypes.c_int)]
|
||||||
|
|
||||||
def _cio_open(cinfo, src):
|
|
||||||
"""Wrapper for openjpeg library function opj_cio_open."""
|
|
||||||
argtypes = [ctypes.POINTER(common_struct_t), ctypes.c_char_p, ctypes.c_int]
|
|
||||||
_OPENJPEG.opj_cio_open.argtypes = argtypes
|
|
||||||
_OPENJPEG.opj_cio_open.restype = ctypes.POINTER(cio_t)
|
|
||||||
|
|
||||||
cio = _OPENJPEG.opj_cio_open(ctypes.cast(cinfo, ctypes.POINTER(common_struct_t)),
|
def cio_open(cinfo, src):
|
||||||
src, len(src))
|
"""Wrapper for openjpeg library function opj_cio_open."""
|
||||||
|
argtypes = [ctypes.POINTER(CommonStructType), ctypes.c_char_p,
|
||||||
|
ctypes.c_int]
|
||||||
|
OPENJPEG.opj_cio_open.argtypes = argtypes
|
||||||
|
OPENJPEG.opj_cio_open.restype = ctypes.POINTER(CioType)
|
||||||
|
|
||||||
|
cio = OPENJPEG.opj_cio_open(ctypes.cast(cinfo,
|
||||||
|
ctypes.POINTER(CommonStructType)),
|
||||||
|
src, len(src))
|
||||||
return cio
|
return cio
|
||||||
|
|
||||||
def _cio_close(cio):
|
|
||||||
|
def cio_close(cio):
|
||||||
"""Wraps openjpeg library function cio_close.
|
"""Wraps openjpeg library function cio_close.
|
||||||
"""
|
"""
|
||||||
_OPENJPEG.opj_cio_close.argtypes = [ctypes.POINTER(cio_t)]
|
OPENJPEG.opj_cio_close.argtypes = [ctypes.POINTER(CioType)]
|
||||||
_OPENJPEG.opj_cio_close(cio)
|
OPENJPEG.opj_cio_close(cio)
|
||||||
|
|
||||||
def _create_decompress(fmt):
|
|
||||||
|
def create_decompress(fmt):
|
||||||
"""Wraps openjpeg library function opj_create_decompress.
|
"""Wraps openjpeg library function opj_create_decompress.
|
||||||
"""
|
"""
|
||||||
_OPENJPEG.opj_create_decompress.argtypes = [ctypes.c_int]
|
OPENJPEG.opj_create_decompress.argtypes = [ctypes.c_int]
|
||||||
_OPENJPEG.opj_create_decompress.restype = ctypes.POINTER(dinfo_t)
|
restype = ctypes.POINTER(DecompressionInfoType)
|
||||||
dinfo = _OPENJPEG.opj_create_decompress(fmt)
|
OPENJPEG.opj_create_decompress.restype = restype
|
||||||
|
dinfo = OPENJPEG.opj_create_decompress(fmt)
|
||||||
return dinfo
|
return dinfo
|
||||||
|
|
||||||
def _decode(dinfo, cio):
|
|
||||||
|
def decode(dinfo, cio):
|
||||||
"""Wrapper for opj_decode.
|
"""Wrapper for opj_decode.
|
||||||
"""
|
"""
|
||||||
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(cio_t)]
|
argtypes = [ctypes.POINTER(DecompressionInfoType), ctypes.POINTER(CioType)]
|
||||||
_OPENJPEG.opj_decode.argtypes = argtypes
|
OPENJPEG.opj_decode.argtypes = argtypes
|
||||||
_OPENJPEG.opj_decode.restype = ctypes.POINTER(image_t)
|
OPENJPEG.opj_decode.restype = ctypes.POINTER(ImageType)
|
||||||
image = _OPENJPEG.opj_decode(dinfo, cio)
|
image = OPENJPEG.opj_decode(dinfo, cio)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def _destroy_decompress(dinfo):
|
|
||||||
|
def destroy_decompress(dinfo):
|
||||||
"""Wraps openjpeg library function opj_destroy_decompress."""
|
"""Wraps openjpeg library function opj_destroy_decompress."""
|
||||||
_OPENJPEG.opj_destroy_decompress.argtypes = [ctypes.POINTER(dinfo_t)]
|
argtypes = [ctypes.POINTER(DecompressionInfoType)]
|
||||||
_OPENJPEG.opj_destroy_decompress(dinfo)
|
OPENJPEG.opj_destroy_decompress.argtypes = argtypes
|
||||||
|
OPENJPEG.opj_destroy_decompress(dinfo)
|
||||||
|
|
||||||
def _image_destroy(image):
|
|
||||||
|
def image_destroy(image):
|
||||||
"""Wraps openjpeg library function opj_image_destroy."""
|
"""Wraps openjpeg library function opj_image_destroy."""
|
||||||
_OPENJPEG.opj_image_destroy.argtypes = [ctypes.POINTER(image_t)]
|
OPENJPEG.opj_image_destroy.argtypes = [ctypes.POINTER(ImageType)]
|
||||||
_OPENJPEG.opj_image_destroy(image)
|
OPENJPEG.opj_image_destroy(image)
|
||||||
|
|
||||||
def _set_default_decoder_parameters(dparams_p):
|
|
||||||
|
def set_default_decoder_parameters(dparams_p):
|
||||||
"""Wrapper for opj_set_default_decoder_parameters.
|
"""Wrapper for opj_set_default_decoder_parameters.
|
||||||
"""
|
"""
|
||||||
argtypes = [ctypes.POINTER(dparameters_t)]
|
argtypes = [ctypes.POINTER(DecompressionParametersType)]
|
||||||
_OPENJPEG.opj_set_default_decoder_parameters.argtypes = argtypes
|
OPENJPEG.opj_set_default_decoder_parameters.argtypes = argtypes
|
||||||
_OPENJPEG.opj_set_default_decoder_parameters(dparams_p)
|
OPENJPEG.opj_set_default_decoder_parameters(dparams_p)
|
||||||
|
|
||||||
|
|
||||||
def _set_event_mgr(dinfo, event_mgr, context=None):
|
def set_event_mgr(dinfo, event_mgr, context=None):
|
||||||
"""Wrapper for openjpeg library function opj_set_event_mgr.
|
"""Wrapper for openjpeg library function opj_set_event_mgr.
|
||||||
"""
|
"""
|
||||||
argtypes = [ctypes.POINTER(common_struct_t),
|
argtypes = [ctypes.POINTER(CommonStructType),
|
||||||
ctypes.POINTER(event_mgr_t),
|
ctypes.POINTER(EventMgrType),
|
||||||
ctypes.c_void_p]
|
ctypes.c_void_p]
|
||||||
_OPENJPEG.opj_set_event_mgr(ctypes.cast(dinfo,
|
OPENJPEG.opj_set_event_mgr.argtypes = argtypes
|
||||||
ctypes.POINTER(common_struct_t)),
|
OPENJPEG.opj_set_event_mgr(ctypes.cast(dinfo,
|
||||||
event_mgr, context)
|
ctypes.POINTER(CommonStructType)),
|
||||||
|
event_mgr, context)
|
||||||
|
|
||||||
def _setup_decoder(dinfo, dparams):
|
|
||||||
|
def setup_decoder(dinfo, dparams):
|
||||||
"""Wrapper for openjpeg library function opj_setup_decoder."""
|
"""Wrapper for openjpeg library function opj_setup_decoder."""
|
||||||
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(dparameters_t)]
|
argtypes = [ctypes.POINTER(DecompressionInfoType),
|
||||||
_OPENJPEG.opj_setup_decoder.argtypes = argtypes
|
ctypes.POINTER(DecompressionParametersType)]
|
||||||
_OPENJPEG.opj_setup_decoder(dinfo, dparams)
|
OPENJPEG.opj_setup_decoder.argtypes = argtypes
|
||||||
|
OPENJPEG.opj_setup_decoder(dinfo, dparams)
|
||||||
|
|
||||||
def _version():
|
|
||||||
|
def version():
|
||||||
"""Wrapper for opj_version library routine."""
|
"""Wrapper for opj_version library routine."""
|
||||||
_OPENJPEG.opj_version.restype = ctypes.c_char_p
|
OPENJPEG.opj_version.restype = ctypes.c_char_p
|
||||||
v = _OPENJPEG.opj_version()
|
library_version = OPENJPEG.opj_version()
|
||||||
return v.decode('utf-8')
|
return library_version.decode('utf-8')
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,7 @@ import numpy as np
|
||||||
import glymur
|
import glymur
|
||||||
|
|
||||||
|
|
||||||
def load_tests(loader, tests, ignore):
|
@unittest.skipIf(glymur.lib._openjp2.OPENJP2 is None,
|
||||||
if glymur.lib.openjp2._OPENJP2 is not None:
|
|
||||||
tests.addTests(doctest.DocTestSuite('glymur.lib.openjp2'))
|
|
||||||
return tests
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
class TestOpenJP2(unittest.TestCase):
|
class TestOpenJP2(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -29,7 +23,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_set_default_encoder_parameters(self):
|
def test_set_default_encoder_parameters(self):
|
||||||
cparams = glymur.lib.openjp2._set_default_encoder_parameters()
|
cparams = glymur.lib._openjp2.set_default_encoder_parameters()
|
||||||
|
|
||||||
self.assertEqual(cparams.res_spec, 0)
|
self.assertEqual(cparams.res_spec, 0)
|
||||||
self.assertEqual(cparams.cblockw_init, 64)
|
self.assertEqual(cparams.cblockw_init, 64)
|
||||||
|
|
@ -38,7 +32,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
self.assertEqual(cparams.subsampling_dx, 1)
|
self.assertEqual(cparams.subsampling_dx, 1)
|
||||||
self.assertEqual(cparams.subsampling_dy, 1)
|
self.assertEqual(cparams.subsampling_dy, 1)
|
||||||
self.assertEqual(cparams.mode, 0)
|
self.assertEqual(cparams.mode, 0)
|
||||||
self.assertEqual(cparams.prog_order, glymur.lib.openjp2.LRCP)
|
self.assertEqual(cparams.prog_order, glymur.core.LRCP)
|
||||||
self.assertEqual(cparams.roi_shift, 0)
|
self.assertEqual(cparams.roi_shift, 0)
|
||||||
self.assertEqual(cparams.cp_tx0, 0)
|
self.assertEqual(cparams.cp_tx0, 0)
|
||||||
self.assertEqual(cparams.cp_ty0, 0)
|
self.assertEqual(cparams.cp_ty0, 0)
|
||||||
|
|
@ -46,7 +40,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
self.assertEqual(cparams.irreversible, 0)
|
self.assertEqual(cparams.irreversible, 0)
|
||||||
|
|
||||||
def test_set_default_decoder_parameters(self):
|
def test_set_default_decoder_parameters(self):
|
||||||
dparams = glymur.lib.openjp2._set_default_decoder_parameters()
|
dparams = glymur.lib._openjp2.set_default_decoder_parameters()
|
||||||
|
|
||||||
self.assertEqual(dparams.DA_x0, 0)
|
self.assertEqual(dparams.DA_x0, 0)
|
||||||
self.assertEqual(dparams.DA_y0, 0)
|
self.assertEqual(dparams.DA_y0, 0)
|
||||||
|
|
@ -55,34 +49,34 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
|
|
||||||
def tile_macro(self, codec, stream, imagep, tidx):
|
def tile_macro(self, codec, stream, imagep, tidx):
|
||||||
# called only by j2k_random_tile_access
|
# called only by j2k_random_tile_access
|
||||||
glymur.lib.openjp2._get_decoded_tile(codec, stream, imagep, tidx)
|
glymur.lib._openjp2.get_decoded_tile(codec, stream, imagep, tidx)
|
||||||
for j in range(imagep.contents.numcomps):
|
for j in range(imagep.contents.numcomps):
|
||||||
self.assertIsNotNone(imagep.contents.comps[j].data)
|
self.assertIsNotNone(imagep.contents.comps[j].data)
|
||||||
|
|
||||||
def j2k_random_tile_access(self, filename, codec_format=None):
|
def j2k_random_tile_access(self, filename, codec_format=None):
|
||||||
# called by the test_rtaX methods
|
# called by the test_rtaX methods
|
||||||
dparam = glymur.lib.openjp2._set_default_decoder_parameters()
|
dparam = glymur.lib._openjp2.set_default_decoder_parameters()
|
||||||
|
|
||||||
infile = filename.encode()
|
infile = filename.encode()
|
||||||
nelts = glymur.lib.openjp2._PATH_LEN - len(infile)
|
nelts = glymur.lib._openjp2.PATH_LEN - len(infile)
|
||||||
infile += b'0' * nelts
|
infile += b'0' * nelts
|
||||||
dparam.infile = infile
|
dparam.infile = infile
|
||||||
|
|
||||||
dparam.decod_format = codec_format
|
dparam.decod_format = codec_format
|
||||||
|
|
||||||
codec = glymur.lib.openjp2._create_decompress(codec_format)
|
codec = glymur.lib._openjp2.create_decompress(codec_format)
|
||||||
|
|
||||||
glymur.lib.openjp2._set_info_handler(codec, None)
|
glymur.lib._openjp2.set_info_handler(codec, None)
|
||||||
glymur.lib.openjp2._set_warning_handler(codec, None)
|
glymur.lib._openjp2.set_warning_handler(codec, None)
|
||||||
glymur.lib.openjp2._set_error_handler(codec, None)
|
glymur.lib._openjp2.set_error_handler(codec, None)
|
||||||
|
|
||||||
x = (filename, True)
|
x = (filename, True)
|
||||||
stream = glymur.lib.openjp2._stream_create_default_file_stream_v3(*x)
|
stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x)
|
||||||
|
|
||||||
glymur.lib.openjp2._setup_decoder(codec, dparam)
|
glymur.lib._openjp2.setup_decoder(codec, dparam)
|
||||||
image = glymur.lib.openjp2._read_header(stream, codec)
|
image = glymur.lib._openjp2.read_header(stream, codec)
|
||||||
|
|
||||||
cstr_info = glymur.lib.openjp2._get_cstr_info(codec)
|
cstr_info = glymur.lib._openjp2.get_cstr_info(codec)
|
||||||
|
|
||||||
tile_ul = 0
|
tile_ul = 0
|
||||||
tile_ur = cstr_info.contents.tw - 1
|
tile_ur = cstr_info.contents.tw - 1
|
||||||
|
|
@ -94,18 +88,18 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
self.tile_macro(codec, stream, image, tile_lr)
|
self.tile_macro(codec, stream, image, tile_lr)
|
||||||
self.tile_macro(codec, stream, image, tile_ll)
|
self.tile_macro(codec, stream, image, tile_ll)
|
||||||
|
|
||||||
glymur.lib.openjp2._destroy_cstr_info(cstr_info)
|
glymur.lib._openjp2.destroy_cstr_info(cstr_info)
|
||||||
|
|
||||||
glymur.lib.openjp2._end_decompress(codec, stream)
|
glymur.lib._openjp2.end_decompress(codec, stream)
|
||||||
glymur.lib.openjp2._destroy_codec(codec)
|
glymur.lib._openjp2.destroy_codec(codec)
|
||||||
glymur.lib.openjp2._stream_destroy_v3(stream)
|
glymur.lib._openjp2.stream_destroy_v3(stream)
|
||||||
glymur.lib.openjp2._image_destroy(image)
|
glymur.lib._openjp2.image_destroy(image)
|
||||||
|
|
||||||
def tile_decoder(self, x0=None, y0=None, x1=None, y1=None, filename=None,
|
def tile_decoder(self, x0=None, y0=None, x1=None, y1=None, filename=None,
|
||||||
codec_format=None):
|
codec_format=None):
|
||||||
x = (filename, True)
|
x = (filename, True)
|
||||||
stream = glymur.lib.openjp2._stream_create_default_file_stream_v3(*x)
|
stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x)
|
||||||
dparam = glymur.lib.openjp2._set_default_decoder_parameters()
|
dparam = glymur.lib._openjp2.set_default_decoder_parameters()
|
||||||
|
|
||||||
dparam.decod_format = codec_format
|
dparam.decod_format = codec_format
|
||||||
|
|
||||||
|
|
@ -115,30 +109,30 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
# do not use resolution reductions.
|
# do not use resolution reductions.
|
||||||
dparam.cp_reduce = 0
|
dparam.cp_reduce = 0
|
||||||
|
|
||||||
codec = glymur.lib.openjp2._create_decompress(codec_format)
|
codec = glymur.lib._openjp2.create_decompress(codec_format)
|
||||||
|
|
||||||
glymur.lib.openjp2._set_info_handler(codec, None)
|
glymur.lib._openjp2.set_info_handler(codec, None)
|
||||||
glymur.lib.openjp2._set_warning_handler(codec, None)
|
glymur.lib._openjp2.set_warning_handler(codec, None)
|
||||||
glymur.lib.openjp2._set_error_handler(codec, None)
|
glymur.lib._openjp2.set_error_handler(codec, None)
|
||||||
|
|
||||||
glymur.lib.openjp2._setup_decoder(codec, dparam)
|
glymur.lib._openjp2.setup_decoder(codec, dparam)
|
||||||
image = glymur.lib.openjp2._read_header(stream, codec)
|
image = glymur.lib._openjp2.read_header(stream, codec)
|
||||||
glymur.lib.openjp2._set_decode_area(codec, image, x0, y0, x1, y1)
|
glymur.lib._openjp2.set_decode_area(codec, image, x0, y0, x1, y1)
|
||||||
|
|
||||||
data = np.zeros((1150, 2048, 3), dtype=np.uint8)
|
data = np.zeros((1150, 2048, 3), dtype=np.uint8)
|
||||||
while True:
|
while True:
|
||||||
rargs = glymur.lib.openjp2._read_tile_header(codec, stream)
|
rargs = glymur.lib._openjp2.read_tile_header(codec, stream)
|
||||||
tidx = rargs[0]
|
tidx = rargs[0]
|
||||||
sz = rargs[1]
|
sz = rargs[1]
|
||||||
go_on = rargs[-1]
|
go_on = rargs[-1]
|
||||||
if not go_on:
|
if not go_on:
|
||||||
break
|
break
|
||||||
glymur.lib.openjp2._decode_tile_data(codec, tidx, data, sz, stream)
|
glymur.lib._openjp2.decode_tile_data(codec, tidx, data, sz, stream)
|
||||||
|
|
||||||
glymur.lib.openjp2._end_decompress(codec, stream)
|
glymur.lib._openjp2.end_decompress(codec, stream)
|
||||||
glymur.lib.openjp2._destroy_codec(codec)
|
glymur.lib._openjp2.destroy_codec(codec)
|
||||||
glymur.lib.openjp2._stream_destroy_v3(stream)
|
glymur.lib._openjp2.stream_destroy_v3(stream)
|
||||||
glymur.lib.openjp2._image_destroy(image)
|
glymur.lib._openjp2.image_destroy(image)
|
||||||
|
|
||||||
def tile_encoder(self, num_comps=None, tile_width=None, tile_height=None,
|
def tile_encoder(self, num_comps=None, tile_width=None, tile_height=None,
|
||||||
filename=None, codec=None, comp_prec=None,
|
filename=None, codec=None, comp_prec=None,
|
||||||
|
|
@ -150,7 +144,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
data = np.random.random((tile_height, tile_width, num_comps))
|
data = np.random.random((tile_height, tile_width, num_comps))
|
||||||
data = (data * 255).astype(np.uint8)
|
data = (data * 255).astype(np.uint8)
|
||||||
|
|
||||||
l_param = glymur.lib.openjp2._set_default_encoder_parameters()
|
l_param = glymur.lib._openjp2.set_default_encoder_parameters()
|
||||||
|
|
||||||
l_param.tcp_numlayers = 1
|
l_param.tcp_numlayers = 1
|
||||||
l_param.cp_fixed_quality = 1
|
l_param.cp_fixed_quality = 1
|
||||||
|
|
@ -170,9 +164,9 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
|
|
||||||
l_param.numresolution = 6
|
l_param.numresolution = 6
|
||||||
|
|
||||||
l_param.prog_order = glymur.lib.openjp2.LRCP
|
l_param.prog_order = glymur.core.LRCP
|
||||||
|
|
||||||
l_params = (glymur.lib.openjp2._image_comptparm_t * num_comps)()
|
l_params = (glymur.lib._openjp2.ImageComptParmType * num_comps)()
|
||||||
for j in range(num_comps):
|
for j in range(num_comps):
|
||||||
l_params[j].dx = 1
|
l_params[j].dx = 1
|
||||||
l_params[j].dy = 1
|
l_params[j].dy = 1
|
||||||
|
|
@ -183,38 +177,38 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
l_params[j].x0 = 0
|
l_params[j].x0 = 0
|
||||||
l_params[j].y0 = 0
|
l_params[j].y0 = 0
|
||||||
|
|
||||||
codec = glymur.lib.openjp2._create_compress(codec)
|
codec = glymur.lib._openjp2.create_compress(codec)
|
||||||
|
|
||||||
glymur.lib.openjp2._set_info_handler(codec, None)
|
glymur.lib._openjp2.set_info_handler(codec, None)
|
||||||
glymur.lib.openjp2._set_warning_handler(codec, None)
|
glymur.lib._openjp2.set_warning_handler(codec, None)
|
||||||
glymur.lib.openjp2._set_error_handler(codec, None)
|
glymur.lib._openjp2.set_error_handler(codec, None)
|
||||||
|
|
||||||
cspace = glymur.lib.openjp2._CLRSPC_SRGB
|
cspace = glymur.lib._openjp2.CLRSPC_SRGB
|
||||||
l_image = glymur.lib.openjp2._image_tile_create(l_params, cspace)
|
l_image = glymur.lib._openjp2.image_tile_create(l_params, cspace)
|
||||||
|
|
||||||
l_image.contents.x0 = 0
|
l_image.contents.x0 = 0
|
||||||
l_image.contents.y0 = 0
|
l_image.contents.y0 = 0
|
||||||
l_image.contents.x1 = image_width
|
l_image.contents.x1 = image_width
|
||||||
l_image.contents.y1 = image_height
|
l_image.contents.y1 = image_height
|
||||||
l_image.contents.color_space = glymur.lib.openjp2._CLRSPC_SRGB
|
l_image.contents.color_space = glymur.lib._openjp2.CLRSPC_SRGB
|
||||||
|
|
||||||
glymur.lib.openjp2._setup_encoder(codec, l_param, l_image)
|
glymur.lib._openjp2.setup_encoder(codec, l_param, l_image)
|
||||||
|
|
||||||
x = (filename, False)
|
x = (filename, False)
|
||||||
stream = glymur.lib.openjp2._stream_create_default_file_stream_v3(*x)
|
stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x)
|
||||||
glymur.lib.openjp2._start_compress(codec, l_image, stream)
|
glymur.lib._openjp2.start_compress(codec, l_image, stream)
|
||||||
|
|
||||||
for j in np.arange(num_tiles):
|
for j in np.arange(num_tiles):
|
||||||
glymur.lib.openjp2._write_tile(codec, j, data, tile_size, stream)
|
glymur.lib._openjp2.write_tile(codec, j, data, tile_size, stream)
|
||||||
|
|
||||||
glymur.lib.openjp2._end_compress(codec, stream)
|
glymur.lib._openjp2.end_compress(codec, stream)
|
||||||
glymur.lib.openjp2._stream_destroy_v3(stream)
|
glymur.lib._openjp2.stream_destroy_v3(stream)
|
||||||
glymur.lib.openjp2._destroy_codec(codec)
|
glymur.lib._openjp2.destroy_codec(codec)
|
||||||
glymur.lib.openjp2._image_destroy(l_image)
|
glymur.lib._openjp2.image_destroy(l_image)
|
||||||
|
|
||||||
def tte0_setup(self, filename):
|
def tte0_setup(self, filename):
|
||||||
kwargs = {'filename': filename,
|
kwargs = {'filename': filename,
|
||||||
'codec': glymur.lib.openjp2._CODEC_J2K,
|
'codec': glymur.lib._openjp2.CODEC_J2K,
|
||||||
'comp_prec': 8,
|
'comp_prec': 8,
|
||||||
'irreversible': 1,
|
'irreversible': 1,
|
||||||
'num_comps': 3,
|
'num_comps': 3,
|
||||||
|
|
@ -241,12 +235,12 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
'x1': 1000,
|
'x1': 1000,
|
||||||
'y1': 1000,
|
'y1': 1000,
|
||||||
'filename': tfile.name,
|
'filename': tfile.name,
|
||||||
'codec_format': glymur.lib.openjp2._CODEC_J2K}
|
'codec_format': glymur.lib._openjp2.CODEC_J2K}
|
||||||
self.tile_decoder(**kwargs)
|
self.tile_decoder(**kwargs)
|
||||||
|
|
||||||
def tte1_setup(self, filename):
|
def tte1_setup(self, filename):
|
||||||
kwargs = {'filename': filename,
|
kwargs = {'filename': filename,
|
||||||
'codec': glymur.lib.openjp2._CODEC_J2K,
|
'codec': glymur.lib._openjp2.CODEC_J2K,
|
||||||
'comp_prec': 8,
|
'comp_prec': 8,
|
||||||
'irreversible': 1,
|
'irreversible': 1,
|
||||||
'num_comps': 3,
|
'num_comps': 3,
|
||||||
|
|
@ -273,7 +267,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
'x1': 128,
|
'x1': 128,
|
||||||
'y1': 128,
|
'y1': 128,
|
||||||
'filename': tfile.name,
|
'filename': tfile.name,
|
||||||
'codec_format': glymur.lib.openjp2._CODEC_J2K}
|
'codec_format': glymur.lib._openjp2.CODEC_J2K}
|
||||||
self.tile_decoder(**kwargs)
|
self.tile_decoder(**kwargs)
|
||||||
|
|
||||||
def test_rta1(self):
|
def test_rta1(self):
|
||||||
|
|
@ -281,12 +275,12 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
# Runs test designated rta1 in OpenJPEG test suite.
|
# Runs test designated rta1 in OpenJPEG test suite.
|
||||||
self.tte1_setup(tfile.name)
|
self.tte1_setup(tfile.name)
|
||||||
|
|
||||||
kwargs = {'codec_format': glymur.lib.openjp2._CODEC_J2K}
|
kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K}
|
||||||
self.j2k_random_tile_access(tfile.name, **kwargs)
|
self.j2k_random_tile_access(tfile.name, **kwargs)
|
||||||
|
|
||||||
def tte2_setup(self, filename):
|
def tte2_setup(self, filename):
|
||||||
kwargs = {'filename': filename,
|
kwargs = {'filename': filename,
|
||||||
'codec': glymur.lib.openjp2._CODEC_JP2,
|
'codec': glymur.lib._openjp2.CODEC_JP2,
|
||||||
'comp_prec': 8,
|
'comp_prec': 8,
|
||||||
'irreversible': 1,
|
'irreversible': 1,
|
||||||
'num_comps': 3,
|
'num_comps': 3,
|
||||||
|
|
@ -312,7 +306,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
'x1': 128,
|
'x1': 128,
|
||||||
'y1': 128,
|
'y1': 128,
|
||||||
'filename': tfile.name,
|
'filename': tfile.name,
|
||||||
'codec_format': glymur.lib.openjp2._CODEC_JP2}
|
'codec_format': glymur.lib._openjp2.CODEC_JP2}
|
||||||
self.tile_decoder(**kwargs)
|
self.tile_decoder(**kwargs)
|
||||||
|
|
||||||
def test_rta2(self):
|
def test_rta2(self):
|
||||||
|
|
@ -320,12 +314,12 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
# Runs test designated rta2 in OpenJPEG test suite.
|
# Runs test designated rta2 in OpenJPEG test suite.
|
||||||
self.tte2_setup(tfile.name)
|
self.tte2_setup(tfile.name)
|
||||||
|
|
||||||
kwargs = {'codec_format': glymur.lib.openjp2._CODEC_JP2}
|
kwargs = {'codec_format': glymur.lib._openjp2.CODEC_JP2}
|
||||||
self.j2k_random_tile_access(tfile.name, **kwargs)
|
self.j2k_random_tile_access(tfile.name, **kwargs)
|
||||||
|
|
||||||
def tte3_setup(self, filename):
|
def tte3_setup(self, filename):
|
||||||
kwargs = {'filename': filename,
|
kwargs = {'filename': filename,
|
||||||
'codec': glymur.lib.openjp2._CODEC_J2K,
|
'codec': glymur.lib._openjp2.CODEC_J2K,
|
||||||
'comp_prec': 8,
|
'comp_prec': 8,
|
||||||
'irreversible': 1,
|
'irreversible': 1,
|
||||||
'num_comps': 1,
|
'num_comps': 1,
|
||||||
|
|
@ -345,12 +339,12 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||||
self.tte3_setup(tfile.name)
|
self.tte3_setup(tfile.name)
|
||||||
|
|
||||||
kwargs = {'codec_format': glymur.lib.openjp2._CODEC_J2K}
|
kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K}
|
||||||
self.j2k_random_tile_access(tfile.name, **kwargs)
|
self.j2k_random_tile_access(tfile.name, **kwargs)
|
||||||
|
|
||||||
def tte4_setup(self, filename):
|
def tte4_setup(self, filename):
|
||||||
kwargs = {'filename': filename,
|
kwargs = {'filename': filename,
|
||||||
'codec': glymur.lib.openjp2._CODEC_J2K,
|
'codec': glymur.lib._openjp2.CODEC_J2K,
|
||||||
'comp_prec': 8,
|
'comp_prec': 8,
|
||||||
'irreversible': 0,
|
'irreversible': 0,
|
||||||
'num_comps': 1,
|
'num_comps': 1,
|
||||||
|
|
@ -370,12 +364,12 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||||
self.tte4_setup(tfile.name)
|
self.tte4_setup(tfile.name)
|
||||||
|
|
||||||
kwargs = {'codec_format': glymur.lib.openjp2._CODEC_J2K}
|
kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K}
|
||||||
self.j2k_random_tile_access(tfile.name, **kwargs)
|
self.j2k_random_tile_access(tfile.name, **kwargs)
|
||||||
|
|
||||||
def tte5_setup(self, filename):
|
def tte5_setup(self, filename):
|
||||||
kwargs = {'filename': filename,
|
kwargs = {'filename': filename,
|
||||||
'codec': glymur.lib.openjp2._CODEC_J2K,
|
'codec': glymur.lib._openjp2.CODEC_J2K,
|
||||||
'comp_prec': 8,
|
'comp_prec': 8,
|
||||||
'irreversible': 0,
|
'irreversible': 0,
|
||||||
'num_comps': 1,
|
'num_comps': 1,
|
||||||
|
|
@ -395,7 +389,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||||
self.tte5_setup(tfile.name)
|
self.tte5_setup(tfile.name)
|
||||||
|
|
||||||
kwargs = {'codec_format': glymur.lib.openjp2._CODEC_J2K}
|
kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K}
|
||||||
self.j2k_random_tile_access(tfile.name, **kwargs)
|
self.j2k_random_tile_access(tfile.name, **kwargs)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import unittest
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
|
@unittest.skipIf(glymur.lib._openjpeg.OPENJPEG is None,
|
||||||
"Missing openjpeg library.")
|
"Missing openjpeg library.")
|
||||||
class TestOpenJPEG(unittest.TestCase):
|
class TestOpenJPEG(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -14,15 +14,15 @@ class TestOpenJPEG(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_version(self):
|
def test_version(self):
|
||||||
v = glymur.lib.openjpeg._version()
|
v = glymur.lib._openjpeg.version()
|
||||||
parts = v.split('.')
|
parts = v.split('.')
|
||||||
self.assertEqual(parts[0], '1')
|
self.assertEqual(parts[0], '1')
|
||||||
self.assertEqual(parts[1], '5')
|
self.assertEqual(parts[1], '5')
|
||||||
|
|
||||||
def test_set_default_decoder_parameters(self):
|
def test_set_default_decoder_parameters(self):
|
||||||
# Verify that we properly set the default decode parameters.
|
# Verify that we properly set the default decode parameters.
|
||||||
dp = glymur.lib.openjpeg.dparameters_t()
|
dp = glymur.lib._openjpeg.DecompressionParametersType()
|
||||||
glymur.lib.openjpeg._set_default_decoder_parameters(ctypes.byref(dp))
|
glymur.lib._openjpeg.set_default_decoder_parameters(ctypes.byref(dp))
|
||||||
|
|
||||||
self.assertEqual(dp.cp_reduce, 0)
|
self.assertEqual(dp.cp_reduce, 0)
|
||||||
self.assertEqual(dp.cp_layer, 0)
|
self.assertEqual(dp.cp_layer, 0)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from .test_jp2k import TestJp2k as jp2k
|
||||||
from .test_icc import TestICC as icc
|
from .test_icc import TestICC as icc
|
||||||
from .test_printing import TestPrinting as printing
|
from .test_printing import TestPrinting as printing
|
||||||
from .test_opj_suite import TestSuite as suite
|
from .test_opj_suite import TestSuite as suite
|
||||||
|
from .test_opj_suite import TestSuiteDump as suitedump
|
||||||
from .test_opj_suite_write import TestSuiteWrite as suitew
|
from .test_opj_suite_write import TestSuiteWrite as suitew
|
||||||
from .test_opj_suite_neg import TestSuiteNegative as suiteneg
|
from .test_opj_suite_neg import TestSuiteNegative as suiteneg
|
||||||
from .test_jp2box import TestJp2Boxes as box
|
from .test_jp2box import TestJp2Boxes as box
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ else:
|
||||||
import glymur
|
import glymur
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
class TestCallbacks(unittest.TestCase):
|
class TestCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@ class TestCallbacks(unittest.TestCase):
|
||||||
# Verify that we get the expected stdio output when our internal info
|
# Verify that we get the expected stdio output when our internal info
|
||||||
# callback handler is enabled.
|
# callback handler is enabled.
|
||||||
j = glymur.Jp2k(self.j2kfile)
|
j = glymur.Jp2k(self.j2kfile)
|
||||||
d = j.read(reduce=1, verbose=True, area=(0, 0, 200, 150))
|
d = j.read(rlevel=1, verbose=True, area=(0, 0, 200, 150))
|
||||||
actual = sys.stdout.getvalue().strip()
|
actual = sys.stdout.getvalue().strip()
|
||||||
|
|
||||||
lines = ['[INFO] Start to read j2k main header (0).',
|
lines = ['[INFO] Start to read j2k main header (0).',
|
||||||
|
|
@ -60,7 +60,7 @@ class TestCallbacks(unittest.TestCase):
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJPEG is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJPEG is None,
|
||||||
"Missing openjpeg library.")
|
"Missing openjpeg library.")
|
||||||
class TestCallbacks15(unittest.TestCase):
|
class TestCallbacks15(unittest.TestCase):
|
||||||
"""This test suite is for OpenJPEG 1.5.1 properties.
|
"""This test suite is for OpenJPEG 1.5.1 properties.
|
||||||
|
|
@ -69,13 +69,13 @@ class TestCallbacks15(unittest.TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
|
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
|
||||||
cls.openjp2 = glymur.lib.openjp2._OPENJP2
|
cls.openjp2 = glymur.lib.openjp2.OPENJP2
|
||||||
glymur.lib.openjp2._OPENJP2 = None
|
glymur.lib.openjp2.OPENJP2 = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
# Restore OPENJP2
|
# Restore OPENJP2
|
||||||
glymur.lib.openjp2._OPENJP2 = cls.openjp2
|
glymur.lib.openjp2.OPENJP2 = cls.openjp2
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Save sys.stdout.
|
# Save sys.stdout.
|
||||||
|
|
@ -92,7 +92,7 @@ class TestCallbacks15(unittest.TestCase):
|
||||||
# Verify that we get the expected stdio output when our internal info
|
# Verify that we get the expected stdio output when our internal info
|
||||||
# callback handler is enabled.
|
# callback handler is enabled.
|
||||||
j = glymur.Jp2k(self.j2kfile)
|
j = glymur.Jp2k(self.j2kfile)
|
||||||
d = j.read(reduce=1, verbose=True)
|
d = j.read(rlevel=1, verbose=True)
|
||||||
actual = sys.stdout.getvalue().strip()
|
actual = sys.stdout.getvalue().strip()
|
||||||
|
|
||||||
regex = re.compile(r"""\[INFO\]\stile\s1\sof\s1\s+
|
regex = re.compile(r"""\[INFO\]\stile\s1\sof\s1\s+
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,9 @@ class TestCodestream(unittest.TestCase):
|
||||||
j = Jp2k(tfile.name)
|
j = Jp2k(tfile.name)
|
||||||
c = j.get_codestream()
|
c = j.get_codestream()
|
||||||
|
|
||||||
self.assertEqual(c.segment[2].id, '0xff6f')
|
self.assertEqual(c.segment[2].marker_id, '0xff6f')
|
||||||
self.assertEqual(c.segment[2].length, 3)
|
self.assertEqual(c.segment[2].length, 3)
|
||||||
self.assertEqual(c.segment[2].data, b'\x00')
|
self.assertEqual(c.segment[2]._data, b'\x00')
|
||||||
|
|
||||||
@unittest.skipIf(sys.hexversion < 0x03020000,
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
"Uses features introduced in 3.2.")
|
"Uses features introduced in 3.2.")
|
||||||
|
|
@ -84,9 +84,9 @@ class TestCodestream(unittest.TestCase):
|
||||||
j = Jp2k(tfile.name)
|
j = Jp2k(tfile.name)
|
||||||
c = j.get_codestream()
|
c = j.get_codestream()
|
||||||
|
|
||||||
self.assertEqual(c.segment[2].id, '0xff79')
|
self.assertEqual(c.segment[2].marker_id, '0xff79')
|
||||||
self.assertEqual(c.segment[2].length, 3)
|
self.assertEqual(c.segment[2].length, 3)
|
||||||
self.assertEqual(c.segment[2].data, b'\x00')
|
self.assertEqual(c.segment[2]._data, b'\x00')
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ from glymur.lib import openjp2 as opj2
|
||||||
|
|
||||||
|
|
||||||
@unittest.skip("Cannot work when both OPENJPEG and OPENJP2 are both present.")
|
@unittest.skip("Cannot work when both OPENJPEG and OPENJP2 are both present.")
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Needs openjp2 library first before these tests make sense.")
|
"Needs openjp2 library first before these tests make sense.")
|
||||||
@unittest.skipIf(sys.hexversion < 0x03020000,
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
"Uses features introduced in 3.2.")
|
"Uses features introduced in 3.2.")
|
||||||
|
|
@ -55,7 +55,7 @@ class TestSuite(unittest.TestCase):
|
||||||
filename = os.path.join(configdir, 'glymurrc')
|
filename = os.path.join(configdir, 'glymurrc')
|
||||||
with open(filename, 'wb') as tfile:
|
with open(filename, 'wb') as tfile:
|
||||||
tfile.write('[library]\n'.encode())
|
tfile.write('[library]\n'.encode())
|
||||||
libloc = glymur.lib.openjp2._OPENJP2._name
|
libloc = glymur.lib.openjp2.OPENJP2._name
|
||||||
line = 'openjp2: {0}\n'.format(libloc)
|
line = 'openjp2: {0}\n'.format(libloc)
|
||||||
tfile.write(line.encode())
|
tfile.write(line.encode())
|
||||||
tfile.flush()
|
tfile.flush()
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ def load_tests(loader, tests, ignore):
|
||||||
return tests
|
return tests
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
class TestChannelDefinition(unittest.TestCase):
|
class TestChannelDefinition(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -58,9 +58,9 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
|
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
|
|
||||||
self.jP = JPEG2000SignatureBox()
|
self.jP = JPEG2000SignatureBox()
|
||||||
self.ftyp = FileTypeBox()
|
self.ftyp = FileTypeBox()
|
||||||
|
|
@ -88,7 +88,7 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
|
|
||||||
jp2 = Jp2k(tfile.name)
|
jp2 = Jp2k(tfile.name)
|
||||||
jp2h = jp2.box[2]
|
jp2h = jp2.box[2]
|
||||||
boxes = [box.id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0, 1, 2))
|
self.assertEqual(jp2h.box[2].index, (0, 1, 2))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0))
|
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0))
|
||||||
|
|
@ -108,7 +108,7 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
|
|
||||||
jp2 = Jp2k(tfile.name)
|
jp2 = Jp2k(tfile.name)
|
||||||
jp2h = jp2.box[2]
|
jp2h = jp2.box[2]
|
||||||
boxes = [box.id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0, 1, 2, 3))
|
self.assertEqual(jp2h.box[2].index, (0, 1, 2, 3))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0, 1))
|
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0, 1))
|
||||||
|
|
@ -141,7 +141,7 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
|
|
||||||
jp2 = Jp2k(tfile.name)
|
jp2 = Jp2k(tfile.name)
|
||||||
jp2h = jp2.box[2]
|
jp2h = jp2.box[2]
|
||||||
boxes = [box.id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0,))
|
self.assertEqual(jp2h.box[2].index, (0,))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0,))
|
self.assertEqual(jp2h.box[2].channel_type, (0,))
|
||||||
|
|
@ -161,7 +161,7 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
|
|
||||||
jp2 = Jp2k(tfile.name)
|
jp2 = Jp2k(tfile.name)
|
||||||
jp2h = jp2.box[2]
|
jp2h = jp2.box[2]
|
||||||
boxes = [box.id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0, 1))
|
self.assertEqual(jp2h.box[2].index, (0, 1))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0, 1))
|
self.assertEqual(jp2h.box[2].channel_type, (0, 1))
|
||||||
|
|
@ -268,9 +268,9 @@ class TestXML(unittest.TestCase):
|
||||||
|
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
|
|
||||||
self.jP = JPEG2000SignatureBox()
|
self.jP = JPEG2000SignatureBox()
|
||||||
self.ftyp = FileTypeBox()
|
self.ftyp = FileTypeBox()
|
||||||
|
|
@ -309,7 +309,7 @@ class TestXML(unittest.TestCase):
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||||
j2k.wrap(tfile.name, boxes=boxes)
|
j2k.wrap(tfile.name, boxes=boxes)
|
||||||
jp2 = Jp2k(tfile.name)
|
jp2 = Jp2k(tfile.name)
|
||||||
self.assertEqual(jp2.box[3].id, 'xml ')
|
self.assertEqual(jp2.box[3].box_id, 'xml ')
|
||||||
self.assertEqual(ET.tostring(jp2.box[3].xml),
|
self.assertEqual(ET.tostring(jp2.box[3].xml),
|
||||||
b'<data>0</data>')
|
b'<data>0</data>')
|
||||||
|
|
||||||
|
|
@ -326,7 +326,7 @@ class TestXML(unittest.TestCase):
|
||||||
j2k.wrap(tfile.name, boxes=boxes)
|
j2k.wrap(tfile.name, boxes=boxes)
|
||||||
jp2 = Jp2k(tfile.name)
|
jp2 = Jp2k(tfile.name)
|
||||||
|
|
||||||
output_boxes = [box.id for box in jp2.box]
|
output_boxes = [box.box_id for box in jp2.box]
|
||||||
self.assertEqual(output_boxes, ['jP ', 'ftyp', 'jp2h', 'xml ',
|
self.assertEqual(output_boxes, ['jP ', 'ftyp', 'jp2h', 'xml ',
|
||||||
'jp2c'])
|
'jp2c'])
|
||||||
|
|
||||||
|
|
@ -345,9 +345,9 @@ class TestColourSpecificationBox(unittest.TestCase):
|
||||||
|
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
|
|
||||||
self.jP = JPEG2000SignatureBox()
|
self.jP = JPEG2000SignatureBox()
|
||||||
self.ftyp = FileTypeBox()
|
self.ftyp = FileTypeBox()
|
||||||
|
|
@ -409,7 +409,7 @@ class TestColourSpecificationBox(unittest.TestCase):
|
||||||
approximation=approx)
|
approximation=approx)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
class TestJp2Boxes(unittest.TestCase):
|
class TestJp2Boxes(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -449,37 +449,37 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
|
|
||||||
def test_default_ContiguousCodestreamBox(self):
|
def test_default_ContiguousCodestreamBox(self):
|
||||||
b = ContiguousCodestreamBox()
|
b = ContiguousCodestreamBox()
|
||||||
self.assertEqual(b.id, 'jp2c')
|
self.assertEqual(b.box_id, 'jp2c')
|
||||||
self.assertEqual(b.main_header, [])
|
self.assertIsNone(b.main_header)
|
||||||
|
|
||||||
def verify_wrapped_raw(self, jp2file):
|
def verify_wrapped_raw(self, jp2file):
|
||||||
# Shared method by at least two tests.
|
# Shared method by at least two tests.
|
||||||
jp2 = Jp2k(jp2file)
|
jp2 = Jp2k(jp2file)
|
||||||
self.assertEqual(len(jp2.box), 4)
|
self.assertEqual(len(jp2.box), 4)
|
||||||
|
|
||||||
self.assertEqual(jp2.box[0].id, 'jP ')
|
self.assertEqual(jp2.box[0].box_id, 'jP ')
|
||||||
self.assertEqual(jp2.box[0].offset, 0)
|
self.assertEqual(jp2.box[0].offset, 0)
|
||||||
self.assertEqual(jp2.box[0].length, 12)
|
self.assertEqual(jp2.box[0].length, 12)
|
||||||
self.assertEqual(jp2.box[0].longname, 'JPEG 2000 Signature')
|
self.assertEqual(jp2.box[0].longname, 'JPEG 2000 Signature')
|
||||||
|
|
||||||
self.assertEqual(jp2.box[1].id, 'ftyp')
|
self.assertEqual(jp2.box[1].box_id, 'ftyp')
|
||||||
self.assertEqual(jp2.box[1].offset, 12)
|
self.assertEqual(jp2.box[1].offset, 12)
|
||||||
self.assertEqual(jp2.box[1].length, 20)
|
self.assertEqual(jp2.box[1].length, 20)
|
||||||
self.assertEqual(jp2.box[1].longname, 'File Type')
|
self.assertEqual(jp2.box[1].longname, 'File Type')
|
||||||
|
|
||||||
self.assertEqual(jp2.box[2].id, 'jp2h')
|
self.assertEqual(jp2.box[2].box_id, 'jp2h')
|
||||||
self.assertEqual(jp2.box[2].offset, 32)
|
self.assertEqual(jp2.box[2].offset, 32)
|
||||||
self.assertEqual(jp2.box[2].length, 45)
|
self.assertEqual(jp2.box[2].length, 45)
|
||||||
self.assertEqual(jp2.box[2].longname, 'JP2 Header')
|
self.assertEqual(jp2.box[2].longname, 'JP2 Header')
|
||||||
|
|
||||||
self.assertEqual(jp2.box[3].id, 'jp2c')
|
self.assertEqual(jp2.box[3].box_id, 'jp2c')
|
||||||
self.assertEqual(jp2.box[3].offset, 77)
|
self.assertEqual(jp2.box[3].offset, 77)
|
||||||
self.assertEqual(jp2.box[3].length, 115228)
|
self.assertEqual(jp2.box[3].length, 115228)
|
||||||
|
|
||||||
# jp2h super box
|
# jp2h super box
|
||||||
self.assertEqual(len(jp2.box[2].box), 2)
|
self.assertEqual(len(jp2.box[2].box), 2)
|
||||||
|
|
||||||
self.assertEqual(jp2.box[2].box[0].id, 'ihdr')
|
self.assertEqual(jp2.box[2].box[0].box_id, 'ihdr')
|
||||||
self.assertEqual(jp2.box[2].box[0].offset, 40)
|
self.assertEqual(jp2.box[2].box[0].offset, 40)
|
||||||
self.assertEqual(jp2.box[2].box[0].length, 22)
|
self.assertEqual(jp2.box[2].box[0].length, 22)
|
||||||
self.assertEqual(jp2.box[2].box[0].longname, 'Image Header')
|
self.assertEqual(jp2.box[2].box[0].longname, 'Image Header')
|
||||||
|
|
@ -492,7 +492,7 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False)
|
self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False)
|
||||||
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
|
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
|
||||||
|
|
||||||
self.assertEqual(jp2.box[2].box[1].id, 'colr')
|
self.assertEqual(jp2.box[2].box[1].box_id, 'colr')
|
||||||
self.assertEqual(jp2.box[2].box[1].offset, 62)
|
self.assertEqual(jp2.box[2].box[1].offset, 62)
|
||||||
self.assertEqual(jp2.box[2].box[1].length, 15)
|
self.assertEqual(jp2.box[2].box[1].length, 15)
|
||||||
self.assertEqual(jp2.box[2].box[1].longname, 'Colour Specification')
|
self.assertEqual(jp2.box[2].box[1].longname, 'Colour Specification')
|
||||||
|
|
@ -511,7 +511,7 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||||
jp2 = j2k.wrap(tfile.name)
|
jp2 = j2k.wrap(tfile.name)
|
||||||
boxes = [box.id for box in jp2.box]
|
boxes = [box.box_id for box in jp2.box]
|
||||||
self.assertEqual(boxes, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
|
self.assertEqual(boxes, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
|
||||||
|
|
||||||
def test_default_layout_but_with_specified_boxes(self):
|
def test_default_layout_but_with_specified_boxes(self):
|
||||||
|
|
@ -521,9 +521,9 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
JP2HeaderBox(),
|
JP2HeaderBox(),
|
||||||
ContiguousCodestreamBox()]
|
ContiguousCodestreamBox()]
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
boxes[2].box = [ImageHeaderBox(height=height,
|
boxes[2].box = [ImageHeaderBox(height=height,
|
||||||
width=width,
|
width=width,
|
||||||
num_components=num_components),
|
num_components=num_components),
|
||||||
|
|
@ -540,9 +540,9 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
JP2HeaderBox(),
|
JP2HeaderBox(),
|
||||||
ContiguousCodestreamBox()]
|
ContiguousCodestreamBox()]
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
boxes[2].box = [ColourSpecificationBox(colorspace=glymur.core.SRGB),
|
boxes[2].box = [ColourSpecificationBox(colorspace=glymur.core.SRGB),
|
||||||
ImageHeaderBox(height=height,
|
ImageHeaderBox(height=height,
|
||||||
width=width,
|
width=width,
|
||||||
|
|
@ -554,9 +554,9 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
def test_first_2_boxes_not_jP_and_ftyp(self):
|
def test_first_2_boxes_not_jP_and_ftyp(self):
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
|
|
||||||
jP = JPEG2000SignatureBox()
|
jP = JPEG2000SignatureBox()
|
||||||
ftyp = FileTypeBox()
|
ftyp = FileTypeBox()
|
||||||
|
|
@ -574,9 +574,9 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
def test_jp2h_not_preceeding_jp2c(self):
|
def test_jp2h_not_preceeding_jp2c(self):
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
|
|
||||||
jP = JPEG2000SignatureBox()
|
jP = JPEG2000SignatureBox()
|
||||||
ftyp = FileTypeBox()
|
ftyp = FileTypeBox()
|
||||||
|
|
@ -594,9 +594,9 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
def test_missing_codestream(self):
|
def test_missing_codestream(self):
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
c = j2k.get_codestream()
|
c = j2k.get_codestream()
|
||||||
height = c.segment[1].Ysiz
|
height = c.segment[1].ysiz
|
||||||
width = c.segment[1].Xsiz
|
width = c.segment[1].xsiz
|
||||||
num_components = len(c.segment[1].XRsiz)
|
num_components = len(c.segment[1].xrsiz)
|
||||||
|
|
||||||
jP = JPEG2000SignatureBox()
|
jP = JPEG2000SignatureBox()
|
||||||
ftyp = FileTypeBox()
|
ftyp = FileTypeBox()
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,12 @@ except:
|
||||||
|
|
||||||
# Doc tests should be run as well.
|
# Doc tests should be run as well.
|
||||||
def load_tests(loader, tests, ignore):
|
def load_tests(loader, tests, ignore):
|
||||||
if glymur.lib.openjp2._OPENJP2 is not None:
|
if glymur.lib.openjp2.OPENJP2 is not None:
|
||||||
tests.addTests(doctest.DocTestSuite('glymur.jp2k'))
|
tests.addTests(doctest.DocTestSuite('glymur.jp2k'))
|
||||||
return tests
|
return tests
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
class TestJp2k(unittest.TestCase):
|
class TestJp2k(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -88,11 +88,11 @@ class TestJp2k(unittest.TestCase):
|
||||||
with self.assertWarns(UserWarning) as cw:
|
with self.assertWarns(UserWarning) as cw:
|
||||||
jp2k = Jp2k(self._bad_xml_file)
|
jp2k = Jp2k(self._bad_xml_file)
|
||||||
|
|
||||||
def test_reduce_max(self):
|
def test_rlevel_max(self):
|
||||||
# Verify that reduce=-1 gets us the lowest resolution image
|
# Verify that rlevel=-1 gets us the lowest resolution image
|
||||||
j = Jp2k(self.j2kfile)
|
j = Jp2k(self.j2kfile)
|
||||||
thumbnail1 = j.read(reduce=-1)
|
thumbnail1 = j.read(rlevel=-1)
|
||||||
thumbnail2 = j.read(reduce=5)
|
thumbnail2 = j.read(rlevel=5)
|
||||||
np.testing.assert_array_equal(thumbnail1, thumbnail2)
|
np.testing.assert_array_equal(thumbnail1, thumbnail2)
|
||||||
self.assertEqual(thumbnail1.shape, (25, 15, 3))
|
self.assertEqual(thumbnail1.shape, (25, 15, 3))
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
jp2k = Jp2k(self._bad_xml_file)
|
jp2k = Jp2k(self._bad_xml_file)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[3].id, 'xml ')
|
self.assertEqual(jp2k.box[3].box_id, 'xml ')
|
||||||
self.assertEqual(jp2k.box[3].offset, 77)
|
self.assertEqual(jp2k.box[3].offset, 77)
|
||||||
self.assertEqual(jp2k.box[3].length, 28)
|
self.assertEqual(jp2k.box[3].length, 28)
|
||||||
self.assertIsNone(jp2k.box[3].xml)
|
self.assertIsNone(jp2k.box[3].xml)
|
||||||
|
|
@ -120,11 +120,11 @@ class TestJp2k(unittest.TestCase):
|
||||||
# End corner must be >= start corner
|
# End corner must be >= start corner
|
||||||
d = j.read(area=(10, 10, 8, 8))
|
d = j.read(area=(10, 10, 8, 8))
|
||||||
|
|
||||||
def test_reduce_too_high(self):
|
def test_rlevel_too_high(self):
|
||||||
# Verify that we error out appropriately if not given a JPEG 2000 file.
|
# Verify that we error out appropriately if not given a JPEG 2000 file.
|
||||||
j = Jp2k(self.jp2file)
|
j = Jp2k(self.jp2file)
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
d = j.read(reduce=6)
|
d = j.read(rlevel=6)
|
||||||
|
|
||||||
def test_not_JPEG2000(self):
|
def test_not_JPEG2000(self):
|
||||||
# Verify that we error out appropriately if not given a JPEG 2000 file.
|
# Verify that we error out appropriately if not given a JPEG 2000 file.
|
||||||
|
|
@ -153,7 +153,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
np.testing.assert_array_equal(actdata, expdata)
|
np.testing.assert_array_equal(actdata, expdata)
|
||||||
|
|
||||||
c = ofile.get_codestream()
|
c = ofile.get_codestream()
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 0) # no mct
|
self.assertEqual(c.segment[2].spcod[3], 0) # no mct
|
||||||
|
|
||||||
def test_write_grayscale_with_mct(self):
|
def test_write_grayscale_with_mct(self):
|
||||||
# MCT usage makes no sense for grayscale images.
|
# MCT usage makes no sense for grayscale images.
|
||||||
|
|
@ -167,7 +167,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
def test_write_cprl(self):
|
def test_write_cprl(self):
|
||||||
# Issue 17
|
# Issue 17
|
||||||
j = Jp2k(self.jp2file)
|
j = Jp2k(self.jp2file)
|
||||||
expdata = j.read(reduce=1)
|
expdata = j.read(rlevel=1)
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
ofile = Jp2k(tfile.name, 'wb')
|
ofile = Jp2k(tfile.name, 'wb')
|
||||||
ofile.write(expdata, prog='CPRL')
|
ofile.write(expdata, prog='CPRL')
|
||||||
|
|
@ -175,7 +175,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
np.testing.assert_array_equal(actdata, expdata)
|
np.testing.assert_array_equal(actdata, expdata)
|
||||||
|
|
||||||
c = ofile.get_codestream()
|
c = ofile.get_codestream()
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.CPRL)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.CPRL)
|
||||||
|
|
||||||
def test_jp2_boxes(self):
|
def test_jp2_boxes(self):
|
||||||
# Verify the boxes of a JP2 file.
|
# Verify the boxes of a JP2 file.
|
||||||
|
|
@ -184,37 +184,37 @@ class TestJp2k(unittest.TestCase):
|
||||||
# top-level boxes
|
# top-level boxes
|
||||||
self.assertEqual(len(jp2k.box), 6)
|
self.assertEqual(len(jp2k.box), 6)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[0].id, 'jP ')
|
self.assertEqual(jp2k.box[0].box_id, 'jP ')
|
||||||
self.assertEqual(jp2k.box[0].offset, 0)
|
self.assertEqual(jp2k.box[0].offset, 0)
|
||||||
self.assertEqual(jp2k.box[0].length, 12)
|
self.assertEqual(jp2k.box[0].length, 12)
|
||||||
self.assertEqual(jp2k.box[0].longname, 'JPEG 2000 Signature')
|
self.assertEqual(jp2k.box[0].longname, 'JPEG 2000 Signature')
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[1].id, 'ftyp')
|
self.assertEqual(jp2k.box[1].box_id, 'ftyp')
|
||||||
self.assertEqual(jp2k.box[1].offset, 12)
|
self.assertEqual(jp2k.box[1].offset, 12)
|
||||||
self.assertEqual(jp2k.box[1].length, 20)
|
self.assertEqual(jp2k.box[1].length, 20)
|
||||||
self.assertEqual(jp2k.box[1].longname, 'File Type')
|
self.assertEqual(jp2k.box[1].longname, 'File Type')
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[2].id, 'jp2h')
|
self.assertEqual(jp2k.box[2].box_id, 'jp2h')
|
||||||
self.assertEqual(jp2k.box[2].offset, 32)
|
self.assertEqual(jp2k.box[2].offset, 32)
|
||||||
self.assertEqual(jp2k.box[2].length, 45)
|
self.assertEqual(jp2k.box[2].length, 45)
|
||||||
self.assertEqual(jp2k.box[2].longname, 'JP2 Header')
|
self.assertEqual(jp2k.box[2].longname, 'JP2 Header')
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[3].id, 'uuid')
|
self.assertEqual(jp2k.box[3].box_id, 'uuid')
|
||||||
self.assertEqual(jp2k.box[3].offset, 77)
|
self.assertEqual(jp2k.box[3].offset, 77)
|
||||||
self.assertEqual(jp2k.box[3].length, 638)
|
self.assertEqual(jp2k.box[3].length, 638)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[4].id, 'uuid')
|
self.assertEqual(jp2k.box[4].box_id, 'uuid')
|
||||||
self.assertEqual(jp2k.box[4].offset, 715)
|
self.assertEqual(jp2k.box[4].offset, 715)
|
||||||
self.assertEqual(jp2k.box[4].length, 2412)
|
self.assertEqual(jp2k.box[4].length, 2412)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[5].id, 'jp2c')
|
self.assertEqual(jp2k.box[5].box_id, 'jp2c')
|
||||||
self.assertEqual(jp2k.box[5].offset, 3127)
|
self.assertEqual(jp2k.box[5].offset, 3127)
|
||||||
self.assertEqual(jp2k.box[5].length, 1132296)
|
self.assertEqual(jp2k.box[5].length, 1132296)
|
||||||
|
|
||||||
# jp2h super box
|
# jp2h super box
|
||||||
self.assertEqual(len(jp2k.box[2].box), 2)
|
self.assertEqual(len(jp2k.box[2].box), 2)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[2].box[0].id, 'ihdr')
|
self.assertEqual(jp2k.box[2].box[0].box_id, 'ihdr')
|
||||||
self.assertEqual(jp2k.box[2].box[0].offset, 40)
|
self.assertEqual(jp2k.box[2].box[0].offset, 40)
|
||||||
self.assertEqual(jp2k.box[2].box[0].length, 22)
|
self.assertEqual(jp2k.box[2].box[0].length, 22)
|
||||||
self.assertEqual(jp2k.box[2].box[0].longname, 'Image Header')
|
self.assertEqual(jp2k.box[2].box[0].longname, 'Image Header')
|
||||||
|
|
@ -227,7 +227,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
self.assertEqual(jp2k.box[2].box[0].colorspace_unknown, False)
|
self.assertEqual(jp2k.box[2].box[0].colorspace_unknown, False)
|
||||||
self.assertEqual(jp2k.box[2].box[0].ip_provided, False)
|
self.assertEqual(jp2k.box[2].box[0].ip_provided, False)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[2].box[1].id, 'colr')
|
self.assertEqual(jp2k.box[2].box[1].box_id, 'colr')
|
||||||
self.assertEqual(jp2k.box[2].box[1].offset, 62)
|
self.assertEqual(jp2k.box[2].box[1].offset, 62)
|
||||||
self.assertEqual(jp2k.box[2].box[1].length, 15)
|
self.assertEqual(jp2k.box[2].box[1].length, 15)
|
||||||
self.assertEqual(jp2k.box[2].box[1].longname, 'Colour Specification')
|
self.assertEqual(jp2k.box[2].box[1].longname, 'Colour Specification')
|
||||||
|
|
@ -272,7 +272,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
|
|
||||||
jp2k = Jp2k(tfile.name)
|
jp2k = Jp2k(tfile.name)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[5].id, 'jp2c')
|
self.assertEqual(jp2k.box[5].box_id, 'jp2c')
|
||||||
self.assertEqual(jp2k.box[5].offset, 3127)
|
self.assertEqual(jp2k.box[5].offset, 3127)
|
||||||
self.assertEqual(jp2k.box[5].length, 1133427 + 8)
|
self.assertEqual(jp2k.box[5].length, 1133427 + 8)
|
||||||
|
|
||||||
|
|
@ -303,8 +303,8 @@ class TestJp2k(unittest.TestCase):
|
||||||
|
|
||||||
# The top level boxes in each file should match.
|
# The top level boxes in each file should match.
|
||||||
for j in range(len(baseline_jp2.box)):
|
for j in range(len(baseline_jp2.box)):
|
||||||
self.assertEqual(new_jp2.box[j].id,
|
self.assertEqual(new_jp2.box[j].box_id,
|
||||||
baseline_jp2.box[j].id)
|
baseline_jp2.box[j].box_id)
|
||||||
self.assertEqual(new_jp2.box[j].offset,
|
self.assertEqual(new_jp2.box[j].offset,
|
||||||
baseline_jp2.box[j].offset)
|
baseline_jp2.box[j].offset)
|
||||||
self.assertEqual(new_jp2.box[j].length,
|
self.assertEqual(new_jp2.box[j].length,
|
||||||
|
|
@ -344,7 +344,7 @@ class TestJp2k(unittest.TestCase):
|
||||||
c = j.get_codestream()
|
c = j.get_codestream()
|
||||||
|
|
||||||
# Code block size is reported as XY in the codestream.
|
# Code block size is reported as XY in the codestream.
|
||||||
self.assertEqual(tuple(c.segment[2].SPcod[5:7]), (3, 2))
|
self.assertEqual(tuple(c.segment[2].spcod[5:7]), (3, 2))
|
||||||
|
|
||||||
def test_negative_too_many_dimensions(self):
|
def test_negative_too_many_dimensions(self):
|
||||||
# OpenJP2 only allows 2D or 3D images.
|
# OpenJP2 only allows 2D or 3D images.
|
||||||
|
|
@ -479,23 +479,23 @@ class TestJp2k(unittest.TestCase):
|
||||||
|
|
||||||
jp2k = Jp2k(tfile.name)
|
jp2k = Jp2k(tfile.name)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[3].id, 'uinf')
|
self.assertEqual(jp2k.box[3].box_id, 'uinf')
|
||||||
self.assertEqual(jp2k.box[3].offset, 77)
|
self.assertEqual(jp2k.box[3].offset, 77)
|
||||||
self.assertEqual(jp2k.box[3].length, 50)
|
self.assertEqual(jp2k.box[3].length, 50)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[3].box[0].id, 'ulst')
|
self.assertEqual(jp2k.box[3].box[0].box_id, 'ulst')
|
||||||
self.assertEqual(jp2k.box[3].box[0].offset, 85)
|
self.assertEqual(jp2k.box[3].box[0].offset, 85)
|
||||||
self.assertEqual(jp2k.box[3].box[0].length, 26)
|
self.assertEqual(jp2k.box[3].box[0].length, 26)
|
||||||
ulst = []
|
ulst = []
|
||||||
ulst.append(uuid.UUID('00000000-0000-0000-0000-000000000000'))
|
ulst.append(uuid.UUID('00000000-0000-0000-0000-000000000000'))
|
||||||
self.assertEqual(jp2k.box[3].box[0].ulst, ulst)
|
self.assertEqual(jp2k.box[3].box[0].ulst, ulst)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[3].box[1].id, 'url ')
|
self.assertEqual(jp2k.box[3].box[1].box_id, 'url ')
|
||||||
self.assertEqual(jp2k.box[3].box[1].offset, 111)
|
self.assertEqual(jp2k.box[3].box[1].offset, 111)
|
||||||
self.assertEqual(jp2k.box[3].box[1].length, 16)
|
self.assertEqual(jp2k.box[3].box[1].length, 16)
|
||||||
self.assertEqual(jp2k.box[3].box[1].version, 0)
|
self.assertEqual(jp2k.box[3].box[1].version, 0)
|
||||||
self.assertEqual(jp2k.box[3].box[1].flag, (0, 0, 0))
|
self.assertEqual(jp2k.box[3].box[1].flag, (0, 0, 0))
|
||||||
self.assertEqual(jp2k.box[3].box[1].URL, 'abcd')
|
self.assertEqual(jp2k.box[3].box[1].url, 'abcd')
|
||||||
|
|
||||||
def test_xml_box_with_trailing_nulls(self):
|
def test_xml_box_with_trailing_nulls(self):
|
||||||
# ElementTree does not like trailing null chars after valid XML
|
# ElementTree does not like trailing null chars after valid XML
|
||||||
|
|
@ -522,14 +522,14 @@ class TestJp2k(unittest.TestCase):
|
||||||
|
|
||||||
jp2k = Jp2k(tfile.name)
|
jp2k = Jp2k(tfile.name)
|
||||||
|
|
||||||
self.assertEqual(jp2k.box[3].id, 'xml ')
|
self.assertEqual(jp2k.box[3].box_id, 'xml ')
|
||||||
self.assertEqual(jp2k.box[3].offset, 77)
|
self.assertEqual(jp2k.box[3].offset, 77)
|
||||||
self.assertEqual(jp2k.box[3].length, 36)
|
self.assertEqual(jp2k.box[3].length, 36)
|
||||||
|
|
||||||
def test_asoc_label_box(self):
|
def test_asoc_label_box(self):
|
||||||
# Construct a fake file with an asoc and a label box, as
|
# Construct a fake file with an asoc and a label box, as
|
||||||
# OpenJPEG doesn't have such a file.
|
# OpenJPEG doesn't have such a file.
|
||||||
data = Jp2k(self.jp2file).read(reduce=1)
|
data = Jp2k(self.jp2file).read(rlevel=1)
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
j = Jp2k(tfile.name, 'wb')
|
j = Jp2k(tfile.name, 'wb')
|
||||||
j.write(data)
|
j.write(data)
|
||||||
|
|
@ -567,10 +567,10 @@ class TestJp2k(unittest.TestCase):
|
||||||
tfile2.flush()
|
tfile2.flush()
|
||||||
|
|
||||||
jasoc = Jp2k(tfile2.name)
|
jasoc = Jp2k(tfile2.name)
|
||||||
self.assertEqual(jasoc.box[3].id, 'asoc')
|
self.assertEqual(jasoc.box[3].box_id, 'asoc')
|
||||||
self.assertEqual(jasoc.box[3].box[0].id, 'lbl ')
|
self.assertEqual(jasoc.box[3].box[0].box_id, 'lbl ')
|
||||||
self.assertEqual(jasoc.box[3].box[0].label, 'label')
|
self.assertEqual(jasoc.box[3].box[0].label, 'label')
|
||||||
self.assertEqual(jasoc.box[3].box[1].id, 'xml ')
|
self.assertEqual(jasoc.box[3].box[1].box_id, 'xml ')
|
||||||
|
|
||||||
def test_openjpeg_library_message(self):
|
def test_openjpeg_library_message(self):
|
||||||
# Verify the error message produced by the openjpeg library.
|
# Verify the error message produced by the openjpeg library.
|
||||||
|
|
@ -599,11 +599,11 @@ class TestJp2k(unittest.TestCase):
|
||||||
Invalid\svalues\sfor\scomp\s=\s0\s+
|
Invalid\svalues\sfor\scomp\s=\s0\s+
|
||||||
:\sdx=1\sdy=0''', re.VERBOSE)
|
:\sdx=1\sdy=0''', re.VERBOSE)
|
||||||
if sys.hexversion < 0x03020000:
|
if sys.hexversion < 0x03020000:
|
||||||
with self.assertRaisesRegexp(IOError, regexp) as ce:
|
with self.assertRaisesRegexp((IOError, OSError), regexp) as ce:
|
||||||
d = j.read(reduce=3)
|
d = j.read(rlevel=1)
|
||||||
else:
|
else:
|
||||||
with self.assertRaisesRegex(IOError, regexp) as ce:
|
with self.assertRaisesRegex((IOError, OSError), regexp) as ce:
|
||||||
d = j.read(reduce=3)
|
d = j.read(rlevel=1)
|
||||||
|
|
||||||
def test_xmp_attribute(self):
|
def test_xmp_attribute(self):
|
||||||
# Verify that we can read the XMP packet in our shipping example file.
|
# Verify that we can read the XMP packet in our shipping example file.
|
||||||
|
|
@ -648,20 +648,20 @@ class TestJp2k(unittest.TestCase):
|
||||||
self.assertFalse('Make' in exif['Image'].keys())
|
self.assertFalse('Make' in exif['Image'].keys())
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
|
@unittest.skipIf(glymur.lib.openjpeg.OPENJPEG is None,
|
||||||
"Missing openjpeg library.")
|
"Missing openjpeg library.")
|
||||||
class TestJp2k15(unittest.TestCase):
|
class TestJp2k15(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
|
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
|
||||||
cls.openjp2 = glymur.lib.openjp2._OPENJP2
|
cls.openjp2 = glymur.lib.openjp2.OPENJP2
|
||||||
glymur.lib.openjp2._OPENJP2 = None
|
glymur.lib.openjp2.OPENJP2 = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
# Restore OPENJP2
|
# Restore OPENJP2
|
||||||
glymur.lib.openjp2._OPENJP2 = cls.openjp2
|
glymur.lib.openjp2.OPENJP2 = cls.openjp2
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.jp2file = glymur.data.nemo()
|
self.jp2file = glymur.data.nemo()
|
||||||
|
|
@ -699,7 +699,7 @@ class TestJp2k15(unittest.TestCase):
|
||||||
# and OPJ_DATA_ROOT is not set. We need at least one
|
# and OPJ_DATA_ROOT is not set. We need at least one
|
||||||
# working JP2 test.
|
# working JP2 test.
|
||||||
j2k = Jp2k(self.jp2file)
|
j2k = Jp2k(self.jp2file)
|
||||||
d = j2k.read(reduce=1)
|
d = j2k.read(rlevel=1)
|
||||||
|
|
||||||
def test_basic_j2k(self):
|
def test_basic_j2k(self):
|
||||||
# This test is only useful when openjp2 is not available
|
# This test is only useful when openjp2 is not available
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -57,7 +57,7 @@ def read_image(infile):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
@unittest.skipIf(no_read_backend, no_read_backend_msg)
|
@unittest.skipIf(no_read_backend, no_read_backend_msg)
|
||||||
@unittest.skipIf(data_root is None,
|
@unittest.skipIf(data_root is None,
|
||||||
|
|
@ -94,7 +94,7 @@ class TestSuiteNegative(unittest.TestCase):
|
||||||
# Verify that the last segment returned in the codestream is SOD,
|
# Verify that the last segment returned in the codestream is SOD,
|
||||||
# not EOC. Codestream parsing should stop when we try to jump to
|
# not EOC. Codestream parsing should stop when we try to jump to
|
||||||
# the end of SOT.
|
# the end of SOT.
|
||||||
self.assertEqual(c.segment[-1].id, 'SOD')
|
self.assertEqual(c.segment[-1].marker_id, 'SOD')
|
||||||
|
|
||||||
@unittest.skipIf(sys.hexversion < 0x03020000,
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
"Uses features introduced in 3.2.")
|
"Uses features introduced in 3.2.")
|
||||||
|
|
@ -109,7 +109,7 @@ class TestSuiteNegative(unittest.TestCase):
|
||||||
# Verify that the last segment returned in the codestream is SOD,
|
# Verify that the last segment returned in the codestream is SOD,
|
||||||
# not EOC. Codestream parsing should stop when we try to jump to
|
# not EOC. Codestream parsing should stop when we try to jump to
|
||||||
# the end of SOT.
|
# the end of SOT.
|
||||||
self.assertEqual(c.segment[-1].id, 'SOD')
|
self.assertEqual(c.segment[-1].marker_id, 'SOD')
|
||||||
|
|
||||||
@unittest.skipIf(sys.hexversion < 0x03020000,
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
"Uses features introduced in 3.2.")
|
"Uses features introduced in 3.2.")
|
||||||
|
|
@ -124,7 +124,7 @@ class TestSuiteNegative(unittest.TestCase):
|
||||||
# Verify that the last segment returned in the codestream is SOD,
|
# Verify that the last segment returned in the codestream is SOD,
|
||||||
# not EOC. Codestream parsing should stop when we try to jump to
|
# not EOC. Codestream parsing should stop when we try to jump to
|
||||||
# the end of SOT.
|
# the end of SOT.
|
||||||
self.assertEqual(c.segment[-1].id, 'SOD')
|
self.assertEqual(c.segment[-1].marker_id, 'SOD')
|
||||||
|
|
||||||
def test_code_block_dimensions(self):
|
def test_code_block_dimensions(self):
|
||||||
# opj_compress doesn't allow the dimensions of a codeblock
|
# opj_compress doesn't allow the dimensions of a codeblock
|
||||||
|
|
@ -157,7 +157,7 @@ class TestSuiteNegative(unittest.TestCase):
|
||||||
def test_precinct_size_not_multiple_of_two(self):
|
def test_precinct_size_not_multiple_of_two(self):
|
||||||
# Seems like precinct sizes should be powers of two.
|
# Seems like precinct sizes should be powers of two.
|
||||||
ifile = Jp2k(self.j2kfile)
|
ifile = Jp2k(self.j2kfile)
|
||||||
data = ifile.read(reduce=2)
|
data = ifile.read(rlevel=2)
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
ofile = Jp2k(tfile.name, 'wb')
|
ofile = Jp2k(tfile.name, 'wb')
|
||||||
with self.assertRaises(IOError) as ce:
|
with self.assertRaises(IOError) as ce:
|
||||||
|
|
@ -166,7 +166,7 @@ class TestSuiteNegative(unittest.TestCase):
|
||||||
def test_codeblock_size_not_multiple_of_two(self):
|
def test_codeblock_size_not_multiple_of_two(self):
|
||||||
# Seems like code block sizes should be powers of two.
|
# Seems like code block sizes should be powers of two.
|
||||||
ifile = Jp2k(self.j2kfile)
|
ifile = Jp2k(self.j2kfile)
|
||||||
data = ifile.read(reduce=2)
|
data = ifile.read(rlevel=2)
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
ofile = Jp2k(tfile.name, 'wb')
|
ofile = Jp2k(tfile.name, 'wb')
|
||||||
with self.assertRaises(IOError) as ce:
|
with self.assertRaises(IOError) as ce:
|
||||||
|
|
@ -176,7 +176,7 @@ class TestSuiteNegative(unittest.TestCase):
|
||||||
# Seems like code block sizes should never exceed half that of
|
# Seems like code block sizes should never exceed half that of
|
||||||
# precinct size.
|
# precinct size.
|
||||||
ifile = Jp2k(self.j2kfile)
|
ifile = Jp2k(self.j2kfile)
|
||||||
data = ifile.read(reduce=2)
|
data = ifile.read(rlevel=2)
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
ofile = Jp2k(tfile.name, 'wb')
|
ofile = Jp2k(tfile.name, 'wb')
|
||||||
with self.assertRaises(IOError) as ce:
|
with self.assertRaises(IOError) as ce:
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ def read_image(infile):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
@unittest.skipIf(no_read_backend, no_read_backend_msg)
|
@unittest.skipIf(no_read_backend, no_read_backend_msg)
|
||||||
@unittest.skipIf(data_root is None,
|
@unittest.skipIf(data_root is None,
|
||||||
|
|
@ -83,50 +83,50 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding bypass
|
# Selective arithmetic coding bypass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# Reset context probabilities
|
# Reset context probabilities
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass
|
# Termination on each coding pass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context
|
# Vertically causal context
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination
|
# Predictable termination
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols
|
# Segmentation symbols
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
def test_NR_ENC_Bretagne1_ppm_2_encode(self):
|
def test_NR_ENC_Bretagne1_ppm_2_encode(self):
|
||||||
# NR-ENC-Bretagne1.ppm-2-encode
|
# NR-ENC-Bretagne1.ppm-2-encode
|
||||||
|
|
@ -141,50 +141,50 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 1) # levels
|
self.assertEqual(c.segment[2].spcod[4], 1) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding bypass
|
# Selective arithmetic coding bypass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# Reset context probabilities
|
# Reset context probabilities
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass
|
# Termination on each coding pass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context
|
# Vertically causal context
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination
|
# Predictable termination
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols
|
# Segmentation symbols
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
def test_NR_ENC_Bretagne1_ppm_3_encode(self):
|
def test_NR_ENC_Bretagne1_ppm_3_encode(self):
|
||||||
# NR-ENC-Bretagne1.ppm-3-encode
|
# NR-ENC-Bretagne1.ppm-3-encode
|
||||||
|
|
@ -200,49 +200,49 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(16, 16)) # cblksz
|
(16, 16)) # cblksz
|
||||||
# Selective arithmetic coding bypass
|
# Selective arithmetic coding bypass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# Reset context probabilities
|
# Reset context probabilities
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass
|
# Termination on each coding pass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context
|
# Vertically causal context
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination
|
# Predictable termination
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols
|
# Segmentation symbols
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(c.segment[2]._precinct_size,
|
self.assertEqual(c.segment[2]._precinct_size,
|
||||||
[(2, 2), (4, 4), (8, 8), (16, 16), (32, 32),
|
[(2, 2), (4, 4), (8, 8), (16, 16), (32, 32),
|
||||||
(64, 64)])
|
(64, 64)])
|
||||||
|
|
@ -263,49 +263,49 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(data.shape[1], data.shape[0]))
|
(data.shape[1], data.shape[0]))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size. Reported as XY, not RC.
|
# Tile size. Reported as XY, not RC.
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(32, 32)) # cblksz
|
(32, 32)) # cblksz
|
||||||
# Selective arithmetic coding bypass
|
# Selective arithmetic coding bypass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# Reset context probabilities
|
# Reset context probabilities
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass
|
# Termination on each coding pass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context
|
# Vertically causal context
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination
|
# Predictable termination
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols
|
# Segmentation symbols
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(c.segment[2]._precinct_size,
|
self.assertEqual(c.segment[2]._precinct_size,
|
||||||
[(16, 16), (32, 32), (64, 64)] + [(128, 128)] * 3)
|
[(16, 16), (32, 32), (64, 64)] + [(128, 128)] * 3)
|
||||||
|
|
||||||
|
|
@ -321,50 +321,50 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(data.shape[1], data.shape[0]))
|
(data.shape[1], data.shape[0]))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(127, 127))
|
(127, 127))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.PCRL)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding bypass
|
# Selective arithmetic coding bypass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# Reset context probabilities
|
# Reset context probabilities
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass
|
# Termination on each coding pass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context
|
# Vertically causal context
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination
|
# Predictable termination
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols
|
# Segmentation symbols
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
def test_NR_ENC_Bretagne2_ppm_6_encode(self):
|
def test_NR_ENC_Bretagne2_ppm_6_encode(self):
|
||||||
# NR-ENC-Bretagne2.ppm-6-encode
|
# NR-ENC-Bretagne2.ppm-6-encode
|
||||||
|
|
@ -378,53 +378,53 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(5183, 3887))
|
(5183, 3887))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(5183, 3887))
|
(5183, 3887))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(2, 2)] * 3)
|
[(2, 2)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertTrue(c.segment[2].Scod & 2) # sop
|
self.assertTrue(c.segment[2].scod & 2) # sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding bypass
|
# Selective arithmetic coding bypass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# Reset context probabilities
|
# Reset context probabilities
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass
|
# Termination on each coding pass
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context
|
# Vertically causal context
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination
|
# Predictable termination
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols
|
# Segmentation symbols
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
# 18 SOP segments.
|
# 18 SOP segments.
|
||||||
nsops = [x.Nsop for x in c.segment if x.id == 'SOP']
|
nsops = [x.nsop for x in c.segment if x.marker_id == 'SOP']
|
||||||
self.assertEqual(nsops, list(range(18)))
|
self.assertEqual(nsops, list(range(18)))
|
||||||
|
|
||||||
def test_NR_ENC_Bretagne2_ppm_7_encode(self):
|
def test_NR_ENC_Bretagne2_ppm_7_encode(self):
|
||||||
|
|
@ -438,53 +438,53 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(2592, 1944))
|
(2592, 1944))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(2592, 1944))
|
(2592, 1944))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertTrue(c.segment[2].Scod & 4) # eph
|
self.assertTrue(c.segment[2].scod & 4) # eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding BYPASS
|
# Selective arithmetic coding BYPASS
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# RESET context probabilities (RESET)
|
# RESET context probabilities (RESET)
|
||||||
self.assertTrue(c.segment[2].SPcod[7] & 0x02)
|
self.assertTrue(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass, RESTART(TERMALL)
|
# Termination on each coding pass, RESTART(TERMALL)
|
||||||
self.assertTrue(c.segment[2].SPcod[7] & 0x04)
|
self.assertTrue(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context (VSC)
|
# Vertically causal context (VSC)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination, ERTERM(SEGTERM)
|
# Predictable termination, ERTERM(SEGTERM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols, SEGMARK(SEGSYSM)
|
# Segmentation symbols, SEGMARK(SEGSYSM)
|
||||||
self.assertTrue(c.segment[2].SPcod[7] & 0x0020)
|
self.assertTrue(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
# 18 EPH segments.
|
# 18 EPH segments.
|
||||||
ephs = [x for x in c.segment if x.id == 'EPH']
|
ephs = [x for x in c.segment if x.marker_id == 'EPH']
|
||||||
self.assertEqual(len(ephs), 18)
|
self.assertEqual(len(ephs), 18)
|
||||||
|
|
||||||
def test_NR_ENC_Bretagne2_ppm_8_encode(self):
|
def test_NR_ENC_Bretagne2_ppm_8_encode(self):
|
||||||
|
|
@ -498,51 +498,51 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(2742, 2244))
|
(2742, 2244))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz),
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz),
|
||||||
(150, 300))
|
(150, 300))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(2742, 2244))
|
(2742, 2244))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding BYPASS
|
# Selective arithmetic coding BYPASS
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# RESET context probabilities (RESET)
|
# RESET context probabilities (RESET)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass, RESTART(TERMALL)
|
# Termination on each coding pass, RESTART(TERMALL)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context (VSC)
|
# Vertically causal context (VSC)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination, ERTERM(SEGTERM)
|
# Predictable termination, ERTERM(SEGTERM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols, SEGMARK(SEGSYSM)
|
# Segmentation symbols, SEGMARK(SEGSYSM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
def test_NR_ENC_Cevennes1_bmp_9_encode(self):
|
def test_NR_ENC_Cevennes1_bmp_9_encode(self):
|
||||||
infile = os.path.join(data_root, 'input/nonregression/Cevennes1.bmp')
|
infile = os.path.join(data_root, 'input/nonregression/Cevennes1.bmp')
|
||||||
|
|
@ -555,50 +555,50 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(2592, 1944))
|
(2592, 1944))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(2592, 1944))
|
(2592, 1944))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding BYPASS
|
# Selective arithmetic coding BYPASS
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# RESET context probabilities (RESET)
|
# RESET context probabilities (RESET)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass, RESTART(TERMALL)
|
# Termination on each coding pass, RESTART(TERMALL)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context (VSC)
|
# Vertically causal context (VSC)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination, ERTERM(SEGTERM)
|
# Predictable termination, ERTERM(SEGTERM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols, SEGMARK(SEGSYSM)
|
# Segmentation symbols, SEGMARK(SEGSYSM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
def test_NR_ENC_Cevennes2_ppm_10_encode(self):
|
def test_NR_ENC_Cevennes2_ppm_10_encode(self):
|
||||||
infile = os.path.join(data_root, 'input/nonregression/Cevennes2.ppm')
|
infile = os.path.join(data_root, 'input/nonregression/Cevennes2.ppm')
|
||||||
|
|
@ -611,50 +611,50 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding BYPASS
|
# Selective arithmetic coding BYPASS
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# RESET context probabilities (RESET)
|
# RESET context probabilities (RESET)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass, RESTART(TERMALL)
|
# Termination on each coding pass, RESTART(TERMALL)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context (VSC)
|
# Vertically causal context (VSC)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination, ERTERM(SEGTERM)
|
# Predictable termination, ERTERM(SEGTERM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols, SEGMARK(SEGSYSM)
|
# Segmentation symbols, SEGMARK(SEGSYSM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
def test_NR_ENC_Rome_bmp_11_encode(self):
|
def test_NR_ENC_Rome_bmp_11_encode(self):
|
||||||
infile = os.path.join(data_root, 'input/nonregression/Rome.bmp')
|
infile = os.path.join(data_root, 'input/nonregression/Rome.bmp')
|
||||||
|
|
@ -663,11 +663,11 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
jp2 = Jp2k(tfile.name, 'wb')
|
jp2 = Jp2k(tfile.name, 'wb')
|
||||||
jp2.write(data, psnr=[30, 35, 50], prog='LRCP', numres=3)
|
jp2.write(data, psnr=[30, 35, 50], prog='LRCP', numres=3)
|
||||||
|
|
||||||
ids = [box.id for box in jp2.box]
|
ids = [box.box_id for box in jp2.box]
|
||||||
lst = ['jP ', 'ftyp', 'jp2h', 'jp2c']
|
lst = ['jP ', 'ftyp', 'jp2h', 'jp2c']
|
||||||
self.assertEqual(ids, lst)
|
self.assertEqual(ids, lst)
|
||||||
|
|
||||||
ids = [box.id for box in jp2.box[2].box]
|
ids = [box.box_id for box in jp2.box[2].box]
|
||||||
self.assertEqual(ids, ['ihdr', 'colr'])
|
self.assertEqual(ids, ['ihdr', 'colr'])
|
||||||
|
|
||||||
# Signature box. Check for corruption.
|
# Signature box. Check for corruption.
|
||||||
|
|
@ -701,51 +701,51 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz),
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(640, 480))
|
(640, 480))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
self.assertEqual(c.segment[1]._signed, (False, False, False))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)] * 3)
|
[(1, 1)] * 3)
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
|
self.assertEqual(c.segment[2].spcod[3], 1) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 2) # levels
|
self.assertEqual(c.segment[2].spcod[4], 2) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding BYPASS
|
# Selective arithmetic coding BYPASS
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# RESET context probabilities (RESET)
|
# RESET context probabilities (RESET)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass, RESTART(TERMALL)
|
# Termination on each coding pass, RESTART(TERMALL)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context (VSC)
|
# Vertically causal context (VSC)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination, ERTERM(SEGTERM)
|
# Predictable termination, ERTERM(SEGTERM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols, SEGMARK(SEGSYSM)
|
# Segmentation symbols, SEGMARK(SEGSYSM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
@unittest.skip("Known failure in openjpeg test suite.")
|
@unittest.skip("Known failure in openjpeg test suite.")
|
||||||
def test_NR_ENC_random_issue_0005_tif_12_encode(self):
|
def test_NR_ENC_random_issue_0005_tif_12_encode(self):
|
||||||
|
|
@ -762,50 +762,50 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
|
|
||||||
# SIZ: Image and tile size
|
# SIZ: Image and tile size
|
||||||
# Profile: "0" means profile 2
|
# Profile: "0" means profile 2
|
||||||
self.assertEqual(c.segment[1].Rsiz, 0)
|
self.assertEqual(c.segment[1].rsiz, 0)
|
||||||
# Reference grid size
|
# Reference grid size
|
||||||
self.assertEqual((c.segment[1].Xsiz, c.segment[1].Ysiz),
|
self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz),
|
||||||
(1024, 1024))
|
(1024, 1024))
|
||||||
# Reference grid offset
|
# Reference grid offset
|
||||||
self.assertEqual((c.segment[1].XOsiz, c.segment[1].YOsiz), (0, 0))
|
self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0))
|
||||||
# Tile size
|
# Tile size
|
||||||
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
|
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
|
||||||
(1024, 1024))
|
(1024, 1024))
|
||||||
# Tile offset
|
# Tile offset
|
||||||
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
|
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
|
||||||
(0, 0))
|
(0, 0))
|
||||||
# bitdepth
|
# bitdepth
|
||||||
self.assertEqual(c.segment[1]._bitdepth, (16,))
|
self.assertEqual(c.segment[1]._bitdepth, (16,))
|
||||||
# signed
|
# signed
|
||||||
self.assertEqual(c.segment[1]._signed, (False,))
|
self.assertEqual(c.segment[1]._signed, (False,))
|
||||||
# subsampling
|
# subsampling
|
||||||
self.assertEqual(list(zip(c.segment[1].XRsiz, c.segment[1].YRsiz)),
|
self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)),
|
||||||
[(1, 1)])
|
[(1, 1)])
|
||||||
|
|
||||||
# COD: Coding style default
|
# COD: Coding style default
|
||||||
self.assertFalse(c.segment[2].Scod & 2) # no sop
|
self.assertFalse(c.segment[2].scod & 2) # no sop
|
||||||
self.assertFalse(c.segment[2].Scod & 4) # no eph
|
self.assertFalse(c.segment[2].scod & 4) # no eph
|
||||||
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
|
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
|
||||||
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
|
||||||
self.assertEqual(c.segment[2].SPcod[3], 0) # mct
|
self.assertEqual(c.segment[2].spcod[3], 0) # mct
|
||||||
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
|
self.assertEqual(c.segment[2].spcod[4], 5) # levels
|
||||||
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
self.assertEqual(tuple(c.segment[2]._code_block_size),
|
||||||
(64, 64)) # cblksz
|
(64, 64)) # cblksz
|
||||||
# Selective arithmetic coding BYPASS
|
# Selective arithmetic coding BYPASS
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
|
self.assertFalse(c.segment[2].spcod[7] & 0x01)
|
||||||
# RESET context probabilities (RESET)
|
# RESET context probabilities (RESET)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
|
self.assertFalse(c.segment[2].spcod[7] & 0x02)
|
||||||
# Termination on each coding pass, RESTART(TERMALL)
|
# Termination on each coding pass, RESTART(TERMALL)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
|
self.assertFalse(c.segment[2].spcod[7] & 0x04)
|
||||||
# Vertically causal context (VSC)
|
# Vertically causal context (VSC)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
|
self.assertFalse(c.segment[2].spcod[7] & 0x08)
|
||||||
# Predictable termination, ERTERM(SEGTERM)
|
# Predictable termination, ERTERM(SEGTERM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
|
||||||
# Segmentation symbols, SEGMARK(SEGSYSM)
|
# Segmentation symbols, SEGMARK(SEGSYSM)
|
||||||
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
|
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
|
||||||
self.assertEqual(c.segment[2].SPcod[8],
|
self.assertEqual(c.segment[2].spcod[8],
|
||||||
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
|
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||||
self.assertEqual(len(c.segment[2].SPcod), 9)
|
self.assertEqual(len(c.segment[2].spcod), 9)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
class TestPrintingNeedsLib(unittest.TestCase):
|
class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
"""These tests require the library, mostly in order to just setup the test.
|
"""These tests require the library, mostly in order to just setup the test.
|
||||||
|
|
@ -34,7 +34,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2', delete=False) as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2', delete=False) as tfile:
|
||||||
cls._plain_nemo_file = tfile.name
|
cls._plain_nemo_file = tfile.name
|
||||||
ijfile = Jp2k(jp2file)
|
ijfile = Jp2k(jp2file)
|
||||||
data = ijfile.read(reduce=1)
|
data = ijfile.read(rlevel=1)
|
||||||
ojfile = Jp2k(cls._plain_nemo_file, 'wb')
|
ojfile = Jp2k(cls._plain_nemo_file, 'wb')
|
||||||
ojfile.write(data)
|
ojfile.write(data)
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
def test_asoc_label_box(self):
|
def test_asoc_label_box(self):
|
||||||
# Construct a fake file with an asoc and a label box, as
|
# Construct a fake file with an asoc and a label box, as
|
||||||
# OpenJPEG doesn't have such a file.
|
# OpenJPEG doesn't have such a file.
|
||||||
data = glymur.Jp2k(self.jp2file).read(reduce=1)
|
data = glymur.Jp2k(self.jp2file).read(rlevel=1)
|
||||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
j = glymur.Jp2k(tfile.name, 'wb')
|
j = glymur.Jp2k(tfile.name, 'wb')
|
||||||
j.write(data)
|
j.write(data)
|
||||||
|
|
@ -640,6 +640,7 @@ class TestPrinting(unittest.TestCase):
|
||||||
' CME marker segment @ (3209, 37)',
|
' CME marker segment @ (3209, 37)',
|
||||||
' "Created by OpenJPEG version 2.0.0"']
|
' "Created by OpenJPEG version 2.0.0"']
|
||||||
expected = '\n'.join(lst)
|
expected = '\n'.join(lst)
|
||||||
|
self.maxDiff = None
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
@unittest.skipIf(data_root is None,
|
@unittest.skipIf(data_root is None,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue