Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0815db6c0d | ||
|
|
a783f6f139 | ||
|
|
6abf184ad7 | ||
|
|
67456c3b89 | ||
|
|
3d60d30871 | ||
|
|
1a2aa8397b | ||
|
|
dc0c1950a2 |
7 changed files with 412 additions and 168 deletions
290
glymur/jp2k.py
290
glymur/jp2k.py
|
|
@ -157,7 +157,7 @@ class Jp2k(Jp2kBox):
|
||||||
msg += "profile if the file type box brand is 'jp2 '."
|
msg += "profile if the file type box brand is 'jp2 '."
|
||||||
warnings.warn(msg)
|
warnings.warn(msg)
|
||||||
|
|
||||||
def _set_cinema_params(self, cparams, cinema_mode, fps):
|
def _set_cinema_params(self, cinema_mode, fps):
|
||||||
"""Populate compression parameters structure for cinema2K.
|
"""Populate compression parameters structure for cinema2K.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -176,7 +176,7 @@ class Jp2k(Jp2kBox):
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
# Cinema modes imply MCT.
|
# Cinema modes imply MCT.
|
||||||
cparams.tcp_mct = 1
|
self._cparams.tcp_mct = 1
|
||||||
|
|
||||||
if cinema_mode == 'cinema2k':
|
if cinema_mode == 'cinema2k':
|
||||||
if fps not in [24, 48]:
|
if fps not in [24, 48]:
|
||||||
|
|
@ -185,30 +185,28 @@ class Jp2k(Jp2kBox):
|
||||||
if re.match("2.0", version.openjpeg_version) is not None:
|
if re.match("2.0", version.openjpeg_version) is not None:
|
||||||
# 2.0 API
|
# 2.0 API
|
||||||
if fps == 24:
|
if fps == 24:
|
||||||
cparams.cp_cinema = core.OPJ_CINEMA2K_24
|
self._cparams.cp_cinema = core.OPJ_CINEMA2K_24
|
||||||
else:
|
else:
|
||||||
cparams.cp_cinema = core.OPJ_CINEMA2K_48
|
self._cparams.cp_cinema = core.OPJ_CINEMA2K_48
|
||||||
else:
|
else:
|
||||||
# 2.1 API
|
# 2.1 API
|
||||||
if fps == 24:
|
if fps == 24:
|
||||||
cparams.rsiz = core.OPJ_PROFILE_CINEMA_2K
|
self._cparams.rsiz = core.OPJ_PROFILE_CINEMA_2K
|
||||||
cparams.max_comp_size = core.OPJ_CINEMA_24_COMP
|
self._cparams.max_comp_size = core.OPJ_CINEMA_24_COMP
|
||||||
cparams.max_cs_size = core.OPJ_CINEMA_24_CS
|
self._cparams.max_cs_size = core.OPJ_CINEMA_24_CS
|
||||||
else:
|
else:
|
||||||
cparams.rsiz = core.OPJ_PROFILE_CINEMA_2K
|
self._cparams.rsiz = core.OPJ_PROFILE_CINEMA_2K
|
||||||
cparams.max_comp_size = core.OPJ_CINEMA_48_COMP
|
self._cparams.max_comp_size = core.OPJ_CINEMA_48_COMP
|
||||||
cparams.max_cs_size = core.OPJ_CINEMA_48_CS
|
self._cparams.max_cs_size = core.OPJ_CINEMA_48_CS
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# cinema4k
|
# cinema4k
|
||||||
if re.match("2.0", version.openjpeg_version) is not None:
|
if re.match("2.0", version.openjpeg_version) is not None:
|
||||||
# 2.0 API
|
# 2.0 API
|
||||||
cparams.cp_cinema = core.OPJ_CINEMA4K_24
|
self._cparams.cp_cinema = core.OPJ_CINEMA4K_24
|
||||||
else:
|
else:
|
||||||
# 2.1 API
|
# 2.1 API
|
||||||
cparams.rsiz = core.OPJ_PROFILE_CINEMA_4K
|
self._cparams.rsiz = core.OPJ_PROFILE_CINEMA_4K
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _populate_cparams(self, img_array, **kwargs):
|
def _populate_cparams(self, img_array, **kwargs):
|
||||||
"""Directs processing of write method arguments.
|
"""Directs processing of write method arguments.
|
||||||
|
|
@ -219,11 +217,6 @@ class Jp2k(Jp2kBox):
|
||||||
image data to be written to file
|
image data to be written to file
|
||||||
kwargs : dictionary
|
kwargs : dictionary
|
||||||
non-image keyword inputs provided to write method
|
non-image keyword inputs provided to write method
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
cparams : CompressionParametersType(ctypes.Structure)
|
|
||||||
corresponds to cparameters_t openjpeg datatype
|
|
||||||
"""
|
"""
|
||||||
if (('cinema2k' in kwargs or 'cinema4k' in kwargs) and
|
if (('cinema2k' in kwargs or 'cinema4k' in kwargs) and
|
||||||
(len(set(kwargs)) > 1)):
|
(len(set(kwargs)) > 1)):
|
||||||
|
|
@ -258,12 +251,14 @@ class Jp2k(Jp2kBox):
|
||||||
cparams.irreversible = 1
|
cparams.irreversible = 1
|
||||||
|
|
||||||
if 'cinema2k' in kwargs:
|
if 'cinema2k' in kwargs:
|
||||||
self._set_cinema_params(cparams, 'cinema2k', kwargs['cinema2k'])
|
self._cparams = cparams
|
||||||
return cparams
|
self._set_cinema_params('cinema2k', kwargs['cinema2k'])
|
||||||
|
return
|
||||||
|
|
||||||
if 'cinema4k' in kwargs:
|
if 'cinema4k' in kwargs:
|
||||||
self._set_cinema_params(cparams, 'cinema4k', kwargs['cinema4k'])
|
self._cparams = cparams
|
||||||
return cparams
|
self._set_cinema_params('cinema4k', kwargs['cinema4k'])
|
||||||
|
return
|
||||||
|
|
||||||
if 'cbsize' in kwargs:
|
if 'cbsize' in kwargs:
|
||||||
cparams.cblockw_init = kwargs['cbsize'][1]
|
cparams.cblockw_init = kwargs['cbsize'][1]
|
||||||
|
|
@ -337,7 +332,7 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
self._validate_compression_params(img_array, cparams, **kwargs)
|
self._validate_compression_params(img_array, cparams, **kwargs)
|
||||||
|
|
||||||
return cparams
|
self._cparams = cparams
|
||||||
|
|
||||||
def write(self, img_array, verbose=False, **kwargs):
|
def write(self, img_array, verbose=False, **kwargs):
|
||||||
"""Write image data to a JP2/JPX/J2k file. Intended usage of the
|
"""Write image data to a JP2/JPX/J2k file. Intended usage of the
|
||||||
|
|
@ -412,14 +407,14 @@ class Jp2k(Jp2kBox):
|
||||||
"in order to write images.")
|
"in order to write images.")
|
||||||
|
|
||||||
self._determine_colorspace(img_array, **kwargs)
|
self._determine_colorspace(img_array, **kwargs)
|
||||||
cparams = self._populate_cparams(img_array, **kwargs)
|
self._populate_cparams(img_array, **kwargs)
|
||||||
|
|
||||||
if opj2.OPENJP2 is not None:
|
if opj2.OPENJP2 is not None:
|
||||||
self._write_openjp2(img_array, cparams, verbose=verbose)
|
self._write_openjp2(img_array, verbose=verbose)
|
||||||
else:
|
else:
|
||||||
self._write_openjpeg(img_array, cparams, verbose=verbose)
|
self._write_openjpeg(img_array, verbose=verbose)
|
||||||
|
|
||||||
def _write_openjpeg(self, img_array, cparams, verbose=False):
|
def _write_openjpeg(self, img_array, verbose=False):
|
||||||
"""
|
"""
|
||||||
Write JPEG 2000 file using OpenJPEG 1.5 interface.
|
Write JPEG 2000 file using OpenJPEG 1.5 interface.
|
||||||
"""
|
"""
|
||||||
|
|
@ -429,21 +424,21 @@ class Jp2k(Jp2kBox):
|
||||||
img_array.shape[1],
|
img_array.shape[1],
|
||||||
1)
|
1)
|
||||||
|
|
||||||
comptparms = _populate_comptparms(img_array, cparams)
|
self._populate_comptparms(img_array)
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
image = opj.image_create(comptparms, self._colorspace)
|
image = opj.image_create(self._comptparms, self._colorspace)
|
||||||
stack.callback(opj.image_destroy, image)
|
stack.callback(opj.image_destroy, image)
|
||||||
|
|
||||||
numrows, numcols, numlayers = img_array.shape
|
numrows, numcols, numlayers = img_array.shape
|
||||||
|
|
||||||
# set image offset and reference grid
|
# set image offset and reference grid
|
||||||
image.contents.x0 = cparams.image_offset_x0
|
image.contents.x0 = self._cparams.image_offset_x0
|
||||||
image.contents.y0 = cparams.image_offset_y0
|
image.contents.y0 = self._cparams.image_offset_y0
|
||||||
image.contents.x1 = image.contents.x0 \
|
image.contents.x1 = image.contents.x0 \
|
||||||
+ (numcols - 1) * cparams.subsampling_dx + 1
|
+ (numcols - 1) * self._cparams.subsampling_dx + 1
|
||||||
image.contents.y1 = image.contents.y0 \
|
image.contents.y1 = image.contents.y0 \
|
||||||
+ (numrows - 1) * cparams.subsampling_dy + 1
|
+ (numrows - 1) * self._cparams.subsampling_dy + 1
|
||||||
|
|
||||||
# Stage the image data to the openjpeg data structure.
|
# Stage the image data to the openjpeg data structure.
|
||||||
for k in range(0, numlayers):
|
for k in range(0, numlayers):
|
||||||
|
|
@ -453,7 +448,7 @@ class Jp2k(Jp2kBox):
|
||||||
src = layer.ctypes.data
|
src = layer.ctypes.data
|
||||||
ctypes.memmove(dest, src, layer.nbytes)
|
ctypes.memmove(dest, src, layer.nbytes)
|
||||||
|
|
||||||
cinfo = opj.create_compress(cparams.codec_fmt)
|
cinfo = opj.create_compress(self._cparams.codec_fmt)
|
||||||
stack.callback(opj.destroy_compress, cinfo)
|
stack.callback(opj.destroy_compress, cinfo)
|
||||||
|
|
||||||
# Setup the info, warning, and error handlers.
|
# Setup the info, warning, and error handlers.
|
||||||
|
|
@ -467,7 +462,7 @@ class Jp2k(Jp2kBox):
|
||||||
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.setup_encoder(cinfo, ctypes.byref(cparams), image)
|
opj.setup_encoder(cinfo, ctypes.byref(self._cparams), image)
|
||||||
|
|
||||||
cio = opj.cio_open(cinfo)
|
cio = opj.cio_open(cinfo)
|
||||||
stack.callback(opj.cio_close, cio)
|
stack.callback(opj.cio_close, cio)
|
||||||
|
|
@ -588,7 +583,7 @@ class Jp2k(Jp2kBox):
|
||||||
self._colorspace = _COLORSPACE_MAP[colorspace.lower()]
|
self._colorspace = _COLORSPACE_MAP[colorspace.lower()]
|
||||||
|
|
||||||
|
|
||||||
def _write_openjp2(self, img_array, cparams, verbose=False):
|
def _write_openjp2(self, img_array, verbose=False):
|
||||||
"""
|
"""
|
||||||
Write JPEG 2000 file using OpenJPEG 2.x interface.
|
Write JPEG 2000 file using OpenJPEG 2.x interface.
|
||||||
"""
|
"""
|
||||||
|
|
@ -597,15 +592,15 @@ class Jp2k(Jp2kBox):
|
||||||
numrows, numcols = img_array.shape
|
numrows, numcols = img_array.shape
|
||||||
img_array = img_array.reshape(numrows, numcols, 1)
|
img_array = img_array.reshape(numrows, numcols, 1)
|
||||||
|
|
||||||
comptparms = _populate_comptparms(img_array, cparams)
|
self._populate_comptparms(img_array)
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
image = opj2.image_create(comptparms, self._colorspace)
|
image = opj2.image_create(self._comptparms, self._colorspace)
|
||||||
stack.callback(opj2.image_destroy, image)
|
stack.callback(opj2.image_destroy, image)
|
||||||
|
|
||||||
_populate_image_struct(cparams, image, img_array)
|
self._populate_image_struct(image, img_array)
|
||||||
|
|
||||||
codec = opj2.create_compress(cparams.codec_fmt)
|
codec = opj2.create_compress(self._cparams.codec_fmt)
|
||||||
stack.callback(opj2.destroy_codec, codec)
|
stack.callback(opj2.destroy_codec, codec)
|
||||||
|
|
||||||
info_handler = _INFO_CALLBACK if verbose else None
|
info_handler = _INFO_CALLBACK if verbose else None
|
||||||
|
|
@ -613,7 +608,7 @@ class Jp2k(Jp2kBox):
|
||||||
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, self._cparams, image)
|
||||||
|
|
||||||
if re.match("2.0", version.openjpeg_version) is not None:
|
if re.match("2.0", version.openjpeg_version) is not None:
|
||||||
fptr = libc.fopen(self.filename, 'wb')
|
fptr = libc.fopen(self.filename, 'wb')
|
||||||
|
|
@ -1020,13 +1015,13 @@ class Jp2k(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
self._subsampling_sanity_check()
|
self._subsampling_sanity_check()
|
||||||
|
|
||||||
dparameters = self._populate_dparam(rlevel, ignore_pclr_cmap_cdef)
|
self._populate_dparams(rlevel, ignore_pclr_cmap_cdef)
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
try:
|
try:
|
||||||
dparameters.decod_format = self._codec_format
|
self._dparams.decod_format = self._codec_format
|
||||||
|
|
||||||
dinfo = opj.create_decompress(dparameters.decod_format)
|
dinfo = opj.create_decompress(self._dparams.decod_format)
|
||||||
|
|
||||||
event_mgr = opj.EventMgrType()
|
event_mgr = opj.EventMgrType()
|
||||||
info_handler = ctypes.cast(_INFO_CALLBACK, ctypes.c_void_p)
|
info_handler = ctypes.cast(_INFO_CALLBACK, ctypes.c_void_p)
|
||||||
|
|
@ -1037,7 +1032,7 @@ class Jp2k(Jp2kBox):
|
||||||
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, self._dparams)
|
||||||
|
|
||||||
with open(self.filename, 'rb') as fptr:
|
with open(self.filename, 'rb') as fptr:
|
||||||
src = fptr.read()
|
src = fptr.read()
|
||||||
|
|
@ -1104,8 +1099,8 @@ class Jp2k(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
self._subsampling_sanity_check()
|
self._subsampling_sanity_check()
|
||||||
|
|
||||||
dparam = self._populate_dparam(rlevel, ignore_pclr_cmap_cdef,
|
self._populate_dparams(rlevel, ignore_pclr_cmap_cdef,
|
||||||
layer=layer, tile=tile, area=area)
|
layer=layer, tile=tile, area=area)
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
if re.match("2.1", version.openjpeg_version):
|
if re.match("2.1", version.openjpeg_version):
|
||||||
|
|
@ -1127,16 +1122,17 @@ class Jp2k(Jp2kBox):
|
||||||
else:
|
else:
|
||||||
opj2.set_info_handler(codec, None)
|
opj2.set_info_handler(codec, None)
|
||||||
|
|
||||||
opj2.setup_decoder(codec, dparam)
|
opj2.setup_decoder(codec, self._dparams)
|
||||||
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 self._dparams.nb_tile_to_decode:
|
||||||
opj2.get_decoded_tile(codec, stream, image, dparam.tile_index)
|
opj2.get_decoded_tile(codec, stream, image,
|
||||||
|
self._dparams.tile_index)
|
||||||
else:
|
else:
|
||||||
opj2.set_decode_area(codec, image,
|
opj2.set_decode_area(codec, image,
|
||||||
dparam.DA_x0, dparam.DA_y0,
|
self._dparams.DA_x0, self._dparams.DA_y0,
|
||||||
dparam.DA_x1, dparam.DA_y1)
|
self._dparams.DA_x1, self._dparams.DA_y1)
|
||||||
opj2.decode(codec, stream, image)
|
opj2.decode(codec, stream, image)
|
||||||
opj2.end_decompress(codec, stream)
|
opj2.end_decompress(codec, stream)
|
||||||
|
|
||||||
|
|
@ -1147,8 +1143,8 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
return img_array
|
return img_array
|
||||||
|
|
||||||
def _populate_dparam(self, rlevel, ignore_pclr_cmap_cdef, tile=None,
|
def _populate_dparams(self, rlevel, ignore_pclr_cmap_cdef, tile=None,
|
||||||
layer=None, area=None):
|
layer=None, area=None):
|
||||||
"""Populate decompression structure with appropriate input parameters.
|
"""Populate decompression structure with appropriate input parameters.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -1165,11 +1161,6 @@ class Jp2k(Jp2kBox):
|
||||||
ignore_pclr_cmap_cdef : bool
|
ignore_pclr_cmap_cdef : bool
|
||||||
Whether or not to ignore the pclr, cmap, or cdef boxes during any
|
Whether or not to ignore the pclr, cmap, or cdef boxes during any
|
||||||
color transformation. Defaults to False.
|
color transformation. Defaults to False.
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
dparam : DecompressionParametersType (ctypes)
|
|
||||||
Corresponds to openjp2 decompression parameters structure.
|
|
||||||
"""
|
"""
|
||||||
if opj2.OPENJP2 is not None:
|
if opj2.OPENJP2 is not None:
|
||||||
dparam = opj2.set_default_decoder_parameters()
|
dparam = opj2.set_default_decoder_parameters()
|
||||||
|
|
@ -1220,7 +1211,7 @@ class Jp2k(Jp2kBox):
|
||||||
# Return raw codestream components.
|
# Return raw codestream components.
|
||||||
dparam.flags |= 1
|
dparam.flags |= 1
|
||||||
|
|
||||||
return dparam
|
self._dparams = dparam
|
||||||
|
|
||||||
def read_bands(self, rlevel=0, layer=0, area=None, tile=None,
|
def read_bands(self, rlevel=0, layer=0, area=None, tile=None,
|
||||||
verbose=False, ignore_pclr_cmap_cdef=False):
|
verbose=False, ignore_pclr_cmap_cdef=False):
|
||||||
|
|
@ -1268,8 +1259,8 @@ class Jp2k(Jp2kBox):
|
||||||
"OpenJPEG installed before using this "
|
"OpenJPEG installed before using this "
|
||||||
"functionality.")
|
"functionality.")
|
||||||
|
|
||||||
dparam = self._populate_dparam(rlevel, ignore_pclr_cmap_cdef,
|
self._populate_dparams(rlevel, ignore_pclr_cmap_cdef,
|
||||||
layer=layer, tile=tile, area=area)
|
layer=layer, tile=tile, area=area)
|
||||||
|
|
||||||
with ExitStack() as stack:
|
with ExitStack() as stack:
|
||||||
if re.match("2.1", version.openjpeg_version):
|
if re.match("2.1", version.openjpeg_version):
|
||||||
|
|
@ -1292,16 +1283,17 @@ class Jp2k(Jp2kBox):
|
||||||
else:
|
else:
|
||||||
opj2.set_info_handler(codec, None)
|
opj2.set_info_handler(codec, None)
|
||||||
|
|
||||||
opj2.setup_decoder(codec, dparam)
|
opj2.setup_decoder(codec, self._dparams)
|
||||||
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 self._dparams.nb_tile_to_decode:
|
||||||
opj2.get_decoded_tile(codec, stream, image, dparam.tile_index)
|
opj2.get_decoded_tile(codec, stream, image,
|
||||||
|
self._dparams.tile_index)
|
||||||
else:
|
else:
|
||||||
opj2.set_decode_area(codec, image,
|
opj2.set_decode_area(codec, image,
|
||||||
dparam.DA_x0, dparam.DA_y0,
|
self._dparams.DA_x0, self._dparams.DA_y0,
|
||||||
dparam.DA_x1, dparam.DA_y1)
|
self._dparams.DA_x1, self._dparams.DA_y1)
|
||||||
opj2.decode(codec, stream, image)
|
opj2.decode(codec, stream, image)
|
||||||
opj2.end_decompress(codec, stream)
|
opj2.end_decompress(codec, stream)
|
||||||
|
|
||||||
|
|
@ -1362,7 +1354,83 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
return codestream
|
return codestream
|
||||||
|
|
||||||
|
def _populate_image_struct(self, image, imgdata):
|
||||||
|
"""Populates image struct needed for compression.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
image : ImageType(ctypes.Structure)
|
||||||
|
Corresponds to image_t type in openjp2 headers.
|
||||||
|
img_array : ndarray
|
||||||
|
Image data to be written to file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
numrows, numcols, num_comps = imgdata.shape
|
||||||
|
|
||||||
|
# set image offset and reference grid
|
||||||
|
image.contents.x0 = self._cparams.image_offset_x0
|
||||||
|
image.contents.y0 = self._cparams.image_offset_y0
|
||||||
|
image.contents.x1 = (image.contents.x0 +
|
||||||
|
(numcols - 1) * self._cparams.subsampling_dx + 1)
|
||||||
|
image.contents.y1 = (image.contents.y0 +
|
||||||
|
(numrows - 1) * self._cparams.subsampling_dy + 1)
|
||||||
|
|
||||||
|
# Stage the image data to the openjpeg data structure.
|
||||||
|
for k in range(0, num_comps):
|
||||||
|
if re.match("2.0", version.openjpeg_version) is not None:
|
||||||
|
# 2.0 API
|
||||||
|
if self._cparams.cp_cinema:
|
||||||
|
image.contents.comps[k].prec = 12
|
||||||
|
image.contents.comps[k].bpp = 12
|
||||||
|
else:
|
||||||
|
# 2.1 API
|
||||||
|
if self._cparams.rsiz in (core.OPJ_PROFILE_CINEMA_2K,
|
||||||
|
core.OPJ_PROFILE_CINEMA_4K):
|
||||||
|
image.contents.comps[k].prec = 12
|
||||||
|
image.contents.comps[k].bpp = 12
|
||||||
|
|
||||||
|
layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32)
|
||||||
|
dest = image.contents.comps[k].data
|
||||||
|
src = layer.ctypes.data
|
||||||
|
ctypes.memmove(dest, src, layer.nbytes)
|
||||||
|
|
||||||
|
return image
|
||||||
|
|
||||||
|
def _populate_comptparms(self, img_array):
|
||||||
|
"""Instantiate and populate comptparms structure.
|
||||||
|
|
||||||
|
This structure defines the image components.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
img_array : ndarray
|
||||||
|
Image data to be written to file.
|
||||||
|
"""
|
||||||
|
# Only two precisions are possible.
|
||||||
|
if img_array.dtype == np.uint8:
|
||||||
|
comp_prec = 8
|
||||||
|
else:
|
||||||
|
comp_prec = 16
|
||||||
|
|
||||||
|
numrows, numcols, num_comps = img_array.shape
|
||||||
|
if version.openjpeg_version_tuple[0] == 1:
|
||||||
|
comptparms = (opj.ImageComptParmType * num_comps)()
|
||||||
|
else:
|
||||||
|
comptparms = (opj2.ImageComptParmType * num_comps)()
|
||||||
|
for j in range(num_comps):
|
||||||
|
comptparms[j].dx = self._cparams.subsampling_dx
|
||||||
|
comptparms[j].dy = self._cparams.subsampling_dy
|
||||||
|
comptparms[j].w = numcols
|
||||||
|
comptparms[j].h = numrows
|
||||||
|
comptparms[j].x0 = self._cparams.image_offset_x0
|
||||||
|
comptparms[j].y0 = self._cparams.image_offset_y0
|
||||||
|
comptparms[j].prec = comp_prec
|
||||||
|
comptparms[j].bpp = comp_prec
|
||||||
|
comptparms[j].sgnd = 0
|
||||||
|
|
||||||
|
self._comptparms = comptparms
|
||||||
|
|
||||||
|
|
||||||
def _component2dtype(component):
|
def _component2dtype(component):
|
||||||
"""Take an OpenJPEG component structure and determine the numpy datatype.
|
"""Take an OpenJPEG component structure and determine the numpy datatype.
|
||||||
|
|
||||||
|
|
@ -1704,92 +1772,6 @@ def extract_image_bands(image):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def _populate_comptparms(img_array, cparams):
|
|
||||||
"""Instantiate and populate comptparms structure.
|
|
||||||
|
|
||||||
This structure defines the image components.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
img_array : ndarray
|
|
||||||
Image data to be written to file.
|
|
||||||
cparams : CompressionParametersType(ctypes.Structure)
|
|
||||||
Corresponds to cparameters_t type in openjp2 headers.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
comptparms : ImageCompType(ctypes.Structure)
|
|
||||||
Corresponds to image_comp_t type in openjp2 headers.
|
|
||||||
"""
|
|
||||||
# Only two precisions are possible.
|
|
||||||
if img_array.dtype == np.uint8:
|
|
||||||
comp_prec = 8
|
|
||||||
else:
|
|
||||||
comp_prec = 16
|
|
||||||
|
|
||||||
numrows, numcols, num_comps = img_array.shape
|
|
||||||
if version.openjpeg_version_tuple[0] == 1:
|
|
||||||
comptparms = (opj.ImageComptParmType * num_comps)()
|
|
||||||
else:
|
|
||||||
comptparms = (opj2.ImageComptParmType * num_comps)()
|
|
||||||
for j in range(num_comps):
|
|
||||||
comptparms[j].dx = cparams.subsampling_dx
|
|
||||||
comptparms[j].dy = cparams.subsampling_dy
|
|
||||||
comptparms[j].w = numcols
|
|
||||||
comptparms[j].h = numrows
|
|
||||||
comptparms[j].x0 = cparams.image_offset_x0
|
|
||||||
comptparms[j].y0 = cparams.image_offset_y0
|
|
||||||
comptparms[j].prec = comp_prec
|
|
||||||
comptparms[j].bpp = comp_prec
|
|
||||||
comptparms[j].sgnd = 0
|
|
||||||
|
|
||||||
return comptparms
|
|
||||||
|
|
||||||
|
|
||||||
def _populate_image_struct(cparams, image, imgdata):
|
|
||||||
"""Populates image struct needed for compression.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
cparams : CompressionParametersType(ctypes.Structure)
|
|
||||||
Corresponds to cparameters_t type in openjp2 headers.
|
|
||||||
image : ImageType(ctypes.Structure)
|
|
||||||
Corresponds to image_t type in openjp2 headers.
|
|
||||||
imgarray : ndarray
|
|
||||||
Image data to be written to file.
|
|
||||||
"""
|
|
||||||
|
|
||||||
numrows, numcols, num_comps = imgdata.shape
|
|
||||||
|
|
||||||
# set image offset and reference grid
|
|
||||||
image.contents.x0 = cparams.image_offset_x0
|
|
||||||
image.contents.y0 = cparams.image_offset_y0
|
|
||||||
image.contents.x1 = (image.contents.x0 +
|
|
||||||
(numcols - 1) * cparams.subsampling_dx + 1)
|
|
||||||
image.contents.y1 = (image.contents.y0 +
|
|
||||||
(numrows - 1) * cparams.subsampling_dy + 1)
|
|
||||||
|
|
||||||
# Stage the image data to the openjpeg data structure.
|
|
||||||
for k in range(0, num_comps):
|
|
||||||
if re.match("2.0", version.openjpeg_version) is not None:
|
|
||||||
# 2.0 API
|
|
||||||
if cparams.cp_cinema:
|
|
||||||
image.contents.comps[k].prec = 12
|
|
||||||
image.contents.comps[k].bpp = 12
|
|
||||||
else:
|
|
||||||
# 2.1 API
|
|
||||||
if cparams.rsiz in (core.OPJ_PROFILE_CINEMA_2K,
|
|
||||||
core.OPJ_PROFILE_CINEMA_4K):
|
|
||||||
image.contents.comps[k].prec = 12
|
|
||||||
image.contents.comps[k].bpp = 12
|
|
||||||
|
|
||||||
layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32)
|
|
||||||
dest = image.contents.comps[k].data
|
|
||||||
src = layer.ctypes.data
|
|
||||||
ctypes.memmove(dest, src, layer.nbytes)
|
|
||||||
|
|
||||||
return image
|
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
||||||
|
|
@ -117,15 +117,17 @@ def read_config_file(libname):
|
||||||
None if no location is specified, otherwise a path to the library
|
None if no location is specified, otherwise a path to the library
|
||||||
"""
|
"""
|
||||||
filename = glymurrc_fname()
|
filename = glymurrc_fname()
|
||||||
if filename is not None:
|
if filename is None:
|
||||||
# Read the configuration file for the library location.
|
# There's no library file path to return in this case.
|
||||||
parser = ConfigParser()
|
return None
|
||||||
parser.read(filename)
|
|
||||||
try:
|
|
||||||
path = parser.get('library', libname)
|
|
||||||
except NoOptionError:
|
|
||||||
path = None
|
|
||||||
|
|
||||||
|
# Read the configuration file for the library location.
|
||||||
|
parser = ConfigParser()
|
||||||
|
parser.read(filename)
|
||||||
|
try:
|
||||||
|
path = parser.get('library', libname)
|
||||||
|
except NoOptionError:
|
||||||
|
path = None
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def glymur_config():
|
def glymur_config():
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ Wraps individual functions in openjp2 library.
|
||||||
import ctypes
|
import ctypes
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import textwrap
|
||||||
|
|
||||||
from .config import glymur_config
|
from .config import glymur_config
|
||||||
|
|
||||||
|
|
@ -138,6 +139,13 @@ class PocType(ctypes.Structure):
|
||||||
("tx0_t", ctypes.c_uint32),
|
("tx0_t", ctypes.c_uint32),
|
||||||
("ty0_t", ctypes.c_uint32)]
|
("ty0_t", ctypes.c_uint32)]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
msg = "{0}:\n".format(self.__class__)
|
||||||
|
for field_name, _ in self._fields_:
|
||||||
|
msg += " {0}: {1}\n".format(
|
||||||
|
field_name, getattr(self, field_name))
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
class DecompressionParametersType(ctypes.Structure):
|
class DecompressionParametersType(ctypes.Structure):
|
||||||
"""Decompression parameters.
|
"""Decompression parameters.
|
||||||
|
|
@ -201,6 +209,13 @@ class DecompressionParametersType(ctypes.Structure):
|
||||||
# maximum number of tiles
|
# maximum number of tiles
|
||||||
("flags", ctypes.c_uint32)]
|
("flags", ctypes.c_uint32)]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
msg = "{0}:\n".format(self.__class__)
|
||||||
|
for field_name, _ in self._fields_:
|
||||||
|
msg += " {0}: {1}\n".format(
|
||||||
|
field_name, getattr(self, field_name))
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
class CompressionParametersType(ctypes.Structure):
|
class CompressionParametersType(ctypes.Structure):
|
||||||
"""Compression parameters.
|
"""Compression parameters.
|
||||||
|
|
@ -392,6 +407,47 @@ class CompressionParametersType(ctypes.Structure):
|
||||||
# values.
|
# values.
|
||||||
_fields_.append(("rsiz", ctypes.c_uint16))
|
_fields_.append(("rsiz", ctypes.c_uint16))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
msg = "{0}:\n".format(self.__class__)
|
||||||
|
for field_name, _ in self._fields_:
|
||||||
|
|
||||||
|
if field_name == 'poc':
|
||||||
|
msg += " numpocs: {0}\n".format(self.numpocs)
|
||||||
|
for j in range(self.numpocs):
|
||||||
|
msg += " [#{0}]:".format(j)
|
||||||
|
msg += " {0}".format(str(self.poc[j]))
|
||||||
|
msg += textwrap.indent(textstr, ' ' * 12)
|
||||||
|
|
||||||
|
elif field_name in ['tcp_rates', 'tcp_distoratio']:
|
||||||
|
lst = []
|
||||||
|
arr = getattr(self, field_name)
|
||||||
|
lst = [arr[j] for j in range(self.tcp_numlayers)]
|
||||||
|
msg += " {0}: {1}\n".format(field_name, lst)
|
||||||
|
|
||||||
|
elif field_name in ['prcw_init', 'prch_init']:
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif field_name == 'res_spec':
|
||||||
|
prcw_init = [self.prcw_init[j] for j in range(self.res_spec)]
|
||||||
|
prch_init = [self.prch_init[j] for j in range(self.res_spec)]
|
||||||
|
msg += " res_spec: {0}\n".format(self.res_spec)
|
||||||
|
msg += " prch_init: {0}\n".format(prch_init)
|
||||||
|
msg += " prcw_init: {0}\n".format(prcw_init)
|
||||||
|
|
||||||
|
elif field_name in [
|
||||||
|
'jpwl_hprot_tph_tileno', 'jpwl_hprot_tph',
|
||||||
|
'jpwl_pprot_tileno', 'jpwl_pprot_packno', 'jpwl_pprot',
|
||||||
|
'jpwl_sens_tph_tileno', 'jpwl_sens_tph']:
|
||||||
|
arr = getattr(self, field_name)
|
||||||
|
lst = [arr[j] for j in range(JPWL_MAX_NO_TILESPECS)]
|
||||||
|
msg += " {0}: {1}\n".format(field_name, lst)
|
||||||
|
|
||||||
|
else:
|
||||||
|
msg += " {0}: {1}\n".format(
|
||||||
|
field_name, getattr(self, field_name))
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
class ImageCompType(ctypes.Structure):
|
class ImageCompType(ctypes.Structure):
|
||||||
"""Defines a single image component.
|
"""Defines a single image component.
|
||||||
|
|
||||||
|
|
@ -492,6 +548,13 @@ class ImageComptParmType(ctypes.Structure):
|
||||||
# signed (1) / unsigned (0)
|
# signed (1) / unsigned (0)
|
||||||
("sgnd", ctypes.c_uint32)]
|
("sgnd", ctypes.c_uint32)]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
msg = "{0}:\n".format(self.__class__)
|
||||||
|
for field_name, _ in self._fields_:
|
||||||
|
msg += " {0}: {1}\n".format(
|
||||||
|
field_name, getattr(self, field_name))
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
class TccpInfo(ctypes.Structure):
|
class TccpInfo(ctypes.Structure):
|
||||||
"""Tile-component coding parameters information.
|
"""Tile-component coding parameters information.
|
||||||
|
|
|
||||||
129
glymur/lib/test/fixtures.py
Normal file
129
glymur/lib/test/fixtures.py
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
decompression_parameters_type = """<class 'glymur.lib.openjp2.DecompressionParametersType'>:
|
||||||
|
cp_reduce: 0
|
||||||
|
cp_layer: 0
|
||||||
|
infile: b''
|
||||||
|
outfile: b''
|
||||||
|
decod_format: -1
|
||||||
|
cod_format: -1
|
||||||
|
DA_x0: 0
|
||||||
|
DA_x1: 0
|
||||||
|
DA_y0: 0
|
||||||
|
DA_y1: 0
|
||||||
|
m_verbose: 0
|
||||||
|
tile_index: 0
|
||||||
|
nb_tile_to_decode: 0
|
||||||
|
jpwl_correct: 0
|
||||||
|
jpwl_exp_comps: 0
|
||||||
|
jpwl_max_tiles: 0
|
||||||
|
flags: 0"""
|
||||||
|
|
||||||
|
default_progression_order_changes_type = """<class 'glymur.lib.openjp2.PocType'>:
|
||||||
|
resno0: 0
|
||||||
|
compno0: 0
|
||||||
|
layno1: 0
|
||||||
|
resno1: 0
|
||||||
|
compno1: 0
|
||||||
|
layno0: 0
|
||||||
|
precno0: 0
|
||||||
|
precno1: 0
|
||||||
|
prg1: 0
|
||||||
|
prg: 0
|
||||||
|
progorder: b''
|
||||||
|
tile: 0
|
||||||
|
tx0: 0
|
||||||
|
tx1: 0
|
||||||
|
ty0: 0
|
||||||
|
ty1: 0
|
||||||
|
layS: 0
|
||||||
|
resS: 0
|
||||||
|
compS: 0
|
||||||
|
prcS: 0
|
||||||
|
layE: 0
|
||||||
|
resE: 0
|
||||||
|
compE: 0
|
||||||
|
prcE: 0
|
||||||
|
txS: 0
|
||||||
|
txE: 0
|
||||||
|
tyS: 0
|
||||||
|
tyE: 0
|
||||||
|
dx: 0
|
||||||
|
dy: 0
|
||||||
|
lay_t: 0
|
||||||
|
res_t: 0
|
||||||
|
comp_t: 0
|
||||||
|
prec_t: 0
|
||||||
|
tx0_t: 0
|
||||||
|
ty0_t: 0"""
|
||||||
|
|
||||||
|
default_compression_parameters_type = """<class 'glymur.lib.openjp2.CompressionParametersType'>:
|
||||||
|
tile_size_on: 0
|
||||||
|
cp_tx0: 0
|
||||||
|
cp_ty0: 0
|
||||||
|
cp_tdx: 0
|
||||||
|
cp_tdy: 0
|
||||||
|
cp_disto_alloc: 0
|
||||||
|
cp_fixed_alloc: 0
|
||||||
|
cp_fixed_quality: 0
|
||||||
|
cp_matrice: None
|
||||||
|
cp_comment: None
|
||||||
|
csty: 0
|
||||||
|
prog_order: 0
|
||||||
|
numpocs: 0
|
||||||
|
numpocs: 0
|
||||||
|
tcp_numlayers: 0
|
||||||
|
tcp_rates: []
|
||||||
|
tcp_distoratio: []
|
||||||
|
numresolution: 6
|
||||||
|
cblockw_init: 64
|
||||||
|
cblockh_init: 64
|
||||||
|
mode: 0
|
||||||
|
irreversible: 0
|
||||||
|
roi_compno: -1
|
||||||
|
roi_shift: 0
|
||||||
|
res_spec: 0
|
||||||
|
prch_init: []
|
||||||
|
prcw_init: []
|
||||||
|
infile: b''
|
||||||
|
outfile: b''
|
||||||
|
index_on: 0
|
||||||
|
index: b''
|
||||||
|
image_offset_x0: 0
|
||||||
|
image_offset_y0: 0
|
||||||
|
subsampling_dx: 1
|
||||||
|
subsampling_dy: 1
|
||||||
|
decod_format: -1
|
||||||
|
cod_format: -1
|
||||||
|
jpwl_epc_on: 0
|
||||||
|
jpwl_hprot_mh: 0
|
||||||
|
jpwl_hprot_tph_tileno: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
jpwl_hprot_tph: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
jpwl_pprot_tileno: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
jpwl_pprot_packno: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
jpwl_pprot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
jpwl_sens_size: 0
|
||||||
|
jpwl_sens_addr: 0
|
||||||
|
jpwl_sens_range: 0
|
||||||
|
jpwl_sens_mh: 0
|
||||||
|
jpwl_sens_tph_tileno: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
jpwl_sens_tph: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
cp_cinema: 0
|
||||||
|
max_comp_size: 0
|
||||||
|
cp_rsiz: 0
|
||||||
|
tp_on: 0
|
||||||
|
tp_flag: 0
|
||||||
|
tcp_mct: 0
|
||||||
|
jpip_on: 0
|
||||||
|
mct_data: None
|
||||||
|
max_cs_size: 0
|
||||||
|
rsiz: 0"""
|
||||||
|
|
||||||
|
default_image_component_parameters = """<class 'glymur.lib.openjp2.ImageComptParmType'>:
|
||||||
|
dx: 0
|
||||||
|
dy: 0
|
||||||
|
w: 0
|
||||||
|
h: 0
|
||||||
|
x0: 0
|
||||||
|
y0: 0
|
||||||
|
prec: 0
|
||||||
|
bpp: 0
|
||||||
|
sgnd: 0"""
|
||||||
67
glymur/lib/test/test_printing.py
Normal file
67
glymur/lib/test/test_printing.py
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Test suite for printing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
if sys.hexversion < 0x03000000:
|
||||||
|
from mock import patch
|
||||||
|
from StringIO import StringIO
|
||||||
|
else:
|
||||||
|
from unittest.mock import patch
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
import glymur
|
||||||
|
from . import fixtures
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.hexversion < 0x03000000, "do not care about 2.7 here")
|
||||||
|
@unittest.skipIf(re.match('1|2.0', glymur.version.openjpeg_version),
|
||||||
|
"Requires openjpeg 2.1.0 or higher")
|
||||||
|
class TestPrintingOpenjp2(unittest.TestCase):
|
||||||
|
"""Tests for verifying how printing works on openjp2 library structures."""
|
||||||
|
def setUp(self):
|
||||||
|
self.jp2file = glymur.data.nemo()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_decompression_parameters(self):
|
||||||
|
"""printing DecompressionParametersType"""
|
||||||
|
dparams = glymur.lib.openjp2.set_default_decoder_parameters()
|
||||||
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
|
print(dparams)
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
expected = fixtures.decompression_parameters_type
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_progression_order_changes(self):
|
||||||
|
"""printing PocType"""
|
||||||
|
ptype = glymur.lib.openjp2.PocType()
|
||||||
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
|
print(ptype)
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
expected = fixtures.default_progression_order_changes_type
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_default_compression_parameters(self):
|
||||||
|
"""printing default compression parameters"""
|
||||||
|
cparams = glymur.lib.openjp2.set_default_encoder_parameters()
|
||||||
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
|
print(cparams)
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
expected = fixtures.default_compression_parameters_type
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_default_component_parameters(self):
|
||||||
|
"""printing default image component parameters"""
|
||||||
|
icpt = glymur.lib.openjp2.ImageComptParmType()
|
||||||
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
|
print(icpt)
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
expected = fixtures.default_image_component_parameters
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -900,3 +900,4 @@ goodstuff_with_full_header = r"""Codestream:
|
||||||
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
|
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
|
||||||
SOD marker segment @ (164, 0)
|
SOD marker segment @ (164, 0)
|
||||||
EOC marker segment @ (115218, 0)"""
|
EOC marker segment @ (115218, 0)"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,13 @@ import lxml.etree as ET
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k, command_line
|
from glymur import Jp2k, command_line
|
||||||
from . import fixtures
|
from . import fixtures
|
||||||
from .fixtures import OPJ_DATA_ROOT, opj_data_file
|
from .fixtures import (
|
||||||
from .fixtures import WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG
|
OPJ_DATA_ROOT, opj_data_file,
|
||||||
from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34
|
WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG,
|
||||||
|
WINDOWS_TMP_FILE_MSG, text_gbr_27, text_gbr_33, text_gbr_34
|
||||||
|
)
|
||||||
|
|
||||||
|
@unittest.skipIf(os.name == "nt", WINDOWS_TMP_FILE_MSG)
|
||||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
|
||||||
class TestPrinting(unittest.TestCase):
|
class TestPrinting(unittest.TestCase):
|
||||||
"""Tests for verifying how printing works."""
|
"""Tests for verifying how printing works."""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
@ -617,7 +618,6 @@ class TestPrinting(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
||||||
"OPJ_DATA_ROOT environment variable not set")
|
"OPJ_DATA_ROOT environment variable not set")
|
||||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue