Merge branch 'issue71' into devel

This commit is contained in:
jevans 2013-07-09 20:23:27 -04:00
commit 37cf486719
21 changed files with 4945 additions and 4871 deletions

View file

@ -6,13 +6,13 @@ How do I...?
Read the lowest resolution thumbnail?
=====================================
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
level. ::
COD segment section), but you can take a shortcut by supplying -1 as the
resolution level. ::
>>> import glymur
>>> file = glymur.data.nemo()
>>> j = glymur.Jp2k(file)
>>> thumbnail = j.read(reduce=-1)
>>> thumbnail = j.read(rlevel=-1)
Display metadata?
=================

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,5 @@
"""Core definitions to be shared amongst the modules.
"""
# Progression order
LRCP = 0
RLCP = 1
@ -5,44 +7,21 @@ RPCL = 2
PCRL = 3
CPRL = 4
_progression_order_display = {
LRCP: 'LRCP',
RLCP: 'RLCP',
RPCL: 'RPCL',
PCRL: 'PCRL',
CPRL: 'CPRL'}
progression_order = {
PROGRESSION_ORDER = {
'LRCP': LRCP,
'RLCP': RLCP,
'RPCL': RPCL,
'PCRL': PCRL,
'CPRL': CPRL}
WAVELET_TRANSFORM_9x7_IRREVERSIBLE = 0
WAVELET_TRANSFORM_5x3_REVERSIBLE = 1
_wavelet_transform_display = {
WAVELET_TRANSFORM_9x7_IRREVERSIBLE: '9-7 irreversible',
WAVELET_TRANSFORM_5x3_REVERSIBLE: '5-3 reversible'}
WAVELET_XFORM_9X7_IRREVERSIBLE = 0
WAVELET_XFORM_5X3_REVERSIBLE = 1
ENUMERATED_COLORSPACE = 1
RESTRICTED_ICC_PROFILE = 2
ANY_ICC_PROFILE = 3
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.
RCME_BINARY = 0 # binary value comments
RCME_ISO_8859_1 = 1 # comments in latin-1 codec
@ -55,7 +34,7 @@ YCC = 18
E_SRGB = 20
ROMM_RGB = 21
_colorspace_map_display = {
_COLORSPACE_MAP_DISPLAY = {
CMYK: 'CMYK',
SRGB: 'sRGB',
GREYSCALE: 'greyscale',
@ -68,7 +47,7 @@ _COLOR = 0
_OPACITY = 1
_PRE_MULTIPLIED_OPACITY = 2
_UNSPECIFIED = 65535
_color_type_map_display = {
_COLOR_TYPE_MAP_DISPLAY = {
_COLOR: 'color',
_OPACITY: 'opacity',
_PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
@ -81,108 +60,15 @@ BLUE = 3
GREY = 1
# enumerated color channel associations
_rgb_colorspace = {"R": 1, "G": 2, "B": 3}
_greyscale_colorspace = {"Y": 1}
_ycbcr_colorspace = {"Y": 1, "Cb": 2, "Cr": 3}
_colorspace = {SRGB: _rgb_colorspace,
GREYSCALE: _greyscale_colorspace,
YCC: _ycbcr_colorspace,
E_SRGB: _rgb_colorspace,
ROMM_RGB: _rgb_colorspace}
_COLORSPACE = {SRGB: {"R": 1, "G": 2, "B": 3},
GREYSCALE: {"Y": 1},
YCC: {"Y": 1, "Cb": 2, "Cr": 3},
E_SRGB: {"R": 1, "G": 2, "B": 3},
ROMM_RGB: {"R": 1, "G": 2, "B": 3}}
# How to display the codestream profile.
_capabilities_display = {
_CAPABILITIES_DISPLAY = {
0: '2',
1: '0',
2: '1',
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'}

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,9 @@
License: MIT
"""
# pylint: disable=C0302
import sys
if sys.hexversion >= 0x03030000:
from contextlib import ExitStack
@ -16,15 +19,23 @@ import warnings
import numpy as np
from .codestream import Codestream
from .core import *
from .jp2box import *
from .lib import openjpeg as opj
from .lib import openjp2 as opj2
from .core import SRGB
from .core import GREYSCALE
from .core import PROGRESSION_ORDER
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,
'gray': opj2._CLRSPC_GRAY,
'grey': opj2._CLRSPC_GRAY,
'ycc': opj2._CLRSPC_YCC}
_COLORSPACE_MAP = {'rgb': _opj2.CLRSPC_SRGB,
'gray': _opj2.CLRSPC_GRAY,
'grey': _opj2.CLRSPC_GRAY,
'ycc': _opj2.CLRSPC_YCC}
# Setup the default callback handlers. See the callback functions subsection
# 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)
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())
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()))
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()
msg = "OpenJPEG library warning: {0}".format(library_msg)
warnings.warn(msg)
_error_callback = _CMPFUNC(_default_error_handler)
_info_callback = _CMPFUNC(_default_info_handler)
_warning_callback = _CMPFUNC(_default_warning_handler)
_ERROR_CALLBACK = _CMPFUNC(_default_error_handler)
_INFO_CALLBACK = _CMPFUNC(_default_info_handler)
_WARNING_CALLBACK = _CMPFUNC(_default_warning_handler)
class Jp2k(Jp2kBox):
@ -75,10 +89,12 @@ class Jp2k(Jp2kBox):
mode : str, optional
The mode used to open the file.
"""
Jp2kBox.__init__(self)
self.filename = filename
self.mode = mode
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.
if mode == 'rb':
@ -90,8 +106,8 @@ class Jp2k(Jp2kBox):
for box in self.box:
metadata.append(str(box))
else:
c = self.get_codestream()
metadata.append(str(c))
codestream = self.get_codestream()
metadata.append(str(codestream))
return '\n'.join(metadata)
def _parse(self):
@ -106,39 +122,41 @@ class Jp2k(Jp2kBox):
self.length = 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
# J2C. Check for J2C first, single box in that case.
buffer = f.read(2)
signature, = struct.unpack('>H', buffer)
read_buffer = fptr.read(2)
signature, = struct.unpack('>H', read_buffer)
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
# produced upon explicit request.
return
self._codec_format = opj2._CODEC_JP2
self._codec_format = _opj2.CODEC_JP2
# Should be JP2.
# First 4 bytes should be 12, the length of the 'jP ' box.
# 2nd 4 bytes should be the box ID ('jP ').
# 3rd 4 bytes should be the box signature (13, 10, 135, 10).
f.seek(0)
buffer = f.read(12)
values = struct.unpack('>I4s4B', buffer)
L = values[0]
T = values[1]
fptr.seek(0)
read_buffer = fptr.read(12)
values = struct.unpack('>I4s4B', read_buffer)
box_length = values[0]
box_id = values[1]
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)
raise IOError(msg)
# Back up and start again, we know we have a superbox (box of
# boxes) here.
f.seek(0)
self.box = self._parse_superbox(f)
fptr.seek(0)
self.box = self.parse_superbox(fptr)
# pylint: disable-msg=W0221
def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None,
cbsize=None, psizes=None, grid_offset=None, sop=False,
subsam=None, tilesize=None, prog=None, modesw=None,
@ -203,24 +221,24 @@ class Jp2k(Jp2kBox):
>>> import glymur
>>> jfile = glymur.data.nemo()
>>> jp2 = glymur.Jp2k(jfile)
>>> data = jp2.read(reduce=1)
>>> data = jp2.read(rlevel=1)
>>> from tempfile import NamedTemporaryFile
>>> tfile = NamedTemporaryFile(suffix='.jp2', delete=False)
>>> j = Jp2k(tfile.name, mode='wb')
>>> j.write(data.astype(np.uint8))
"""
cparams = opj2._set_default_encoder_parameters()
cparams = _opj2.set_default_encoder_parameters()
outfile = self.filename.encode()
n = opj2._PATH_LEN - len(outfile)
outfile += b'0' * n
num_pad_bytes = _opj2.PATH_LEN - len(outfile)
outfile += b'0' * num_pad_bytes
cparams.outfile = outfile
if self.filename[-4:].lower() == '.jp2':
codec_fmt = opj2._CODEC_JP2
codec_fmt = _opj2.CODEC_JP2
else:
codec_fmt = opj2._CODEC_J2K
codec_fmt = _opj2.CODEC_J2K
cparams.cod_format = codec_fmt
@ -230,19 +248,19 @@ class Jp2k(Jp2kBox):
cparams.cp_disto_alloc = 1
if cbsize is not None:
w = cbsize[1]
h = cbsize[0]
if h * w > 4096 or h < 4 or w < 4:
width = cbsize[1]
height = cbsize[0]
if height * width > 4096 or height < 4 or width < 4:
msg = "Code block area cannot exceed 4096. "
msg += "Code block height and width must be larger than 4."
raise RuntimeError(msg)
if ((math.log(h, 2) != math.floor(math.log(h, 2)) or
math.log(w, 2) != math.floor(math.log(w, 2)))):
if ((math.log(height, 2) != math.floor(math.log(height, 2)) or
math.log(width, 2) != math.floor(math.log(width, 2)))):
msg = "Bad code block size ({0}, {1}), "
msg += "must be powers of 2."
raise IOError(msg.format(h, w))
cparams.cblockw_init = w
cparams.cblockh_init = h
raise IOError(msg.format(height, width))
cparams.cblockw_init = width
cparams.cblockh_init = height
if cratios is not None:
cparams.tcp_numlayers = len(cratios)
@ -258,16 +276,17 @@ class Jp2k(Jp2kBox):
cparams.image_offset_y0 = grid_offset[0]
if modesw is not None:
for x in range(6):
if modesw & (1 << x):
cparams.mode |= (1 << x)
for shift in range(6):
power_of_two = 1 << shift
if modesw & power_of_two:
cparams.mode |= power_of_two
if numres is not None:
cparams.numresolution = numres
if prog is not None:
prog = prog.upper()
cparams.prog_order = progression_order[prog]
cparams.prog_order = PROGRESSION_ORDER[prog]
if psnr is not None:
cparams.tcp_numlayers = len(psnr)
@ -304,7 +323,7 @@ class Jp2k(Jp2kBox):
if tilesize is not None:
cparams.cp_tdx = tilesize[1]
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:
msg = "Cannot specify cratios and psnr together."
@ -323,12 +342,12 @@ class Jp2k(Jp2kBox):
if colorspace is None:
if img_array.shape[2] == 1 or img_array.shape[2] == 2:
colorspace = opj2._CLRSPC_GRAY
colorspace = _opj2.CLRSPC_GRAY
else:
# No YCC unless specifically told to do so.
colorspace = opj2._CLRSPC_SRGB
colorspace = _opj2.CLRSPC_SRGB
else:
if codec_fmt == opj2._CODEC_J2K:
if codec_fmt == _opj2.CODEC_J2K:
raise IOError('Do not specify a colorspace with J2K.')
colorspace = colorspace.lower()
if colorspace not in ('rgb', 'grey', 'gray'):
@ -338,15 +357,15 @@ class Jp2k(Jp2kBox):
msg = 'RGB colorspace requires at least 3 components.'
raise IOError(msg)
else:
colorspace = _cspace_map[colorspace]
colorspace = _COLORSPACE_MAP[colorspace]
if mct is None:
if colorspace == opj2._CLRSPC_SRGB:
if colorspace == _opj2.CLRSPC_SRGB:
cparams.tcp_mct = 1
else:
cparams.tcp_mct = 0
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 += "if the colorspace is gray."
raise IOError(msg)
@ -359,7 +378,7 @@ class Jp2k(Jp2kBox):
else:
raise RuntimeError("unhandled datatype")
comptparms = (opj2._image_comptparm_t * num_comps)()
comptparms = (_opj2.ImageComptParmType * num_comps)()
for j in range(num_comps):
comptparms[j].dx = cparams.subsampling_dx
comptparms[j].dy = cparams.subsampling_dy
@ -371,7 +390,7 @@ class Jp2k(Jp2kBox):
comptparms[j].bpp = comp_prec
comptparms[j].sgnd = 0
image = opj2._image_create(comptparms, colorspace)
image = _opj2.image_create(comptparms, colorspace)
# set image offset and reference grid
image.contents.x0 = cparams.image_offset_x0
@ -388,23 +407,23 @@ class Jp2k(Jp2kBox):
src = layer.ctypes.data
ctypes.memmove(dest, src, layer.nbytes)
codec = opj2._create_compress(codec_fmt)
codec = _opj2.create_compress(codec_fmt)
if verbose:
opj2._set_info_handler(codec, _info_callback)
_opj2.set_info_handler(codec, _INFO_CALLBACK)
else:
opj2._set_info_handler(codec, None)
_opj2.set_info_handler(codec, None)
opj2._set_warning_handler(codec, _warning_callback)
opj2._set_error_handler(codec, _error_callback)
opj2._setup_encoder(codec, cparams, image)
strm = opj2._stream_create_default_file_stream_v3(self.filename, False)
opj2._start_compress(codec, image, strm)
opj2._encode(codec, strm)
opj2._end_compress(codec, strm)
opj2._stream_destroy_v3(strm)
opj2._destroy_codec(codec)
opj2._image_destroy(image)
_opj2.set_warning_handler(codec, _WARNING_CALLBACK)
_opj2.set_error_handler(codec, _ERROR_CALLBACK)
_opj2.setup_encoder(codec, cparams, image)
strm = _opj2.stream_create_default_file_stream_v3(self.filename, False)
_opj2.start_compress(codec, image, strm)
_opj2.encode(codec, strm)
_opj2.end_compress(codec, strm)
_opj2.stream_destroy_v3(strm)
_opj2.destroy_codec(codec)
_opj2.image_destroy(image)
self._parse()
@ -439,10 +458,10 @@ class Jp2k(Jp2kBox):
FileTypeBox(),
JP2HeaderBox(),
ContiguousCodestreamBox()]
c = self.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
codestream = self.get_codestream()
height = codestream.segment[1].ysiz
width = codestream.segment[1].xsiz
num_components = len(codestream.segment[1].xrsiz)
boxes[2].box = [ImageHeaderBox(height=height,
width=width,
num_components=num_components),
@ -450,15 +469,17 @@ class Jp2k(Jp2kBox):
# Check for a bad sequence of boxes.
# 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 += "must be the file type box."
raise IOError(msg)
# 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]
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:
msg = "A codestream box must be defined in the outermost "
msg += "list of boxes."
@ -471,27 +492,28 @@ class Jp2k(Jp2kBox):
# 1st jp2 header box must be ihdr
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 += "header box."
raise IOError(msg)
# colr must be present in jp2 header box.
jp2hb = jp2h.box
colr_lst = [j for (j, box) in enumerate(jp2h.box) if box.id == 'colr']
colr_lst = [j for (j, box) in enumerate(jp2h.box)
if box.box_id == 'colr']
if len(colr_lst) == 0:
msg = "The jp2 header box must contain a color definition box."
raise IOError(msg)
colr = jp2h.box[colr_lst[0]]
# 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:
msg = "Any channel defintion box must be in the JP2 header "
msg += "following the image header."
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:
msg = "Only one channel definition box is allowed in the "
msg += "JP2 header."
@ -500,7 +522,6 @@ class Jp2k(Jp2kBox):
cdef = jp2h.box[cdef_lst[0]]
assn = cdef.association
typ = cdef.channel_type
index = cdef.index
if colr.colorspace == SRGB:
if any([chan + 1 not in assn or typ[chan] != 0
for chan in [0, 1, 2]]):
@ -515,8 +536,8 @@ class Jp2k(Jp2kBox):
with open(filename, 'wb') as ofile:
for box in boxes:
if box.id != 'jp2c':
box._write(ofile)
if box.box_id != 'jp2c':
box.write(ofile)
else:
# The codestream gets written last.
if len(self.box) == 0:
@ -530,7 +551,8 @@ class Jp2k(Jp2kBox):
else:
# OK, I'm a jp2 file. Need to find out where the
# 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]
ofile.write(struct.pack('>I', jp2c.length + 8))
ofile.write('jp2c'.encode())
@ -550,8 +572,8 @@ class Jp2k(Jp2kBox):
Parameters
----------
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
rlevel : int, optional
Factor by which to rlevel output resolution. Use -1 to get the
lowest resolution thumbnail. This is the only keyword option
available to use when only OpenJPEG version 1.5.1 is present.
layer : int, optional
@ -585,23 +607,23 @@ class Jp2k(Jp2kBox):
Read the lowest resolution thumbnail.
>>> thumbnail = jp.read(reduce=-1)
>>> thumbnail = jp.read(rlevel=-1)
>>> thumbnail.shape
(728, 1296, 3)
"""
if opj2._OPENJP2 is not None:
if _opj2.OPENJP2 is not None:
img = self._read_openjp2(**kwargs)
else:
img = self._read_openjpeg(**kwargs)
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.
Parameters
----------
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
rlevel : int, optional
Factor by which to rlevel output resolution. Use -1 to get the
lowest resolution thumbnail.
verbose : bool, optional
Print informational messages produced by the OpenJPEG library.
@ -618,49 +640,48 @@ class Jp2k(Jp2kBox):
"""
# Check for differing subsample factors.
codestream = self.get_codestream(header_only=True)
dxs = np.array(codestream.segment[1].XRsiz)
dys = np.array(codestream.segment[1].YRsiz)
dxs = np.array(codestream.segment[1].xrsiz)
dys = np.array(codestream.segment[1].yrsiz)
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
msg = "Components must all have the same subsampling factors "
msg += "to use this method with OpenJPEG 1.5.1. Please consider "
msg += "using OPENJP2 instead."
raise RuntimeError(msg)
with ExitStack() as stack:
# Set decoding parameters.
dparameters = opj.dparameters_t()
opj._set_default_decoder_parameters(ctypes.byref(dparameters))
dparameters.cp_reduce = reduce
dparameters = _opj.DecompressionParametersType()
_opj.set_default_decoder_parameters(ctypes.byref(dparameters))
dparameters.cp_reduce = rlevel
dparameters.decod_format = self._codec_format
infile = self.filename.encode()
nelts = opj._PATH_LEN - len(infile)
nelts = _opj.PATH_LEN - len(infile)
infile += b'0' * nelts
dparameters.infile = infile
dinfo = opj._create_decompress(dparameters.decod_format)
dinfo = _opj.create_decompress(dparameters.decod_format)
event_mgr = opj.event_mgr_t()
info_handler = ctypes.cast(_info_callback, ctypes.c_void_p)
event_mgr = _opj.EventMgrType()
info_handler = ctypes.cast(_INFO_CALLBACK, ctypes.c_void_p)
event_mgr.info_handler = info_handler if verbose else None
event_mgr.warning_handler = ctypes.cast(_warning_callback,
ctypes.c_void_p)
event_mgr.error_handler = ctypes.cast(_error_callback,
ctypes.c_void_p)
opj._set_event_mgr(dinfo, ctypes.byref(event_mgr))
event_mgr.warning_handler = ctypes.cast(_WARNING_CALLBACK,
ctypes.c_void_p)
event_mgr.error_handler = ctypes.cast(_ERROR_CALLBACK,
ctypes.c_void_p)
_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:
src = fp.read()
cio = opj._cio_open(dinfo, src)
with open(self.filename, 'rb') as fptr:
src = fptr.read()
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._destroy_decompress, dinfo)
stack.callback(opj._cio_close, cio)
stack.callback(_opj.image_destroy, image)
stack.callback(_opj.destroy_decompress, dinfo)
stack.callback(_opj.cio_close, cio)
ncomps = image.contents.numcomps
component = image.contents.comps[0]
@ -700,8 +721,10 @@ class Jp2k(Jp2kBox):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
nelts = nrows * ncols
x = np.ctypeslib.as_array((ctypes.c_int32 * nelts).from_address(addr))
data[:, :, k] = np.reshape(x.astype(dtype), (nrows, ncols))
band = np.ctypeslib.as_array(
(ctypes.c_int32 * nelts).from_address(addr))
data[:, :, k] = np.reshape(band.astype(dtype),
(nrows, ncols))
if data.shape[2] == 1:
data = data.view()
@ -709,7 +732,7 @@ class Jp2k(Jp2kBox):
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):
"""Read a JPEG 2000 image using libopenjp2.
@ -717,8 +740,8 @@ class Jp2k(Jp2kBox):
----------
layer : int, optional
Number of quality layer to decode.
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
rlevel : int, optional
Factor by which to rlevel output resolution. Use -1 to get the
lowest resolution thumbnail.
area : tuple, optional
Specifies decoding image area,
@ -740,13 +763,13 @@ class Jp2k(Jp2kBox):
"""
# Check for differing subsample factors.
codestream = self.get_codestream(header_only=True)
dxs = np.array(codestream.segment[1].XRsiz)
dys = np.array(codestream.segment[1].YRsiz)
dxs = np.array(codestream.segment[1].xrsiz)
dys = np.array(codestream.segment[1].yrsiz)
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
msg = "Components must all have the same subsampling factors."
raise RuntimeError(msg)
img_array = self._read_common(reduce=reduce,
img_array = self._read_common(rlevel=rlevel,
layer=layer,
area=area,
tile=tile,
@ -759,7 +782,7 @@ class Jp2k(Jp2kBox):
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):
"""Read a JPEG 2000 image.
@ -767,8 +790,8 @@ class Jp2k(Jp2kBox):
----------
layer : int, optional
Number of quality layer to decode.
reduce : int, optional
Factor by which to reduce output resolution.
rlevel : int, optional
Factor by which to rlevel output resolution.
area : tuple, optional
Specifies decoding image area,
(first_row, first_col, last_row, last_col)
@ -784,10 +807,10 @@ class Jp2k(Jp2kBox):
img_array : ndarray
The individual image components or a single array.
"""
dparam = opj2._set_default_decoder_parameters()
dparam = _opj2.set_default_decoder_parameters()
infile = self.filename.encode()
nelts = opj2._PATH_LEN - len(infile)
nelts = _opj2.PATH_LEN - len(infile)
infile += b'0' * nelts
dparam.infile = infile
@ -795,12 +818,12 @@ class Jp2k(Jp2kBox):
dparam.cp_layer = layer
if reduce == -1:
if rlevel == -1:
# Get the lowest resolution thumbnail.
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[0] < 0 or area[1] < 0:
msg = "Upper left corner coordinates must be nonnegative: {0}"
@ -820,31 +843,31 @@ class Jp2k(Jp2kBox):
dparam.nb_tile_to_decode = 1
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)
stack.callback(opj2._stream_destroy_v3, stream)
codec = opj2._create_decompress(self._codec_format)
stack.callback(opj2._destroy_codec, codec)
stack.callback(_opj2.stream_destroy_v3, stream)
codec = _opj2.create_decompress(self._codec_format)
stack.callback(_opj2.destroy_codec, codec)
opj2._set_error_handler(codec, _error_callback)
opj2._set_warning_handler(codec, _warning_callback)
_opj2.set_error_handler(codec, _ERROR_CALLBACK)
_opj2.set_warning_handler(codec, _WARNING_CALLBACK)
if verbose:
opj2._set_info_handler(codec, _info_callback)
_opj2.set_info_handler(codec, _INFO_CALLBACK)
else:
opj2._set_info_handler(codec, None)
_opj2.set_info_handler(codec, None)
opj2._setup_decoder(codec, dparam)
image = opj2._read_header(stream, codec)
stack.callback(opj2._image_destroy, image)
_opj2.setup_decoder(codec, dparam)
image = _opj2.read_header(stream, codec)
stack.callback(_opj2.image_destroy, image)
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:
opj2._set_decode_area(codec, image,
_opj2.set_decode_area(codec, image,
dparam.DA_x0, dparam.DA_y0,
dparam.DA_x1, dparam.DA_y1)
opj2._decode(codec, stream, image)
opj2._end_decompress(codec, stream)
_opj2.decode(codec, stream, image)
_opj2.end_decompress(codec, stream)
component = image.contents.comps[0]
if component.sgnd:
@ -885,16 +908,17 @@ class Jp2k(Jp2kBox):
addr = ctypes.addressof(component.data.contents)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
x = np.ctypeslib.as_array(
band = np.ctypeslib.as_array(
(ctypes.c_int32 * nrows * ncols).from_address(addr))
if as_bands:
data.append(np.reshape(x.astype(dtype), (nrows, ncols)))
data.append(np.reshape(band.astype(dtype), (nrows, ncols)))
else:
data[:, :, k] = np.reshape(x.astype(dtype), (nrows, ncols))
data[:, :, k] = np.reshape(band.astype(dtype),
(nrows, ncols))
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):
"""Read a JPEG 2000 image.
@ -906,8 +930,8 @@ class Jp2k(Jp2kBox):
----------
layer : int, optional
Number of quality layer to decode.
reduce : int, optional
Factor by which to reduce output resolution.
rlevel : int, optional
Factor by which to rlevel output resolution.
area : tuple, optional
Specifies decoding image area,
(first_row, first_col, last_row, last_col)
@ -930,18 +954,18 @@ class Jp2k(Jp2kBox):
>>> import glymur
>>> jfile = glymur.data.nemo()
>>> jp = glymur.Jp2k(jfile)
>>> components_lst = jp.read_bands(reduce=1)
>>> components_lst = jp.read_bands(rlevel=1)
Raises
------
NotImplementedError
If the openjp2 library is not available.
"""
if opj2._OPENJP2 is None:
if _opj2.OPENJP2 is None:
msg = "Requires openjp2 library."
raise NotImplementedError(msg)
lst = self._read_common(reduce=reduce,
lst = self._read_common(rlevel=rlevel,
layer=layer,
area=area,
tile=tile,
@ -985,20 +1009,20 @@ class Jp2k(Jp2kBox):
IOError
If the file is JPX with more than one codestream.
"""
with open(self.filename, 'rb') as fp:
if self._codec_format == opj2._CODEC_J2K:
codestream = Codestream(fp, header_only=header_only)
with open(self.filename, 'rb') as fptr:
if self._codec_format == _opj2.CODEC_J2K:
codestream = Codestream(fptr, header_only=header_only)
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:
msg = "JP2 files must have a single codestream."
raise RuntimeError(msg)
fp.seek(box[0].offset)
buffer = fp.read(8)
(L, T) = struct.unpack('>I4s', buffer)
if L == 1:
fptr.seek(box[0].offset)
read_buffer = fptr.read(8)
(box_length, _) = struct.unpack('>I4s', read_buffer)
if box_length == 1:
# Seek past the XL field.
buffer = fp.read(8)
codestream = Codestream(fp, header_only=header_only)
read_buffer = fptr.read(8)
codestream = Codestream(fptr, header_only=header_only)
return codestream

View file

@ -1,4 +1,4 @@
"""This package organizes individual libraries employed by glymur."""
from . import openjp2
from . import openjpeg
from . import openjp2 as _openjp2
from . import openjpeg as _openjpeg
#from . import test

133
glymur/lib/config.py Normal file
View 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

View file

@ -1,35 +1,30 @@
"""Wraps library calls to openjpeg.
"""
# pylint: disable=R0903
import ctypes
from ctypes.util import find_library
import platform
import os
if os.name == "nt":
path = os.path.join('C:\\', 'Program files', 'OpenJPEG 1.5',
'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'))
from .config import glymur_config
_, OPENJPEG = glymur_config()
_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.
Corresponds to event_mgr_t type in openjpeg headers.
"""
_fields_ = [("error_handler", ctypes.c_void_p),
("warning_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.
"""
_fields_ = [("event_mgr", ctypes.POINTER(event_mgr_t)),
_fields_ = [("event_mgr", ctypes.POINTER(EventMgrType)),
("client_data", ctypes.c_void_p),
("is_decompressor", ctypes.c_bool),
("codec_format", ctypes.c_int),
@ -38,16 +33,20 @@ class common_struct_t(ctypes.Structure):
("mj2_handle", ctypes.c_void_p)]
class dinfo_t(ctypes.Structure):
"""Common fields between JPEG 2000 compression and decompression contextx.
This is for decompression contexts.
class DecompressionInfoType(ctypes.Structure):
"""This is for decompression contexts.
Corresponds to dinfo_t type in openjpeg headers.
"""
pass
class cio_t(ctypes.Structure):
_fields_ = [# codec context
("cinfo", ctypes.POINTER(common_struct_t)),
class CioType(ctypes.Structure):
"""Byte input-output stream (CIO)
Corresponds to cio_t in openjpeg headers.
"""
_fields_ = [("cinfo", ctypes.POINTER(CommonStructType)), # codec context
# STREAM_READ or STREAM_WRITE
("openmode", ctypes.c_int),
# pointer to start of buffer
@ -62,15 +61,19 @@ class cio_t(ctypes.Structure):
("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
_fields_ = [("cp_reduce", ctypes.c_int),
# cp_layer: the maximum number of quality layers to decode
("cp_layer", ctypes.c_int),
# infile: input file name
("infile", ctypes.c_char * _PATH_LEN),
("infile", ctypes.c_char * PATH_LEN),
# 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", ctypes.c_int),
# cod_format: output file format 0: PGX, 1: PxM, 2: BMP
@ -87,8 +90,11 @@ class dparameters_t(ctypes.Structure):
("flags", ctypes.c_uint)]
class image_comp_t(ctypes.Structure):
"""Defines a single image component. """
class ImageCompType(ctypes.Structure):
"""Defines a single image component.
Corresponds to image_comp_t type in openjpeg.
"""
_fields_ = [("dx", ctypes.c_int),
("dy", ctypes.c_int),
("w", ctypes.c_int),
@ -103,87 +109,105 @@ class image_comp_t(ctypes.Structure):
("data", ctypes.POINTER(ctypes.c_int))]
class image_t(ctypes.Structure):
"""Defines image data and characteristics."""
class ImageType(ctypes.Structure):
"""Defines image data and characteristics.
Corresponds to image_t type in openjpeg headers.
"""
_fields_ = [("x0", ctypes.c_int),
("y0", ctypes.c_int),
("x1", ctypes.c_int),
("y1", ctypes.c_int),
("numcomps", 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_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)),
src, len(src))
def cio_open(cinfo, 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
def _cio_close(cio):
def cio_close(cio):
"""Wraps openjpeg library function cio_close.
"""
_OPENJPEG.opj_cio_close.argtypes = [ctypes.POINTER(cio_t)]
_OPENJPEG.opj_cio_close(cio)
OPENJPEG.opj_cio_close.argtypes = [ctypes.POINTER(CioType)]
OPENJPEG.opj_cio_close(cio)
def _create_decompress(fmt):
def create_decompress(fmt):
"""Wraps openjpeg library function opj_create_decompress.
"""
_OPENJPEG.opj_create_decompress.argtypes = [ctypes.c_int]
_OPENJPEG.opj_create_decompress.restype = ctypes.POINTER(dinfo_t)
dinfo = _OPENJPEG.opj_create_decompress(fmt)
OPENJPEG.opj_create_decompress.argtypes = [ctypes.c_int]
restype = ctypes.POINTER(DecompressionInfoType)
OPENJPEG.opj_create_decompress.restype = restype
dinfo = OPENJPEG.opj_create_decompress(fmt)
return dinfo
def _decode(dinfo, cio):
def decode(dinfo, cio):
"""Wrapper for opj_decode.
"""
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(cio_t)]
_OPENJPEG.opj_decode.argtypes = argtypes
_OPENJPEG.opj_decode.restype = ctypes.POINTER(image_t)
image = _OPENJPEG.opj_decode(dinfo, cio)
argtypes = [ctypes.POINTER(DecompressionInfoType), ctypes.POINTER(CioType)]
OPENJPEG.opj_decode.argtypes = argtypes
OPENJPEG.opj_decode.restype = ctypes.POINTER(ImageType)
image = OPENJPEG.opj_decode(dinfo, cio)
return image
def _destroy_decompress(dinfo):
def destroy_decompress(dinfo):
"""Wraps openjpeg library function opj_destroy_decompress."""
_OPENJPEG.opj_destroy_decompress.argtypes = [ctypes.POINTER(dinfo_t)]
_OPENJPEG.opj_destroy_decompress(dinfo)
argtypes = [ctypes.POINTER(DecompressionInfoType)]
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."""
_OPENJPEG.opj_image_destroy.argtypes = [ctypes.POINTER(image_t)]
_OPENJPEG.opj_image_destroy(image)
OPENJPEG.opj_image_destroy.argtypes = [ctypes.POINTER(ImageType)]
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.
"""
argtypes = [ctypes.POINTER(dparameters_t)]
_OPENJPEG.opj_set_default_decoder_parameters.argtypes = argtypes
_OPENJPEG.opj_set_default_decoder_parameters(dparams_p)
argtypes = [ctypes.POINTER(DecompressionParametersType)]
OPENJPEG.opj_set_default_decoder_parameters.argtypes = argtypes
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.
"""
argtypes = [ctypes.POINTER(common_struct_t),
ctypes.POINTER(event_mgr_t),
argtypes = [ctypes.POINTER(CommonStructType),
ctypes.POINTER(EventMgrType),
ctypes.c_void_p]
_OPENJPEG.opj_set_event_mgr(ctypes.cast(dinfo,
ctypes.POINTER(common_struct_t)),
event_mgr, context)
OPENJPEG.opj_set_event_mgr.argtypes = argtypes
OPENJPEG.opj_set_event_mgr(ctypes.cast(dinfo,
ctypes.POINTER(CommonStructType)),
event_mgr, context)
def _setup_decoder(dinfo, dparams):
def setup_decoder(dinfo, dparams):
"""Wrapper for openjpeg library function opj_setup_decoder."""
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(dparameters_t)]
_OPENJPEG.opj_setup_decoder.argtypes = argtypes
_OPENJPEG.opj_setup_decoder(dinfo, dparams)
argtypes = [ctypes.POINTER(DecompressionInfoType),
ctypes.POINTER(DecompressionParametersType)]
OPENJPEG.opj_setup_decoder.argtypes = argtypes
OPENJPEG.opj_setup_decoder(dinfo, dparams)
def _version():
def version():
"""Wrapper for opj_version library routine."""
_OPENJPEG.opj_version.restype = ctypes.c_char_p
v = _OPENJPEG.opj_version()
return v.decode('utf-8')
OPENJPEG.opj_version.restype = ctypes.c_char_p
library_version = OPENJPEG.opj_version()
return library_version.decode('utf-8')

View file

@ -12,13 +12,7 @@ import numpy as np
import glymur
def load_tests(loader, tests, ignore):
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,
@unittest.skipIf(glymur.lib._openjp2.OPENJP2 is None,
"Missing openjp2 library.")
class TestOpenJP2(unittest.TestCase):
@ -29,7 +23,7 @@ class TestOpenJP2(unittest.TestCase):
pass
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.cblockw_init, 64)
@ -38,7 +32,7 @@ class TestOpenJP2(unittest.TestCase):
self.assertEqual(cparams.subsampling_dx, 1)
self.assertEqual(cparams.subsampling_dy, 1)
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.cp_tx0, 0)
self.assertEqual(cparams.cp_ty0, 0)
@ -46,7 +40,7 @@ class TestOpenJP2(unittest.TestCase):
self.assertEqual(cparams.irreversible, 0)
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_y0, 0)
@ -55,34 +49,34 @@ class TestOpenJP2(unittest.TestCase):
def tile_macro(self, codec, stream, imagep, tidx):
# 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):
self.assertIsNotNone(imagep.contents.comps[j].data)
def j2k_random_tile_access(self, filename, codec_format=None):
# 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()
nelts = glymur.lib.openjp2._PATH_LEN - len(infile)
nelts = glymur.lib._openjp2.PATH_LEN - len(infile)
infile += b'0' * nelts
dparam.infile = infile
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_warning_handler(codec, None)
glymur.lib.openjp2._set_error_handler(codec, None)
glymur.lib._openjp2.set_info_handler(codec, None)
glymur.lib._openjp2.set_warning_handler(codec, None)
glymur.lib._openjp2.set_error_handler(codec, None)
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)
image = glymur.lib.openjp2._read_header(stream, codec)
glymur.lib._openjp2.setup_decoder(codec, dparam)
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_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_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._destroy_codec(codec)
glymur.lib.openjp2._stream_destroy_v3(stream)
glymur.lib.openjp2._image_destroy(image)
glymur.lib._openjp2.end_decompress(codec, stream)
glymur.lib._openjp2.destroy_codec(codec)
glymur.lib._openjp2.stream_destroy_v3(stream)
glymur.lib._openjp2.image_destroy(image)
def tile_decoder(self, x0=None, y0=None, x1=None, y1=None, filename=None,
codec_format=None):
x = (filename, True)
stream = glymur.lib.openjp2._stream_create_default_file_stream_v3(*x)
dparam = glymur.lib.openjp2._set_default_decoder_parameters()
stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x)
dparam = glymur.lib._openjp2.set_default_decoder_parameters()
dparam.decod_format = codec_format
@ -115,30 +109,30 @@ class TestOpenJP2(unittest.TestCase):
# do not use resolution reductions.
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_warning_handler(codec, None)
glymur.lib.openjp2._set_error_handler(codec, None)
glymur.lib._openjp2.set_info_handler(codec, None)
glymur.lib._openjp2.set_warning_handler(codec, None)
glymur.lib._openjp2.set_error_handler(codec, None)
glymur.lib.openjp2._setup_decoder(codec, dparam)
image = glymur.lib.openjp2._read_header(stream, codec)
glymur.lib.openjp2._set_decode_area(codec, image, x0, y0, x1, y1)
glymur.lib._openjp2.setup_decoder(codec, dparam)
image = glymur.lib._openjp2.read_header(stream, codec)
glymur.lib._openjp2.set_decode_area(codec, image, x0, y0, x1, y1)
data = np.zeros((1150, 2048, 3), dtype=np.uint8)
while True:
rargs = glymur.lib.openjp2._read_tile_header(codec, stream)
rargs = glymur.lib._openjp2.read_tile_header(codec, stream)
tidx = rargs[0]
sz = rargs[1]
go_on = rargs[-1]
if not go_on:
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._destroy_codec(codec)
glymur.lib.openjp2._stream_destroy_v3(stream)
glymur.lib.openjp2._image_destroy(image)
glymur.lib._openjp2.end_decompress(codec, stream)
glymur.lib._openjp2.destroy_codec(codec)
glymur.lib._openjp2.stream_destroy_v3(stream)
glymur.lib._openjp2.image_destroy(image)
def tile_encoder(self, num_comps=None, tile_width=None, tile_height=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 = (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.cp_fixed_quality = 1
@ -170,9 +164,9 @@ class TestOpenJP2(unittest.TestCase):
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):
l_params[j].dx = 1
l_params[j].dy = 1
@ -183,38 +177,38 @@ class TestOpenJP2(unittest.TestCase):
l_params[j].x0 = 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_warning_handler(codec, None)
glymur.lib.openjp2._set_error_handler(codec, None)
glymur.lib._openjp2.set_info_handler(codec, None)
glymur.lib._openjp2.set_warning_handler(codec, None)
glymur.lib._openjp2.set_error_handler(codec, None)
cspace = glymur.lib.openjp2._CLRSPC_SRGB
l_image = glymur.lib.openjp2._image_tile_create(l_params, cspace)
cspace = glymur.lib._openjp2.CLRSPC_SRGB
l_image = glymur.lib._openjp2.image_tile_create(l_params, cspace)
l_image.contents.x0 = 0
l_image.contents.y0 = 0
l_image.contents.x1 = image_width
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)
stream = glymur.lib.openjp2._stream_create_default_file_stream_v3(*x)
glymur.lib.openjp2._start_compress(codec, l_image, stream)
stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x)
glymur.lib._openjp2.start_compress(codec, l_image, stream)
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._stream_destroy_v3(stream)
glymur.lib.openjp2._destroy_codec(codec)
glymur.lib.openjp2._image_destroy(l_image)
glymur.lib._openjp2.end_compress(codec, stream)
glymur.lib._openjp2.stream_destroy_v3(stream)
glymur.lib._openjp2.destroy_codec(codec)
glymur.lib._openjp2.image_destroy(l_image)
def tte0_setup(self, filename):
kwargs = {'filename': filename,
'codec': glymur.lib.openjp2._CODEC_J2K,
'codec': glymur.lib._openjp2.CODEC_J2K,
'comp_prec': 8,
'irreversible': 1,
'num_comps': 3,
@ -241,12 +235,12 @@ class TestOpenJP2(unittest.TestCase):
'x1': 1000,
'y1': 1000,
'filename': tfile.name,
'codec_format': glymur.lib.openjp2._CODEC_J2K}
'codec_format': glymur.lib._openjp2.CODEC_J2K}
self.tile_decoder(**kwargs)
def tte1_setup(self, filename):
kwargs = {'filename': filename,
'codec': glymur.lib.openjp2._CODEC_J2K,
'codec': glymur.lib._openjp2.CODEC_J2K,
'comp_prec': 8,
'irreversible': 1,
'num_comps': 3,
@ -273,7 +267,7 @@ class TestOpenJP2(unittest.TestCase):
'x1': 128,
'y1': 128,
'filename': tfile.name,
'codec_format': glymur.lib.openjp2._CODEC_J2K}
'codec_format': glymur.lib._openjp2.CODEC_J2K}
self.tile_decoder(**kwargs)
def test_rta1(self):
@ -281,12 +275,12 @@ class TestOpenJP2(unittest.TestCase):
# Runs test designated rta1 in OpenJPEG test suite.
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)
def tte2_setup(self, filename):
kwargs = {'filename': filename,
'codec': glymur.lib.openjp2._CODEC_JP2,
'codec': glymur.lib._openjp2.CODEC_JP2,
'comp_prec': 8,
'irreversible': 1,
'num_comps': 3,
@ -312,7 +306,7 @@ class TestOpenJP2(unittest.TestCase):
'x1': 128,
'y1': 128,
'filename': tfile.name,
'codec_format': glymur.lib.openjp2._CODEC_JP2}
'codec_format': glymur.lib._openjp2.CODEC_JP2}
self.tile_decoder(**kwargs)
def test_rta2(self):
@ -320,12 +314,12 @@ class TestOpenJP2(unittest.TestCase):
# Runs test designated rta2 in OpenJPEG test suite.
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)
def tte3_setup(self, filename):
kwargs = {'filename': filename,
'codec': glymur.lib.openjp2._CODEC_J2K,
'codec': glymur.lib._openjp2.CODEC_J2K,
'comp_prec': 8,
'irreversible': 1,
'num_comps': 1,
@ -345,12 +339,12 @@ class TestOpenJP2(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
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)
def tte4_setup(self, filename):
kwargs = {'filename': filename,
'codec': glymur.lib.openjp2._CODEC_J2K,
'codec': glymur.lib._openjp2.CODEC_J2K,
'comp_prec': 8,
'irreversible': 0,
'num_comps': 1,
@ -370,12 +364,12 @@ class TestOpenJP2(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
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)
def tte5_setup(self, filename):
kwargs = {'filename': filename,
'codec': glymur.lib.openjp2._CODEC_J2K,
'codec': glymur.lib._openjp2.CODEC_J2K,
'comp_prec': 8,
'irreversible': 0,
'num_comps': 1,
@ -395,7 +389,7 @@ class TestOpenJP2(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
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)
if __name__ == "__main__":

View file

@ -3,7 +3,7 @@ import unittest
import glymur
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
@unittest.skipIf(glymur.lib._openjpeg.OPENJPEG is None,
"Missing openjpeg library.")
class TestOpenJPEG(unittest.TestCase):
@ -14,15 +14,15 @@ class TestOpenJPEG(unittest.TestCase):
pass
def test_version(self):
v = glymur.lib.openjpeg._version()
v = glymur.lib._openjpeg.version()
parts = v.split('.')
self.assertEqual(parts[0], '1')
self.assertEqual(parts[1], '5')
def test_set_default_decoder_parameters(self):
# Verify that we properly set the default decode parameters.
dp = glymur.lib.openjpeg.dparameters_t()
glymur.lib.openjpeg._set_default_decoder_parameters(ctypes.byref(dp))
dp = glymur.lib._openjpeg.DecompressionParametersType()
glymur.lib._openjpeg.set_default_decoder_parameters(ctypes.byref(dp))
self.assertEqual(dp.cp_reduce, 0)
self.assertEqual(dp.cp_layer, 0)

View file

@ -5,6 +5,7 @@ from .test_jp2k import TestJp2k as jp2k
from .test_icc import TestICC as icc
from .test_printing import TestPrinting as printing
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_neg import TestSuiteNegative as suiteneg
from .test_jp2box import TestJp2Boxes as box

View file

@ -14,7 +14,7 @@ else:
import glymur
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
class TestCallbacks(unittest.TestCase):
@ -46,7 +46,7 @@ class TestCallbacks(unittest.TestCase):
# Verify that we get the expected stdio output when our internal info
# callback handler is enabled.
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()
lines = ['[INFO] Start to read j2k main header (0).',
@ -60,7 +60,7 @@ class TestCallbacks(unittest.TestCase):
self.assertEqual(actual, expected)
@unittest.skipIf(glymur.lib.openjp2._OPENJPEG is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJPEG is None,
"Missing openjpeg library.")
class TestCallbacks15(unittest.TestCase):
"""This test suite is for OpenJPEG 1.5.1 properties.
@ -69,13 +69,13 @@ class TestCallbacks15(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
cls.openjp2 = glymur.lib.openjp2._OPENJP2
glymur.lib.openjp2._OPENJP2 = None
cls.openjp2 = glymur.lib.openjp2.OPENJP2
glymur.lib.openjp2.OPENJP2 = None
@classmethod
def tearDownClass(cls):
# Restore OPENJP2
glymur.lib.openjp2._OPENJP2 = cls.openjp2
glymur.lib.openjp2.OPENJP2 = cls.openjp2
def setUp(self):
# Save sys.stdout.
@ -92,7 +92,7 @@ class TestCallbacks15(unittest.TestCase):
# Verify that we get the expected stdio output when our internal info
# callback handler is enabled.
j = glymur.Jp2k(self.j2kfile)
d = j.read(reduce=1, verbose=True)
d = j.read(rlevel=1, verbose=True)
actual = sys.stdout.getvalue().strip()
regex = re.compile(r"""\[INFO\]\stile\s1\sof\s1\s+

View file

@ -54,9 +54,9 @@ class TestCodestream(unittest.TestCase):
j = Jp2k(tfile.name)
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].data, b'\x00')
self.assertEqual(c.segment[2]._data, b'\x00')
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
@ -84,9 +84,9 @@ class TestCodestream(unittest.TestCase):
j = Jp2k(tfile.name)
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].data, b'\x00')
self.assertEqual(c.segment[2]._data, b'\x00')
if __name__ == "__main__":
unittest.main()

View file

@ -21,7 +21,7 @@ from glymur.lib import openjp2 as opj2
@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.")
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
@ -55,7 +55,7 @@ class TestSuite(unittest.TestCase):
filename = os.path.join(configdir, 'glymurrc')
with open(filename, 'wb') as tfile:
tfile.write('[library]\n'.encode())
libloc = glymur.lib.openjp2._OPENJP2._name
libloc = glymur.lib.openjp2.OPENJP2._name
line = 'openjp2: {0}\n'.format(libloc)
tfile.write(line.encode())
tfile.flush()

View file

@ -18,7 +18,7 @@ def load_tests(loader, tests, ignore):
return tests
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
class TestChannelDefinition(unittest.TestCase):
@ -58,9 +58,9 @@ class TestChannelDefinition(unittest.TestCase):
j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
self.jP = JPEG2000SignatureBox()
self.ftyp = FileTypeBox()
@ -88,7 +88,7 @@ class TestChannelDefinition(unittest.TestCase):
jp2 = Jp2k(tfile.name)
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(jp2h.box[2].index, (0, 1, 2))
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0))
@ -108,7 +108,7 @@ class TestChannelDefinition(unittest.TestCase):
jp2 = Jp2k(tfile.name)
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(jp2h.box[2].index, (0, 1, 2, 3))
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0, 1))
@ -141,7 +141,7 @@ class TestChannelDefinition(unittest.TestCase):
jp2 = Jp2k(tfile.name)
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(jp2h.box[2].index, (0,))
self.assertEqual(jp2h.box[2].channel_type, (0,))
@ -161,7 +161,7 @@ class TestChannelDefinition(unittest.TestCase):
jp2 = Jp2k(tfile.name)
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(jp2h.box[2].index, (0, 1))
self.assertEqual(jp2h.box[2].channel_type, (0, 1))
@ -268,9 +268,9 @@ class TestXML(unittest.TestCase):
j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
self.jP = JPEG2000SignatureBox()
self.ftyp = FileTypeBox()
@ -309,7 +309,7 @@ class TestXML(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes)
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),
b'<data>0</data>')
@ -326,7 +326,7 @@ class TestXML(unittest.TestCase):
j2k.wrap(tfile.name, boxes=boxes)
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 ',
'jp2c'])
@ -345,9 +345,9 @@ class TestColourSpecificationBox(unittest.TestCase):
j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
self.jP = JPEG2000SignatureBox()
self.ftyp = FileTypeBox()
@ -409,7 +409,7 @@ class TestColourSpecificationBox(unittest.TestCase):
approximation=approx)
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
class TestJp2Boxes(unittest.TestCase):
@ -449,37 +449,37 @@ class TestJp2Boxes(unittest.TestCase):
def test_default_ContiguousCodestreamBox(self):
b = ContiguousCodestreamBox()
self.assertEqual(b.id, 'jp2c')
self.assertEqual(b.main_header, [])
self.assertEqual(b.box_id, 'jp2c')
self.assertIsNone(b.main_header)
def verify_wrapped_raw(self, jp2file):
# Shared method by at least two tests.
jp2 = Jp2k(jp2file)
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].length, 12)
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].length, 20)
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].length, 45)
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].length, 115228)
# jp2h super box
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].length, 22)
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].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].length, 15)
self.assertEqual(jp2.box[2].box[1].longname, 'Colour Specification')
@ -511,7 +511,7 @@ class TestJp2Boxes(unittest.TestCase):
j2k = Jp2k(self.j2kfile)
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
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'])
def test_default_layout_but_with_specified_boxes(self):
@ -521,9 +521,9 @@ class TestJp2Boxes(unittest.TestCase):
JP2HeaderBox(),
ContiguousCodestreamBox()]
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
boxes[2].box = [ImageHeaderBox(height=height,
width=width,
num_components=num_components),
@ -540,9 +540,9 @@ class TestJp2Boxes(unittest.TestCase):
JP2HeaderBox(),
ContiguousCodestreamBox()]
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
boxes[2].box = [ColourSpecificationBox(colorspace=glymur.core.SRGB),
ImageHeaderBox(height=height,
width=width,
@ -554,9 +554,9 @@ class TestJp2Boxes(unittest.TestCase):
def test_first_2_boxes_not_jP_and_ftyp(self):
j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
jP = JPEG2000SignatureBox()
ftyp = FileTypeBox()
@ -574,9 +574,9 @@ class TestJp2Boxes(unittest.TestCase):
def test_jp2h_not_preceeding_jp2c(self):
j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
jP = JPEG2000SignatureBox()
ftyp = FileTypeBox()
@ -594,9 +594,9 @@ class TestJp2Boxes(unittest.TestCase):
def test_missing_codestream(self):
j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream()
height = c.segment[1].Ysiz
width = c.segment[1].Xsiz
num_components = len(c.segment[1].XRsiz)
height = c.segment[1].ysiz
width = c.segment[1].xsiz
num_components = len(c.segment[1].xrsiz)
jP = JPEG2000SignatureBox()
ftyp = FileTypeBox()

View file

@ -33,12 +33,12 @@ except:
# Doc tests should be run as well.
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'))
return tests
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
class TestJp2k(unittest.TestCase):
@ -88,11 +88,11 @@ class TestJp2k(unittest.TestCase):
with self.assertWarns(UserWarning) as cw:
jp2k = Jp2k(self._bad_xml_file)
def test_reduce_max(self):
# Verify that reduce=-1 gets us the lowest resolution image
def test_rlevel_max(self):
# Verify that rlevel=-1 gets us the lowest resolution image
j = Jp2k(self.j2kfile)
thumbnail1 = j.read(reduce=-1)
thumbnail2 = j.read(reduce=5)
thumbnail1 = j.read(rlevel=-1)
thumbnail2 = j.read(rlevel=5)
np.testing.assert_array_equal(thumbnail1, thumbnail2)
self.assertEqual(thumbnail1.shape, (25, 15, 3))
@ -102,7 +102,7 @@ class TestJp2k(unittest.TestCase):
warnings.simplefilter("ignore")
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].length, 28)
self.assertIsNone(jp2k.box[3].xml)
@ -120,11 +120,11 @@ class TestJp2k(unittest.TestCase):
# End corner must be >= start corner
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.
j = Jp2k(self.jp2file)
with self.assertRaises(IOError):
d = j.read(reduce=6)
d = j.read(rlevel=6)
def test_not_JPEG2000(self):
# 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)
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):
# MCT usage makes no sense for grayscale images.
@ -167,7 +167,7 @@ class TestJp2k(unittest.TestCase):
def test_write_cprl(self):
# Issue 17
j = Jp2k(self.jp2file)
expdata = j.read(reduce=1)
expdata = j.read(rlevel=1)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
ofile.write(expdata, prog='CPRL')
@ -175,7 +175,7 @@ class TestJp2k(unittest.TestCase):
np.testing.assert_array_equal(actdata, expdata)
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):
# Verify the boxes of a JP2 file.
@ -184,37 +184,37 @@ class TestJp2k(unittest.TestCase):
# top-level boxes
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].length, 12)
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].length, 20)
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].length, 45)
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].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].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].length, 1132296)
# jp2h super box
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].length, 22)
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].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].length, 15)
self.assertEqual(jp2k.box[2].box[1].longname, 'Colour Specification')
@ -272,7 +272,7 @@ class TestJp2k(unittest.TestCase):
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].length, 1133427 + 8)
@ -303,8 +303,8 @@ class TestJp2k(unittest.TestCase):
# The top level boxes in each file should match.
for j in range(len(baseline_jp2.box)):
self.assertEqual(new_jp2.box[j].id,
baseline_jp2.box[j].id)
self.assertEqual(new_jp2.box[j].box_id,
baseline_jp2.box[j].box_id)
self.assertEqual(new_jp2.box[j].offset,
baseline_jp2.box[j].offset)
self.assertEqual(new_jp2.box[j].length,
@ -344,7 +344,7 @@ class TestJp2k(unittest.TestCase):
c = j.get_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):
# OpenJP2 only allows 2D or 3D images.
@ -479,23 +479,23 @@ class TestJp2k(unittest.TestCase):
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].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].length, 26)
ulst = []
ulst.append(uuid.UUID('00000000-0000-0000-0000-000000000000'))
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].length, 16)
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].URL, 'abcd')
self.assertEqual(jp2k.box[3].box[1].url, 'abcd')
def test_xml_box_with_trailing_nulls(self):
# ElementTree does not like trailing null chars after valid XML
@ -522,14 +522,14 @@ class TestJp2k(unittest.TestCase):
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].length, 36)
def test_asoc_label_box(self):
# Construct a fake file with an asoc and a label box, as
# 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:
j = Jp2k(tfile.name, 'wb')
j.write(data)
@ -567,10 +567,10 @@ class TestJp2k(unittest.TestCase):
tfile2.flush()
jasoc = Jp2k(tfile2.name)
self.assertEqual(jasoc.box[3].id, 'asoc')
self.assertEqual(jasoc.box[3].box[0].id, 'lbl ')
self.assertEqual(jasoc.box[3].box_id, 'asoc')
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[1].id, 'xml ')
self.assertEqual(jasoc.box[3].box[1].box_id, 'xml ')
def test_openjpeg_library_message(self):
# Verify the error message produced by the openjpeg library.
@ -599,11 +599,11 @@ class TestJp2k(unittest.TestCase):
Invalid\svalues\sfor\scomp\s=\s0\s+
:\sdx=1\sdy=0''', re.VERBOSE)
if sys.hexversion < 0x03020000:
with self.assertRaisesRegexp(IOError, regexp) as ce:
d = j.read(reduce=3)
with self.assertRaisesRegexp((IOError, OSError), regexp) as ce:
d = j.read(rlevel=1)
else:
with self.assertRaisesRegex(IOError, regexp) as ce:
d = j.read(reduce=3)
with self.assertRaisesRegex((IOError, OSError), regexp) as ce:
d = j.read(rlevel=1)
def test_xmp_attribute(self):
# 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())
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
@unittest.skipIf(glymur.lib.openjpeg.OPENJPEG is None,
"Missing openjpeg library.")
class TestJp2k15(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
cls.openjp2 = glymur.lib.openjp2._OPENJP2
glymur.lib.openjp2._OPENJP2 = None
cls.openjp2 = glymur.lib.openjp2.OPENJP2
glymur.lib.openjp2.OPENJP2 = None
@classmethod
def tearDownClass(cls):
# Restore OPENJP2
glymur.lib.openjp2._OPENJP2 = cls.openjp2
glymur.lib.openjp2.OPENJP2 = cls.openjp2
def setUp(self):
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
# working JP2 test.
j2k = Jp2k(self.jp2file)
d = j2k.read(reduce=1)
d = j2k.read(rlevel=1)
def test_basic_j2k(self):
# This test is only useful when openjp2 is not available

File diff suppressed because it is too large Load diff

View file

@ -57,7 +57,7 @@ def read_image(infile):
return data
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
@unittest.skipIf(no_read_backend, no_read_backend_msg)
@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,
# not EOC. Codestream parsing should stop when we try to jump to
# the end of SOT.
self.assertEqual(c.segment[-1].id, 'SOD')
self.assertEqual(c.segment[-1].marker_id, 'SOD')
@unittest.skipIf(sys.hexversion < 0x03020000,
"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,
# not EOC. Codestream parsing should stop when we try to jump to
# the end of SOT.
self.assertEqual(c.segment[-1].id, 'SOD')
self.assertEqual(c.segment[-1].marker_id, 'SOD')
@unittest.skipIf(sys.hexversion < 0x03020000,
"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,
# not EOC. Codestream parsing should stop when we try to jump to
# 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):
# 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):
# Seems like precinct sizes should be powers of two.
ifile = Jp2k(self.j2kfile)
data = ifile.read(reduce=2)
data = ifile.read(rlevel=2)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError) as ce:
@ -166,7 +166,7 @@ class TestSuiteNegative(unittest.TestCase):
def test_codeblock_size_not_multiple_of_two(self):
# Seems like code block sizes should be powers of two.
ifile = Jp2k(self.j2kfile)
data = ifile.read(reduce=2)
data = ifile.read(rlevel=2)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
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
# precinct size.
ifile = Jp2k(self.j2kfile)
data = ifile.read(reduce=2)
data = ifile.read(rlevel=2)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError) as ce:

View file

@ -57,7 +57,7 @@ def read_image(infile):
return data
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
@unittest.skipIf(no_read_backend, no_read_backend_msg)
@unittest.skipIf(data_root is None,
@ -83,50 +83,50 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(640, 480))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding bypass
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# Reset context probabilities
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
self.assertFalse(c.segment[2].spcod[7] & 0x02)
# Termination on each coding pass
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
def test_NR_ENC_Bretagne1_ppm_2_encode(self):
# NR-ENC-Bretagne1.ppm-2-encode
@ -141,50 +141,50 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(640, 480))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 1) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 1) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding bypass
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# Reset context probabilities
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
self.assertFalse(c.segment[2].spcod[7] & 0x02)
# Termination on each coding pass
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
def test_NR_ENC_Bretagne1_ppm_3_encode(self):
# NR-ENC-Bretagne1.ppm-3-encode
@ -200,49 +200,49 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(640, 480))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(16, 16)) # cblksz
# Selective arithmetic coding bypass
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# Reset context probabilities
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
self.assertFalse(c.segment[2].spcod[7] & 0x02)
# Termination on each coding pass
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(c.segment[2]._precinct_size,
[(2, 2), (4, 4), (8, 8), (16, 16), (32, 32),
(64, 64)])
@ -263,49 +263,49 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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]))
# 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.
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(640, 480))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(32, 32)) # cblksz
# Selective arithmetic coding bypass
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# Reset context probabilities
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
self.assertFalse(c.segment[2].spcod[7] & 0x02)
# Termination on each coding pass
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(c.segment[2]._precinct_size,
[(16, 16), (32, 32), (64, 64)] + [(128, 128)] * 3)
@ -321,50 +321,50 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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]))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(127, 127))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.PCRL)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding bypass
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# Reset context probabilities
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
self.assertFalse(c.segment[2].spcod[7] & 0x02)
# Termination on each coding pass
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
def test_NR_ENC_Bretagne2_ppm_6_encode(self):
# NR-ENC-Bretagne2.ppm-6-encode
@ -378,53 +378,53 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(5183, 3887))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertTrue(c.segment[2].Scod & 2) # sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertTrue(c.segment[2].scod & 2) # sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding bypass
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# Reset context probabilities
self.assertFalse(c.segment[2].SPcod[7] & 0x02)
self.assertFalse(c.segment[2].spcod[7] & 0x02)
# Termination on each coding pass
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
# 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)))
def test_NR_ENC_Bretagne2_ppm_7_encode(self):
@ -438,53 +438,53 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(2592, 1944))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertTrue(c.segment[2].Scod & 4) # eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertTrue(c.segment[2].scod & 4) # eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding BYPASS
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# 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)
self.assertTrue(c.segment[2].SPcod[7] & 0x04)
self.assertTrue(c.segment[2].spcod[7] & 0x04)
# Vertically causal context (VSC)
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination, ERTERM(SEGTERM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols, SEGMARK(SEGSYSM)
self.assertTrue(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertTrue(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
# 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)
def test_NR_ENC_Bretagne2_ppm_8_encode(self):
@ -498,51 +498,51 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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))
# Tile size
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(2742, 2244))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding BYPASS
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# 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)
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context (VSC)
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination, ERTERM(SEGTERM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols, SEGMARK(SEGSYSM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
def test_NR_ENC_Cevennes1_bmp_9_encode(self):
infile = os.path.join(data_root, 'input/nonregression/Cevennes1.bmp')
@ -555,50 +555,50 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(2592, 1944))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding BYPASS
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# 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)
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context (VSC)
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination, ERTERM(SEGTERM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols, SEGMARK(SEGSYSM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
def test_NR_ENC_Cevennes2_ppm_10_encode(self):
infile = os.path.join(data_root, 'input/nonregression/Cevennes2.ppm')
@ -611,50 +611,50 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(640, 480))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding BYPASS
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# 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)
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context (VSC)
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination, ERTERM(SEGTERM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols, SEGMARK(SEGSYSM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
def test_NR_ENC_Rome_bmp_11_encode(self):
infile = os.path.join(data_root, 'input/nonregression/Rome.bmp')
@ -663,11 +663,11 @@ class TestSuiteWrite(unittest.TestCase):
jp2 = Jp2k(tfile.name, 'wb')
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']
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'])
# Signature box. Check for corruption.
@ -701,51 +701,51 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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))
# Tile size
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(640, 480))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8))
# signed
self.assertEqual(c.segment[1]._signed, (False, False, False))
# 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)
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 3) # layers = 3
self.assertEqual(c.segment[2].SPcod[3], 1) # mct
self.assertEqual(c.segment[2].SPcod[4], 2) # levels
self.assertEqual(c.segment[2].spcod[3], 1) # mct
self.assertEqual(c.segment[2].spcod[4], 2) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding BYPASS
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# 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)
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context (VSC)
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination, ERTERM(SEGTERM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols, SEGMARK(SEGSYSM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
@unittest.skip("Known failure in openjpeg test suite.")
def test_NR_ENC_random_issue_0005_tif_12_encode(self):
@ -762,50 +762,50 @@ class TestSuiteWrite(unittest.TestCase):
# SIZ: Image and tile size
# Profile: "0" means profile 2
self.assertEqual(c.segment[1].Rsiz, 0)
self.assertEqual(c.segment[1].rsiz, 0)
# 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))
# 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
self.assertEqual((c.segment[1].XTsiz, c.segment[1].YTsiz),
self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz),
(1024, 1024))
# Tile offset
self.assertEqual((c.segment[1].XTOsiz, c.segment[1].YTOsiz),
self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz),
(0, 0))
# bitdepth
self.assertEqual(c.segment[1]._bitdepth, (16,))
# signed
self.assertEqual(c.segment[1]._signed, (False,))
# 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)])
# COD: Coding style default
self.assertFalse(c.segment[2].Scod & 2) # no sop
self.assertFalse(c.segment[2].Scod & 4) # no eph
self.assertEqual(c.segment[2].SPcod[0], glymur.core.LRCP)
self.assertFalse(c.segment[2].scod & 2) # no sop
self.assertFalse(c.segment[2].scod & 4) # no eph
self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP)
self.assertEqual(c.segment[2]._layers, 1) # layers = 1
self.assertEqual(c.segment[2].SPcod[3], 0) # mct
self.assertEqual(c.segment[2].SPcod[4], 5) # levels
self.assertEqual(c.segment[2].spcod[3], 0) # mct
self.assertEqual(c.segment[2].spcod[4], 5) # levels
self.assertEqual(tuple(c.segment[2]._code_block_size),
(64, 64)) # cblksz
# Selective arithmetic coding BYPASS
self.assertFalse(c.segment[2].SPcod[7] & 0x01)
self.assertFalse(c.segment[2].spcod[7] & 0x01)
# 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)
self.assertFalse(c.segment[2].SPcod[7] & 0x04)
self.assertFalse(c.segment[2].spcod[7] & 0x04)
# Vertically causal context (VSC)
self.assertFalse(c.segment[2].SPcod[7] & 0x08)
self.assertFalse(c.segment[2].spcod[7] & 0x08)
# Predictable termination, ERTERM(SEGTERM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0010)
self.assertFalse(c.segment[2].spcod[7] & 0x0010)
# Segmentation symbols, SEGMARK(SEGSYSM)
self.assertFalse(c.segment[2].SPcod[7] & 0x0020)
self.assertEqual(c.segment[2].SPcod[8],
glymur.core.WAVELET_TRANSFORM_5x3_REVERSIBLE)
self.assertEqual(len(c.segment[2].SPcod), 9)
self.assertFalse(c.segment[2].spcod[7] & 0x0020)
self.assertEqual(c.segment[2].spcod[8],
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(c.segment[2].spcod), 9)
if __name__ == "__main__":
unittest.main()

View file

@ -21,7 +21,7 @@ except:
raise
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.")
class TestPrintingNeedsLib(unittest.TestCase):
"""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:
cls._plain_nemo_file = tfile.name
ijfile = Jp2k(jp2file)
data = ijfile.read(reduce=1)
data = ijfile.read(rlevel=1)
ojfile = Jp2k(cls._plain_nemo_file, 'wb')
ojfile.write(data)
@ -122,7 +122,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
def test_asoc_label_box(self):
# Construct a fake file with an asoc and a label box, as
# 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:
j = glymur.Jp2k(tfile.name, 'wb')
j.write(data)
@ -640,6 +640,7 @@ class TestPrinting(unittest.TestCase):
' CME marker segment @ (3209, 37)',
' "Created by OpenJPEG version 2.0.0"']
expected = '\n'.join(lst)
self.maxDiff = None
self.assertEqual(actual, expected)
@unittest.skipIf(data_root is None,