Merge branch 'devel' into issue104
This commit is contained in:
commit
6948f40f27
8 changed files with 568 additions and 146 deletions
|
|
@ -1,3 +1,6 @@
|
|||
Oct 22, 2013 - v0.5.7 Super box constructors now take optional box list
|
||||
argument. Removed ssiz attribute from SIZsegment class.
|
||||
|
||||
Oct 13, 2013 - v0.5.6 Fixed handling of non-ascii chars in XML boxes. Fixed
|
||||
some docstring errors in jp2box module.
|
||||
|
||||
|
|
|
|||
|
|
@ -646,16 +646,50 @@ class Codestream(object):
|
|||
length, = struct.unpack('>H', read_buffer)
|
||||
|
||||
xy_buffer = fptr.read(36)
|
||||
data = struct.unpack('>HIIIIIIIIH', xy_buffer)
|
||||
|
||||
num_components, = struct.unpack('>H', xy_buffer[-2:])
|
||||
rsiz = data[0]
|
||||
xysiz = (data[1], data[2])
|
||||
xyosiz = (data[3], data[4])
|
||||
xytsiz = (data[5], data[6])
|
||||
xytosiz = (data[7], data[8])
|
||||
|
||||
component_buffer = fptr.read(num_components * 3)
|
||||
# Csiz is the number of components
|
||||
Csiz = data[9]
|
||||
|
||||
segment = SIZsegment(xy_buffer, component_buffer, length, offset)
|
||||
component_buffer = fptr.read(Csiz * 3)
|
||||
data = struct.unpack('>' + 'B' * len(component_buffer),
|
||||
component_buffer)
|
||||
|
||||
bitdepth = tuple(((x & 0x7f) + 1) for x in data[0::3])
|
||||
signed = tuple(((x & 0xb0) > 0) for x in data[0::3])
|
||||
|
||||
xrsiz = data[1::3]
|
||||
yrsiz = data[2::3]
|
||||
|
||||
for j, subsampling in enumerate(zip(xrsiz, yrsiz)):
|
||||
if 0 in subsampling:
|
||||
msg = "Invalid subsampling value for component {0}: "
|
||||
msg += "dx={1}, dy={2}."
|
||||
msg = msg.format(j, subsampling[0], subsampling[1])
|
||||
warnings.warn(msg)
|
||||
|
||||
kwargs = {'rsiz': rsiz,
|
||||
'xysiz': xysiz,
|
||||
'xyosiz': xyosiz,
|
||||
'xytsiz': xytsiz,
|
||||
'xytosiz': xytosiz,
|
||||
'Csiz': Csiz,
|
||||
'bitdepth': bitdepth,
|
||||
'signed': signed,
|
||||
'xyrsiz': (xrsiz, yrsiz),
|
||||
'length': length,
|
||||
'offset': offset}
|
||||
segment = SIZsegment(**kwargs)
|
||||
|
||||
# Need to keep track of the number of components from SIZ for
|
||||
# other markers
|
||||
self._csiz = len(segment.ssiz)
|
||||
# other markers.
|
||||
self._csiz = Csiz
|
||||
|
||||
return segment
|
||||
|
||||
|
|
@ -1441,8 +1475,8 @@ class SIZsegment(Segment):
|
|||
Width and height of reference tile with respect to the reference grid.
|
||||
xtosiz, ytosiz : int
|
||||
Horizontal and vertical offsets of tile from origin of reference grid.
|
||||
ssiz : iterable bytes
|
||||
Encoded precision (depth) in bits and sign of each component.
|
||||
Csiz : int
|
||||
Number of components in image.
|
||||
bitdepth : iterable bytes
|
||||
Precision (depth) in bits of each component.
|
||||
signed : iterable bool
|
||||
|
|
@ -1457,21 +1491,20 @@ class SIZsegment(Segment):
|
|||
15444-1:2004 - Information technology -- JPEG 2000 image coding system:
|
||||
Core coding system
|
||||
"""
|
||||
def __init__(self, xy_buffer, component_buffer, length, offset):
|
||||
Segment.__init__(self, marker_id='SIZ')
|
||||
def __init__(self, rsiz=-1, xysiz=None, xyosiz=-1, xytsiz=-1, xytosiz=-1,
|
||||
Csiz=-1, bitdepth=None, signed=None, xyrsiz=-1, length=-1,
|
||||
offset=-1):
|
||||
Segment.__init__(self, marker_id='SIZ', length=length, offset=offset)
|
||||
|
||||
data = struct.unpack('>HIIIIIIIIH', xy_buffer)
|
||||
|
||||
self.rsiz = data[0]
|
||||
self.xsiz = data[1]
|
||||
self.ysiz = data[2]
|
||||
self.xosiz = data[3]
|
||||
self.yosiz = data[4]
|
||||
self.xtsiz = data[5]
|
||||
self.ytsiz = data[6]
|
||||
self.xtosiz = data[7]
|
||||
self.ytosiz = data[8]
|
||||
# disregarding the last element in data
|
||||
self.rsiz = rsiz
|
||||
self.xsiz, self.ysiz = xysiz
|
||||
self.xosiz, self.yosiz = xyosiz
|
||||
self.xtsiz, self.ytsiz = xytsiz
|
||||
self.xtosiz, self.ytosiz = xytosiz
|
||||
self.Csiz = Csiz
|
||||
self.bitdepth = bitdepth
|
||||
self.signed = signed
|
||||
self.xrsiz, self.yrsiz = xyrsiz
|
||||
|
||||
num_tiles_x = (self.xsiz - self.xosiz) / (self.xtsiz - self.xtosiz)
|
||||
num_tiles_y = (self.ysiz - self.yosiz) / (self.ytsiz - self.ytosiz)
|
||||
|
|
@ -1480,26 +1513,23 @@ class SIZsegment(Segment):
|
|||
msg = "Invalid number of tiles ({0}).".format(numtiles)
|
||||
warnings.warn(msg)
|
||||
|
||||
data = struct.unpack('>' + 'B' * len(component_buffer),
|
||||
component_buffer)
|
||||
|
||||
self.ssiz = data[0::3]
|
||||
|
||||
for j, subsampling in enumerate(list(zip(data[1::3], data[2::3]))):
|
||||
if 0 in subsampling:
|
||||
msg = "Invalid subsampling value for component {0}: "
|
||||
msg += "dx={1}, dy={2}."
|
||||
msg = msg.format(j, subsampling[0], subsampling[1])
|
||||
warnings.warn(msg)
|
||||
self.xrsiz = data[1::3]
|
||||
self.yrsiz = data[2::3]
|
||||
|
||||
self.bitdepth = tuple(((x & 0x7f) + 1) for x in self.ssiz)
|
||||
self.signed = tuple(((x & 0xb0) > 0) for x in self.ssiz)
|
||||
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.codestream.SIZsegment(rsiz={rsiz}, xysiz={xysiz}, "
|
||||
msg += "xyosiz={xyosiz}, xytsiz={xytsiz}, xytosiz={xytosiz}, "
|
||||
msg += "Csiz={Csiz}, bitdepth={bitdepth}, signed={signed}, "
|
||||
msg += "xyrsiz={xyrsiz})"
|
||||
msg = msg.format(rsiz=self.rsiz,
|
||||
xysiz=(self.xsiz, self.ysiz),
|
||||
xyosiz=(self.xosiz, self.yosiz),
|
||||
xytsiz=(self.xtsiz, self.ytsiz),
|
||||
xytosiz=(self.xtosiz, self.ytosiz),
|
||||
Csiz=self.Csiz,
|
||||
bitdepth=self.bitdepth,
|
||||
signed=self.signed,
|
||||
xyrsiz=(self.xrsiz, self.yrsiz))
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Segment.__str__(self)
|
||||
msg += '\n '
|
||||
|
|
@ -1549,6 +1579,9 @@ class SOCsegment(Segment):
|
|||
Segment.__init__(self, marker_id='SOC')
|
||||
self.__dict__.update(**kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.codestream.SOCsegment()"
|
||||
return msg
|
||||
|
||||
class SODsegment(Segment):
|
||||
"""Container for Start of Data (SOD) segment information.
|
||||
|
|
|
|||
252
glymur/jp2box.py
252
glymur/jp2box.py
|
|
@ -75,6 +75,12 @@ class Jp2kBox(object):
|
|||
self.offset = offset
|
||||
self.longname = longname
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.Jp2kBox(box_id='{0}', offset={1}, length={2}, "
|
||||
msg += "longname='{3}')"
|
||||
msg = msg.format(self.box_id, self.offset, self.length, self.longname)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = "{0} Box ({1})".format(self.longname, self.box_id)
|
||||
msg += " @ ({0}, {1})".format(self.offset, self.length)
|
||||
|
|
@ -206,6 +212,17 @@ class ColourSpecificationBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ColourSpecificationBox("
|
||||
msg += "method={0}, precedence={1}, approximation={2}, colorspace={3}, "
|
||||
msg += "icc_profile={4})"
|
||||
msg = msg.format(self.method,
|
||||
self.precedence,
|
||||
self.approximation,
|
||||
self.colorspace,
|
||||
self.icc_profile)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
||||
|
|
@ -426,12 +443,12 @@ class ChannelDefinitionBox(Jp2kBox):
|
|||
offset of the box from the start of the file.
|
||||
longname : str
|
||||
more verbose description of the box.
|
||||
index : int
|
||||
index : list
|
||||
number of the channel. Defaults to monotonically increasing sequence,
|
||||
i.e. [0, 1, 2, ...]
|
||||
channel_type : int
|
||||
channel_type : list
|
||||
type of the channel
|
||||
association : int
|
||||
association : list
|
||||
index of the associated color
|
||||
"""
|
||||
def __init__(self, index=None, channel_type=None, association=None,
|
||||
|
|
@ -458,9 +475,9 @@ class ChannelDefinitionBox(Jp2kBox):
|
|||
msg += " 65535 - unspecified"
|
||||
raise IOError(msg)
|
||||
|
||||
self.index = index
|
||||
self.channel_type = channel_type
|
||||
self.association = association
|
||||
self.index = tuple(index)
|
||||
self.channel_type = tuple(channel_type)
|
||||
self.association = tuple(association)
|
||||
self.__dict__.update(**kwargs)
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -475,6 +492,12 @@ class ChannelDefinitionBox(Jp2kBox):
|
|||
msg = msg.format(self.index[j], color_type_string, assn)
|
||||
return msg
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ChannelDefinitionBox("
|
||||
msg += "index={0}, channel_type={1}, association={2})"
|
||||
msg = msg.format(self.index, self.channel_type, self.association)
|
||||
return msg
|
||||
|
||||
def write(self, fptr):
|
||||
"""Write a channel definition box to file.
|
||||
"""
|
||||
|
|
@ -537,11 +560,15 @@ class CodestreamHeaderBox(Jp2kBox):
|
|||
box : list
|
||||
List of boxes contained in this superbox.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
def __init__(self, box=[], length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='jpch', longname='Codestream Header')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
self.box = []
|
||||
self.box = box
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.CodestreamHeaderBox(box={0})".format(self.box)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
|
@ -595,13 +622,18 @@ class CompositingLayerHeaderBox(Jp2kBox):
|
|||
box : list
|
||||
List of boxes contained in this superbox.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
def __init__(self, box=[], length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='jplh',
|
||||
longname='Compositing Layer Header')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
self.box = []
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.CompositingLayerHeaderBox(box={0})"
|
||||
msg = msg.format(self.box)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
for box in self.box:
|
||||
|
|
@ -650,11 +682,11 @@ class ComponentMappingBox(Jp2kBox):
|
|||
Offset of the box from the start of the file.
|
||||
longname : str
|
||||
Verbose description of the box.
|
||||
component_index : int
|
||||
component_index : tuple
|
||||
Index of component in codestream that is mapped to this channel.
|
||||
mapping_type : int
|
||||
mapping_type : tuple
|
||||
mapping type, either direct use (0) or palette (1)
|
||||
palette_index : int
|
||||
palette_index : tuple
|
||||
Index component from palette
|
||||
"""
|
||||
def __init__(self, component_index, mapping_type, palette_index,
|
||||
|
|
@ -666,6 +698,14 @@ class ComponentMappingBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ComponentMappingBox("
|
||||
msg += "component_index={0}, mapping_type={1}, palette_index={2})"
|
||||
msg = msg.format(self.component_index,
|
||||
self.mapping_type,
|
||||
self.palette_index)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
||||
|
|
@ -733,6 +773,10 @@ class ContiguousCodestreamBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ContiguousCodeStreamBox(main_header={0})"
|
||||
return msg.format(repr(self.main_header))
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n Main header:'
|
||||
|
|
@ -801,6 +845,13 @@ class FileTypeBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.FileTypeBox(brand='{0}', minor_version={1}, "
|
||||
msg += "compatibility_list={2})"
|
||||
msg = msg.format(self.brand, self.minor_version,
|
||||
self.compatibility_list)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
lst = [Jp2kBox.__str__(self),
|
||||
' Brand: {0}',
|
||||
|
|
@ -914,8 +965,23 @@ class ImageHeaderBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ImageHeaderBox("
|
||||
msg += "{height}, {width}, num_components={num_components}, "
|
||||
msg += "signed={signed}, bits_per_component={bits_per_component}, "
|
||||
msg += "compression={compression}, "
|
||||
msg += "colorspace_unknown={colorspace_unknown}, "
|
||||
msg += "ip_provided={ip_provided})"
|
||||
msg = msg.format(height=self.height, width=self.width,
|
||||
num_components=self.num_components,
|
||||
signed=self.signed,
|
||||
bits_per_component=self.bits_per_component,
|
||||
compression=self.compression,
|
||||
colorspace_unknown=self.colorspace_unknown,
|
||||
ip_provided=self.ip_provided)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg = "{0}"
|
||||
msg += '\n Size: [{1} {2} {3}]'
|
||||
msg += '\n Bitdepth: {4}'
|
||||
|
|
@ -1004,11 +1070,15 @@ class AssociationBox(Jp2kBox):
|
|||
box : list
|
||||
List of boxes contained in this superbox.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
def __init__(self, box=[], length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='asoc', longname='Association')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
self.box = []
|
||||
self.box = box
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.AssociationBox(box={0})".format(self.box)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
|
@ -1062,11 +1132,15 @@ class JP2HeaderBox(Jp2kBox):
|
|||
box : list
|
||||
List of boxes contained in this superbox.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
def __init__(self, box=[], length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='jp2h', longname='JP2 Header')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
self.box = []
|
||||
self.box = box
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.JP2HeaderBox(box={0})".format(self.box)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
|
@ -1141,6 +1215,9 @@ class JPEG2000SignatureBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
return 'glymur.jp2box.JPEG2000SignatureBox()'
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n Signature: {0:02x}{1:02x}{2:02x}{3:02x}'
|
||||
|
|
@ -1193,8 +1270,8 @@ class PaletteBox(Jp2kBox):
|
|||
offset of the box from the start of the file.
|
||||
longname : str
|
||||
more verbose description of the box.
|
||||
palette : list
|
||||
Colormap represented as list of 1D arrays, one per color component.
|
||||
palette : ndarray
|
||||
Colormap array.
|
||||
"""
|
||||
def __init__(self, palette, bits_per_component, signed, length=0,
|
||||
offset=-1):
|
||||
|
|
@ -1205,10 +1282,15 @@ class PaletteBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.PaletteBox({0}, bits_per_component={1}, "
|
||||
msg += "signed={2})"
|
||||
msg = msg.format(self.palette, self.bits_per_component, self.signed)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n Size: ({0} x {1})'.format(len(self.palette[0]),
|
||||
len(self.palette))
|
||||
msg += '\n Size: ({0} x {1})'.format(*self.palette.shape)
|
||||
return msg
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -1238,68 +1320,29 @@ class PaletteBox(Jp2kBox):
|
|||
bps = [((x & 0x07f) + 1) for x in data]
|
||||
signed = [((x & 0x80) > 1) for x in data]
|
||||
|
||||
fmt = '>'
|
||||
for bits in bps:
|
||||
if bits <= 8:
|
||||
fmt += 'B'
|
||||
elif bits <= 16:
|
||||
fmt += 'H'
|
||||
elif bits <= 32:
|
||||
fmt += 'I'
|
||||
|
||||
# Each palette component is padded out to the next largest byte.
|
||||
# That means a list comprehension does this in one shot.
|
||||
row_nbytes = sum([int(math.ceil(x/8.0)) for x in bps])
|
||||
|
||||
# Form the format string so that we can intelligently unpack the
|
||||
# colormap. We have to do this because it is possible that the
|
||||
# colormap columns could have different datatypes.
|
||||
#
|
||||
# This means that we store the palette as a list of 1D arrays,
|
||||
# which reverses the usual indexing scheme.
|
||||
read_buffer = fptr.read(num_entries * row_nbytes)
|
||||
palette = _buffer2palette(read_buffer, num_entries, num_columns, bps)
|
||||
palette = np.zeros((num_entries, num_columns), dtype=np.int32)
|
||||
for j in range(num_entries):
|
||||
palette[j] = struct.unpack_from(fmt, read_buffer,
|
||||
offset=j * row_nbytes)
|
||||
|
||||
box = PaletteBox(palette, bps, signed, length=length, offset=offset)
|
||||
return box
|
||||
|
||||
|
||||
def _buffer2palette(read_buffer, num_rows, num_cols, bps):
|
||||
"""Construct the palette from the buffer read from file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
read_buffer : iterable
|
||||
Byte array of palette information read from file.
|
||||
num_rows, num_cols : int
|
||||
Size of palette.
|
||||
bps : iterable
|
||||
Bits per sample for each channel.
|
||||
|
||||
Returns
|
||||
-------
|
||||
palette : list of 1D arrays
|
||||
Each 1D array corresponds to a channel.
|
||||
"""
|
||||
row_nbytes = 0
|
||||
palette = []
|
||||
fmt = '>'
|
||||
for j in range(num_cols):
|
||||
if bps[j] <= 8:
|
||||
row_nbytes += 1
|
||||
fmt += 'B'
|
||||
palette.append(np.zeros(num_rows, dtype=np.uint8))
|
||||
elif bps[j] <= 16:
|
||||
row_nbytes += 2
|
||||
fmt += 'H'
|
||||
palette.append(np.zeros(num_rows, dtype=np.uint16))
|
||||
elif bps[j] <= 32:
|
||||
row_nbytes += 4
|
||||
fmt += 'I'
|
||||
palette.append(np.zeros(num_rows, dtype=np.uint32))
|
||||
else:
|
||||
msg = 'Unsupported palette bitdepth (%d).'.format(bps[j])
|
||||
raise IOError(msg)
|
||||
|
||||
for j in range(num_rows):
|
||||
row_buffer = read_buffer[(row_nbytes * j):(row_nbytes * (j + 1))]
|
||||
row = struct.unpack(fmt, row_buffer)
|
||||
for k in range(num_cols):
|
||||
palette[k][j] = row[k]
|
||||
|
||||
return palette
|
||||
|
||||
# Map rreq codes to display text.
|
||||
_READER_REQUIREMENTS_DISPLAY = {
|
||||
0: 'File not completely understood',
|
||||
|
|
@ -1426,6 +1469,18 @@ class ReaderRequirementsBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ReaderRequirementsBox(fuam={fuam}, dcm={dcm}, "
|
||||
msg += "standard_flag={standard_flag}, standard_mask={standard_mask}, "
|
||||
msg += "vendor_feature={vendor_feature}, vendor_mask={vendor_mask})"
|
||||
msg = msg.format(fuam=self.fuam,
|
||||
dcm=self.dcm,
|
||||
standard_flag=self.standard_flag,
|
||||
standard_mask=self.standard_mask,
|
||||
vendor_feature=self.vendor_feature,
|
||||
vendor_mask=self.vendor_mask)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
||||
|
|
@ -1563,11 +1618,16 @@ class ResolutionBox(Jp2kBox):
|
|||
box : list
|
||||
List of boxes contained in this superbox.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
def __init__(self, box=[], length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='res ', longname='Resolution')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
self.box = []
|
||||
self.box = box
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.ResolutionBox(box={0})"
|
||||
msg = msg.format(self.box)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
|
@ -1629,6 +1689,11 @@ class CaptureResolutionBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.CaptureResolutionBox({0}, {1})"
|
||||
msg = msg.format(self.vertical_resolution, self.horizontal_resolution)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n VCR: {0}'.format(self.vertical_resolution)
|
||||
|
|
@ -1686,6 +1751,11 @@ class DisplayResolutionBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.DisplayResolutionBox({0}, {1})"
|
||||
msg = msg.format(self.vertical_resolution, self.horizontal_resolution)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n VDR: {0}'.format(self.vertical_resolution)
|
||||
|
|
@ -1747,6 +1817,10 @@ class LabelBox(Jp2kBox):
|
|||
msg += '\n Label: {0}'.format(self.label)
|
||||
return msg
|
||||
|
||||
def __repr__(self):
|
||||
msg = 'glymur.jp2box.LabelBox("{0}")'.format(self.label)
|
||||
return msg
|
||||
|
||||
@staticmethod
|
||||
def parse(fptr, offset, length):
|
||||
"""Parse Label box.
|
||||
|
|
@ -1808,6 +1882,9 @@ class XMLBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
return "glymur.jp2box.XMLBox(xml={0})".format(self.xml)
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
xml = self.xml
|
||||
|
|
@ -1866,7 +1943,6 @@ class XMLBox(Jp2kBox):
|
|||
msg = msg.format(offset, ude.reason)
|
||||
warnings.warn(msg, UserWarning)
|
||||
|
||||
|
||||
# Strip out any trailing nulls, as they can foul up XML parsing.
|
||||
text = text.rstrip(chr(0))
|
||||
|
||||
|
|
@ -1906,6 +1982,10 @@ class UUIDListBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.UUIDListBox({0})".format(self.ulst)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
for j, uuid_item in enumerate(self.ulst):
|
||||
|
|
@ -1957,11 +2037,15 @@ class UUIDInfoBox(Jp2kBox):
|
|||
box : list
|
||||
List of boxes contained in this superbox.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
def __init__(self, box=[], length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='uinf', longname='UUIDInfo')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
self.box = []
|
||||
self.box = box
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.UUIDInfoBox(box={0})".format(self.box)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
|
|
@ -2030,6 +2114,11 @@ class DataEntryURLBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.DataEntryURLBox({0}, {1}, '{2}')"
|
||||
msg = msg.format(self.version, self.flag, self.url)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n '
|
||||
|
|
@ -2112,6 +2201,7 @@ class UUIDBox(Jp2kBox):
|
|||
"""
|
||||
Jp2kBox.__init__(self, box_id='uuid', longname='UUID')
|
||||
self.uuid = the_uuid
|
||||
self.raw_data = raw_data
|
||||
|
||||
if the_uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
# XMP data. Parse as XML. Seems to be a difference between
|
||||
|
|
@ -2145,6 +2235,12 @@ class UUIDBox(Jp2kBox):
|
|||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.UUIDBox(the_uuid={0}, "
|
||||
msg += "raw_data=<byte array {1} elements>)"
|
||||
return msg.format(repr(self.uuid), len(self.raw_data))
|
||||
|
||||
|
||||
def __str__(self):
|
||||
msg = '{0}\n'
|
||||
msg += ' UUID: {1}{2}\n'
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ class Jp2k(Jp2kBox):
|
|||
if mode == 'rb':
|
||||
self.parse()
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.Jp2k('{0}')".format(self.filename)
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
metadata = ['File: ' + os.path.basename(self.filename)]
|
||||
if len(self.box) > 0:
|
||||
|
|
|
|||
|
|
@ -116,5 +116,49 @@ class TestCodestream(unittest.TestCase):
|
|||
# codestream, so the last one is EOC.
|
||||
self.assertEqual(codestream.segment[-1].marker_id, 'EOC')
|
||||
|
||||
|
||||
class TestCodestreamRepr(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.jp2file = glymur.data.nemo()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_soc(self):
|
||||
"""Test SOC segment repr"""
|
||||
segment = glymur.codestream.SOCsegment()
|
||||
newseg = eval(repr(segment))
|
||||
self.assertEqual(newseg.marker_id, 'SOC')
|
||||
|
||||
def test_siz(self):
|
||||
"""Test SIZ segment repr"""
|
||||
kwargs = {'rsiz': 0,
|
||||
'xysiz': (2592, 1456),
|
||||
'xyosiz': (0, 0),
|
||||
'xytsiz': (2592, 1456),
|
||||
'xytosiz': (0, 0),
|
||||
'Csiz': 3,
|
||||
'bitdepth': (8, 8, 8),
|
||||
'signed': (False, False, False),
|
||||
'xyrsiz': ((1, 1, 1), (1, 1, 1))}
|
||||
segment = glymur.codestream.SIZsegment(**kwargs)
|
||||
newseg = eval(repr(segment))
|
||||
self.assertEqual(newseg.marker_id, 'SIZ')
|
||||
self.assertEqual(newseg.xsiz, 2592)
|
||||
self.assertEqual(newseg.ysiz, 1456)
|
||||
self.assertEqual(newseg.xosiz, 0)
|
||||
self.assertEqual(newseg.yosiz, 0)
|
||||
self.assertEqual(newseg.xtsiz, 2592)
|
||||
self.assertEqual(newseg.ytsiz, 1456)
|
||||
self.assertEqual(newseg.xtosiz, 0)
|
||||
self.assertEqual(newseg.ytosiz, 0)
|
||||
|
||||
self.assertEqual(newseg.xrsiz, (1, 1, 1))
|
||||
self.assertEqual(newseg.yrsiz, (1, 1, 1))
|
||||
self.assertEqual(newseg.bitdepth, (8, 8, 8))
|
||||
self.assertEqual(newseg.signed, (False, False, False))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ Test suite specifically targeting JP2 box layout.
|
|||
|
||||
import doctest
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import struct
|
||||
import sys
|
||||
import tempfile
|
||||
import uuid
|
||||
from uuid import UUID
|
||||
import xml.etree.cElementTree as ET
|
||||
|
||||
if sys.hexversion < 0x02070000:
|
||||
|
|
@ -40,7 +42,7 @@ from glymur.jp2box import JPEG2000SignatureBox
|
|||
from glymur.core import COLOR, OPACITY
|
||||
from glymur.core import RED, GREEN, BLUE, GREY, WHOLE_IMAGE
|
||||
|
||||
from .fixtures import OPENJP2_IS_V2_OFFICIAL
|
||||
from .fixtures import OPENJP2_IS_V2_OFFICIAL, opj_data_file
|
||||
|
||||
try:
|
||||
FORMAT_CORPUS_DATA_ROOT = os.environ['FORMAT_CORPUS_DATA_ROOT']
|
||||
|
|
@ -413,7 +415,7 @@ class TestAppend(unittest.TestCase):
|
|||
|
||||
jp2 = Jp2k(tfile.name)
|
||||
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
|
||||
xmlbox = glymur.jp2box.XMLBox(xml=the_xml)
|
||||
xmlbox = glymur.jp2box.XMLBox(xml=ET.ElementTree(the_xml))
|
||||
jp2.append(xmlbox)
|
||||
|
||||
# The sequence of box IDs should be the same as before, but with an
|
||||
|
|
@ -709,6 +711,250 @@ class TestJp2Boxes(unittest.TestCase):
|
|||
self.assertIsNone(box.main_header)
|
||||
|
||||
|
||||
class TestRepr(unittest.TestCase):
|
||||
"""Tests for __repr__ methods."""
|
||||
def test_default_jp2k(self):
|
||||
"""Should be able to eval a JPEG2000SignatureBox"""
|
||||
jp2k = glymur.jp2box.JPEG2000SignatureBox()
|
||||
|
||||
# Test the representation instantiation.
|
||||
newbox = eval(repr(jp2k))
|
||||
self.assertTrue(isinstance(newbox, glymur.jp2box.JPEG2000SignatureBox))
|
||||
self.assertEqual(newbox.signature, (13, 10, 135, 10))
|
||||
|
||||
def test_default_ftyp(self):
|
||||
"""Should be able to instantiate a FileTypeBox"""
|
||||
ftyp = glymur.jp2box.FileTypeBox()
|
||||
|
||||
# Test the representation instantiation.
|
||||
newbox = eval(repr(ftyp))
|
||||
self.assertTrue(isinstance(newbox, glymur.jp2box.FileTypeBox))
|
||||
self.assertEqual(newbox.brand, 'jp2 ')
|
||||
self.assertEqual(newbox.minor_version, 0)
|
||||
self.assertEqual(newbox.compatibility_list, ['jp2 '])
|
||||
|
||||
def test_colourspecification_box(self):
|
||||
"""Verify __repr__ method on colr box."""
|
||||
# TODO: add icc_profile
|
||||
box = ColourSpecificationBox(colorspace=glymur.core.SRGB)
|
||||
|
||||
newbox = eval(repr(box))
|
||||
self.assertEqual(newbox.method, glymur.core.ENUMERATED_COLORSPACE)
|
||||
self.assertEqual(newbox.precedence, 0)
|
||||
self.assertEqual(newbox.approximation, 0)
|
||||
self.assertEqual(newbox.colorspace, glymur.core.SRGB)
|
||||
self.assertIsNone(newbox.icc_profile)
|
||||
|
||||
def test_channeldefinition_box(self):
|
||||
"""Verify __repr__ method on cdef box."""
|
||||
channel_type = [COLOR, COLOR, COLOR]
|
||||
association = [RED, GREEN, BLUE]
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=channel_type,
|
||||
association=association)
|
||||
newbox = eval(repr(cdef))
|
||||
self.assertEqual(newbox.index, (0, 1, 2))
|
||||
self.assertEqual(newbox.channel_type, (COLOR, COLOR, COLOR))
|
||||
self.assertEqual(newbox.association, (RED, GREEN, BLUE))
|
||||
|
||||
def test_jp2header_box(self):
|
||||
"""Verify __repr__ method on ihdr box."""
|
||||
ihdr = ImageHeaderBox(100, 200, num_components=3)
|
||||
colr = ColourSpecificationBox(colorspace=glymur.core.SRGB)
|
||||
jp2h = JP2HeaderBox(box=[ihdr, colr])
|
||||
newbox = eval(repr(jp2h))
|
||||
self.assertEqual(newbox.box_id, 'jp2h')
|
||||
self.assertEqual(newbox.box[0].box_id, 'ihdr')
|
||||
self.assertEqual(newbox.box[1].box_id, 'colr')
|
||||
|
||||
def test_imageheader_box(self):
|
||||
"""Verify __repr__ method on jhdr box."""
|
||||
ihdr = ImageHeaderBox(100, 200, num_components=3)
|
||||
|
||||
newbox = eval(repr(ihdr))
|
||||
self.assertEqual(newbox.height, 100)
|
||||
self.assertEqual(newbox.width, 200)
|
||||
self.assertEqual(newbox.num_components, 3)
|
||||
self.assertFalse(newbox.signed)
|
||||
self.assertEqual(newbox.bits_per_component, 8)
|
||||
self.assertEqual(newbox.compression, 7)
|
||||
self.assertFalse(newbox.colorspace_unknown)
|
||||
self.assertFalse(newbox.ip_provided)
|
||||
|
||||
def test_association_box(self):
|
||||
"""Verify __repr__ method on asoc box."""
|
||||
asoc = glymur.jp2box.AssociationBox()
|
||||
newbox = eval(repr(asoc))
|
||||
self.assertEqual(newbox.box_id, 'asoc')
|
||||
self.assertEqual(len(newbox.box), 0)
|
||||
|
||||
def test_codestreamheader_box(self):
|
||||
"""Verify __repr__ method on jpch box."""
|
||||
jpch = glymur.jp2box.CodestreamHeaderBox()
|
||||
newbox = eval(repr(jpch))
|
||||
self.assertEqual(newbox.box_id, 'jpch')
|
||||
self.assertEqual(len(newbox.box), 0)
|
||||
|
||||
def test_compositinglayerheader_box(self):
|
||||
"""Verify __repr__ method on jplh box."""
|
||||
jplh = glymur.jp2box.CompositingLayerHeaderBox()
|
||||
newbox = eval(repr(jplh))
|
||||
self.assertEqual(newbox.box_id, 'jplh')
|
||||
self.assertEqual(len(newbox.box), 0)
|
||||
|
||||
def test_componentmapping_box(self):
|
||||
"""Verify __repr__ method on cmap box."""
|
||||
cmap = glymur.jp2box.ComponentMappingBox(component_index=(0, 0, 0),
|
||||
mapping_type=(1, 1, 1),
|
||||
palette_index=(0, 1, 2))
|
||||
newbox = eval(repr(cmap))
|
||||
self.assertEqual(newbox.box_id, 'cmap')
|
||||
self.assertEqual(newbox.component_index, (0, 0, 0))
|
||||
self.assertEqual(newbox.mapping_type, (1, 1, 1))
|
||||
self.assertEqual(newbox.palette_index, (0, 1, 2))
|
||||
|
||||
def test_resolution_boxes(self):
|
||||
"""Verify __repr__ method on resolution boxes."""
|
||||
resc = glymur.jp2box.CaptureResolutionBox(0.5, 2.5)
|
||||
resd = glymur.jp2box.DisplayResolutionBox(2.5, 0.5)
|
||||
res_super_box = glymur.jp2box.ResolutionBox(box=[resc, resd])
|
||||
|
||||
newbox = eval(repr(res_super_box))
|
||||
|
||||
self.assertEqual(newbox.box_id, 'res ')
|
||||
self.assertEqual(newbox.box[0].box_id, 'resc')
|
||||
self.assertEqual(newbox.box[0].vertical_resolution, 0.5)
|
||||
self.assertEqual(newbox.box[0].horizontal_resolution, 2.5)
|
||||
self.assertEqual(newbox.box[1].box_id, 'resd')
|
||||
self.assertEqual(newbox.box[1].vertical_resolution, 2.5)
|
||||
self.assertEqual(newbox.box[1].horizontal_resolution, 0.5)
|
||||
|
||||
def test_label_box(self):
|
||||
"""Verify __repr__ method on label box."""
|
||||
lbl = glymur.jp2box.LabelBox("this is a test")
|
||||
newbox = eval(repr(lbl))
|
||||
self.assertEqual(newbox.box_id, 'lbl ')
|
||||
self.assertEqual(newbox.label, "this is a test")
|
||||
|
||||
def test_data_entry_url_box(self):
|
||||
"""Verify __repr__ method on data entry url box."""
|
||||
version = 0
|
||||
flag = (0, 0, 0)
|
||||
url = "http://readthedocs.glymur.org"
|
||||
box = glymur.jp2box.DataEntryURLBox(version, flag, url)
|
||||
newbox = eval(repr(box))
|
||||
self.assertEqual(newbox.box_id, 'url ')
|
||||
self.assertEqual(newbox.version, version)
|
||||
self.assertEqual(newbox.flag, flag)
|
||||
self.assertEqual(newbox.url, url)
|
||||
|
||||
def test_uuidinfo_box(self):
|
||||
"""Verify __repr__ method on uinf box."""
|
||||
uinf = glymur.jp2box.UUIDInfoBox()
|
||||
newbox = eval(repr(uinf))
|
||||
self.assertEqual(newbox.box_id, 'uinf')
|
||||
self.assertEqual(len(newbox.box), 0)
|
||||
|
||||
def test_uuidlist_box(self):
|
||||
"""Verify __repr__ method on ulst box."""
|
||||
uuid1 = uuid.UUID('00000000-0000-0000-0000-000000000001')
|
||||
uuid2 = uuid.UUID('00000000-0000-0000-0000-000000000002')
|
||||
uuids = [uuid1, uuid2]
|
||||
ulst = glymur.jp2box.UUIDListBox(ulst=uuids)
|
||||
newbox = eval(repr(ulst))
|
||||
self.assertEqual(newbox.box_id, 'ulst')
|
||||
self.assertEqual(newbox.ulst[0], uuid1)
|
||||
self.assertEqual(newbox.ulst[1], uuid2)
|
||||
|
||||
def test_jp2k_box(self):
|
||||
"""Verify Superclass repr."""
|
||||
box = glymur.jp2box.Jp2kBox(box_id='one', offset=2, length=3,
|
||||
longname='four')
|
||||
newbox = eval(repr(box))
|
||||
self.assertEqual(newbox.box_id, 'one')
|
||||
self.assertEqual(newbox.offset, 2)
|
||||
self.assertEqual(newbox.length, 3)
|
||||
self.assertEqual(newbox.longname, 'four')
|
||||
|
||||
def test_palette_box(self):
|
||||
"""Verify Palette box repr."""
|
||||
palette = np.array([[255, 0, 1000], [0, 255, 0]], dtype=np.int32)
|
||||
bps = (8, 8, 16)
|
||||
signed = (True, False, True)
|
||||
box = glymur.jp2box.PaletteBox(palette=palette, bits_per_component=bps,
|
||||
signed=(True, False, True))
|
||||
# The palette can't be reinstantiated thru eval/repr.
|
||||
s = repr(box)
|
||||
self.assertTrue(True)
|
||||
|
||||
@unittest.skipIf(sys.hexversion < 0x02070000, "Requires 2.7+")
|
||||
def test_xml_box(self):
|
||||
"""Verify xml box repr."""
|
||||
elt = ET.fromstring('<?xml version="1.0"?><data>0</data>')
|
||||
tree = ET.ElementTree(elt)
|
||||
box = glymur.jp2box.XMLBox(xml=tree)
|
||||
|
||||
regexp = "glymur.jp2box.XMLBox"
|
||||
regexp += "\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object "
|
||||
regexp += "at 0x([a-f0-9]*)>\)"
|
||||
|
||||
if sys.hexversion < 0x03000000:
|
||||
self.assertRegexpMatches(repr(box), regexp)
|
||||
else:
|
||||
self.assertRegex(repr(box), regexp)
|
||||
|
||||
def test_readerrequirements_box(self):
|
||||
"""Verify rreq repr method."""
|
||||
box = glymur.jp2box.ReaderRequirementsBox(fuam=160, dcm=192,
|
||||
standard_flag=(5, 61, 43),
|
||||
standard_mask=(128, 96, 64),
|
||||
vendor_feature=[],
|
||||
vendor_mask=[])
|
||||
newbox = eval(repr(box))
|
||||
self.assertEqual(box.fuam, newbox.fuam)
|
||||
self.assertEqual(box.dcm, newbox.dcm)
|
||||
self.assertEqual(box.standard_flag, newbox.standard_flag)
|
||||
self.assertEqual(box.standard_mask, newbox.standard_mask)
|
||||
self.assertEqual(box.vendor_feature, newbox.vendor_feature)
|
||||
self.assertEqual(box.vendor_mask, newbox.vendor_mask)
|
||||
|
||||
@unittest.skipIf(sys.hexversion < 0x02070000, "Requires 2.7+")
|
||||
def test_uuid_box(self):
|
||||
"""Verify uuid repr method."""
|
||||
uuid_instance = uuid.UUID('00000000-0000-0000-0000-000000000000')
|
||||
data = b'0123456789'
|
||||
box = glymur.jp2box.UUIDBox(the_uuid=uuid_instance, raw_data=data)
|
||||
|
||||
# Since the raw_data parameter is a sequence of bytes which could be
|
||||
# quite long, don't bother trying to make it conform to eval(repr()).
|
||||
regexp = "glymur.jp2box.UUIDBox\("
|
||||
regexp += "the_uuid=UUID\('00000000-0000-0000-0000-000000000000'\),\s"
|
||||
regexp += "raw_data=<byte\sarray\s10\selements>\)"
|
||||
|
||||
if sys.hexversion < 0x03000000:
|
||||
self.assertRegexpMatches(repr(box), regexp)
|
||||
else:
|
||||
self.assertRegex(repr(box), regexp)
|
||||
|
||||
@unittest.skipIf(sys.hexversion < 0x02070000, "Requires 2.7+")
|
||||
def test_contiguous_codestream_box(self):
|
||||
"""Verify contiguous codestream box repr method."""
|
||||
jp2file = glymur.data.nemo()
|
||||
jp2 = Jp2k(jp2file)
|
||||
box = jp2.box[-1]
|
||||
|
||||
# Difficult to eval(repr()) this, so just match the general pattern.
|
||||
regexp = "glymur.jp2box.ContiguousCodeStreamBox"
|
||||
regexp += "\(main_header=<glymur.codestream.Codestream\sobject\s"
|
||||
regexp += "at\s0x([a-f0-9]*)>\)"
|
||||
|
||||
if sys.hexversion < 0x03000000:
|
||||
self.assertRegexpMatches(repr(box), regexp)
|
||||
else:
|
||||
self.assertRegex(repr(box), regexp)
|
||||
|
||||
|
||||
|
||||
class TestJpxBoxes(unittest.TestCase):
|
||||
"""Tests for JPX boxes."""
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,15 @@ class TestJp2k(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_repr(self):
|
||||
"""Verify that results of __repr__ are eval-able."""
|
||||
j = Jp2k(self.j2kfile)
|
||||
newjp2 = eval(repr(j))
|
||||
|
||||
self.assertEqual(newjp2.filename, self.j2kfile)
|
||||
self.assertEqual(newjp2.mode, 'rb')
|
||||
self.assertEqual(len(newjp2.box), 0)
|
||||
|
||||
def test_rlevel_max(self):
|
||||
"""Verify that rlevel=-1 gets us the lowest resolution image"""
|
||||
j = Jp2k(self.j2kfile)
|
||||
|
|
|
|||
|
|
@ -3797,19 +3797,16 @@ class TestSuiteDump(unittest.TestCase):
|
|||
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
|
||||
|
||||
# Palette box.
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette), 3)
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette[0]), 256)
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette[1]), 256)
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette[2]), 256)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0][0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[1][0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[2][0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0][128], 73)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[1][128], 92)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[2][128], 53)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0][-1], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[1][-1], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[2][-1], 245)
|
||||
self.assertEqual(jp2.box[2].box[1].palette.shape, (256, 3))
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0, 0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0, 1], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0, 2], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[128, 0], 73)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[128, 1], 92)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[128, 2], 53)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[255, 0], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[255, 1], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[255, 2], 245)
|
||||
|
||||
# Component mapping box
|
||||
self.assertEqual(jp2.box[2].box[2].component_index, (0, 0, 0))
|
||||
|
|
@ -5699,10 +5696,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
|
||||
# Jp2 Header
|
||||
# Palette box.
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette), 3)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[0]), 256)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[1]), 256)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[2]), 256)
|
||||
self.assertEqual(jp2.box[3].box[2].palette.shape, (256, 3))
|
||||
|
||||
# Jp2 Header
|
||||
# Component mapping box
|
||||
|
|
@ -6127,11 +6121,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
|
||||
# Jp2 Header
|
||||
# Palette box.
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette), 4)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[0]), 1)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[1]), 1)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[2]), 1)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[3]), 1)
|
||||
self.assertEqual(jp2.box[3].box[2].palette.shape, (1, 4))
|
||||
|
||||
# Jp2 Header
|
||||
# Component mapping box
|
||||
|
|
@ -6242,10 +6232,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
# Jp2 Header
|
||||
# Palette box.
|
||||
# 3 columns with 16 entries.
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette), 3)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[0]), 16)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[1]), 16)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[2]), 16)
|
||||
self.assertEqual(jp2.box[3].box[2].palette.shape, (16, 3))
|
||||
|
||||
# Jp2 Header
|
||||
# Component mapping box
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue