Refactoring, lint cleanup.
This commit is contained in:
parent
eb6f5c87a9
commit
0e370f5882
2 changed files with 62 additions and 66 deletions
|
|
@ -43,7 +43,7 @@ _METHOD_DISPLAY = {
|
|||
ANY_ICC_PROFILE: 'any ICC profile',
|
||||
VENDOR_COLOR_METHOD: 'vendor color method'}
|
||||
|
||||
_factory = lambda x: '{0} (invalid)'.format(x)
|
||||
_factory = lambda x: '{0} (invalid)'.format(x)
|
||||
_APPROX_DISPLAY = _Keydefaultdict(_factory,
|
||||
{1: 'accurately represents correct colorspace definition',
|
||||
2: 'approximates correct colorspace definition, exceptional quality',
|
||||
|
|
@ -125,7 +125,7 @@ class Jp2kBox(object):
|
|||
String to be indented.
|
||||
indent_level : str
|
||||
Number of spaces of indentation to add.
|
||||
|
||||
|
||||
Returns
|
||||
-------
|
||||
indented_string : str
|
||||
|
|
@ -407,15 +407,16 @@ class ColourSpecificationBox(Jp2kBox):
|
|||
-------
|
||||
ColourSpecificationBox instance
|
||||
"""
|
||||
num_bytes = offset + length - fptr.tell()
|
||||
read_buffer = fptr.read(num_bytes)
|
||||
# Read the brand, minor version.
|
||||
read_buffer = fptr.read(3)
|
||||
(method, precedence, approximation) = struct.unpack('>BBB',
|
||||
read_buffer)
|
||||
(method, precedence, approximation) = struct.unpack_from('>BBB',
|
||||
read_buffer,
|
||||
offset=0)
|
||||
|
||||
if method == 1:
|
||||
# enumerated colour space
|
||||
read_buffer = fptr.read(4)
|
||||
colorspace, = struct.unpack('>I', read_buffer)
|
||||
colorspace, = struct.unpack_from('>I', read_buffer, offset=3)
|
||||
if colorspace not in _COLORSPACE_MAP_DISPLAY.keys():
|
||||
msg = "Unrecognized colorspace: {0}".format(colorspace)
|
||||
warnings.warn(msg)
|
||||
|
|
@ -424,14 +425,13 @@ class ColourSpecificationBox(Jp2kBox):
|
|||
else:
|
||||
# ICC profile
|
||||
colorspace = None
|
||||
numbytes = offset + length - fptr.tell()
|
||||
if numbytes < 128:
|
||||
if (num_bytes - 3) < 128:
|
||||
msg = "ICC profile header is corrupt, length is "
|
||||
msg += "only {0} instead of 128."
|
||||
warnings.warn(msg.format(numbytes), UserWarning)
|
||||
warnings.warn(msg.format(num_bytes - 3), UserWarning)
|
||||
icc_profile = None
|
||||
else:
|
||||
profile = _ICCProfile(fptr.read(numbytes))
|
||||
profile = _ICCProfile(read_buffer[3:])
|
||||
icc_profile = profile.header
|
||||
|
||||
return cls(method=method,
|
||||
|
|
@ -659,12 +659,14 @@ class ChannelDefinitionBox(Jp2kBox):
|
|||
-------
|
||||
ComponentDefinitionBox instance
|
||||
"""
|
||||
# Read the number of components.
|
||||
read_buffer = fptr.read(2)
|
||||
num_components, = struct.unpack('>H', read_buffer)
|
||||
num_bytes = offset + length - fptr.tell()
|
||||
read_buffer = fptr.read(num_bytes)
|
||||
|
||||
read_buffer = fptr.read(num_components * 6)
|
||||
data = struct.unpack('>' + 'HHH' * num_components, read_buffer)
|
||||
# Read the number of components.
|
||||
num_components, = struct.unpack_from('>H', read_buffer)
|
||||
|
||||
data = struct.unpack_from('>' + 'HHH' * num_components, read_buffer,
|
||||
offset=2)
|
||||
index = data[0:num_components * 6:3]
|
||||
channel_type = data[1:num_components * 6:3]
|
||||
association = data[2:num_components * 6:3]
|
||||
|
|
@ -1234,19 +1236,21 @@ class FileTypeBox(Jp2kBox):
|
|||
-------
|
||||
FileTypeBox instance
|
||||
"""
|
||||
current_pos = fptr.tell()
|
||||
num_bytes = (offset + length - current_pos)
|
||||
read_buffer = fptr.read(num_bytes)
|
||||
|
||||
# Read the brand, minor version.
|
||||
read_buffer = fptr.read(8)
|
||||
(brand, minor_version) = struct.unpack('>4sI', read_buffer)
|
||||
(brand, minor_version) = struct.unpack_from('>4sI', read_buffer,
|
||||
offset=0)
|
||||
if sys.hexversion >= 0x030000:
|
||||
brand = brand.decode('utf-8')
|
||||
|
||||
# Read the compatibility list. Each entry has 4 bytes.
|
||||
current_pos = fptr.tell()
|
||||
num_bytes = (offset + length - current_pos) / 4
|
||||
read_buffer = fptr.read(int(num_bytes) * 4)
|
||||
compatibility_list = []
|
||||
for j in range(int(num_bytes)):
|
||||
entry, = struct.unpack('>4s', read_buffer[4*j:4*(j+1)])
|
||||
num_entries = int((offset + length - current_pos - 8) / 4)
|
||||
for j in range(num_entries):
|
||||
entry, = struct.unpack_from('>4s', read_buffer, offset=8 + (4 * j))
|
||||
if sys.hexversion >= 0x03000000:
|
||||
entry = entry.decode('utf-8')
|
||||
compatibility_list.append(entry)
|
||||
|
|
@ -1942,7 +1946,7 @@ class PaletteBox(Jp2kBox):
|
|||
elif bps[0] <= 32:
|
||||
nbytes_per_row = 3 * num_columns
|
||||
dtype = np.uint32
|
||||
|
||||
|
||||
read_buffer = fptr.read(num_entries * nbytes_per_row)
|
||||
palette = np.frombuffer(read_buffer, dtype=dtype)
|
||||
palette = np.reshape(palette, (num_entries, num_columns))
|
||||
|
|
@ -2828,13 +2832,15 @@ class UUIDListBox(Jp2kBox):
|
|||
-------
|
||||
UUIDListBox instance
|
||||
"""
|
||||
read_buffer = fptr.read(2)
|
||||
num_uuids, = struct.unpack('>H', read_buffer)
|
||||
num_bytes = offset + length - fptr.tell()
|
||||
read_buffer = fptr.read(num_bytes)
|
||||
|
||||
num_uuids, = struct.unpack_from('>H', read_buffer)
|
||||
|
||||
ulst = []
|
||||
for _ in range(num_uuids):
|
||||
read_buffer = fptr.read(16)
|
||||
ulst.append(uuid.UUID(bytes=read_buffer))
|
||||
for j in range(num_uuids):
|
||||
uuid_buffer = read_buffer[2 + j * 16 : 2 + (j + 1) * 16]
|
||||
ulst.append(uuid.UUID(bytes=uuid_buffer))
|
||||
|
||||
return cls(ulst, length=length, offset=offset)
|
||||
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ class Jp2k(Jp2kBox):
|
|||
msg = "Unable to locate the specified codestream."
|
||||
raise IOError(msg)
|
||||
if L == 0:
|
||||
# The length of the box is presumed to last until the end of
|
||||
# The length of the box is presumed to last until the end of
|
||||
# the file. Compute the effective length of the box.
|
||||
L = os.path.getsize(ifile.name) - ifile.tell() + 8
|
||||
|
||||
|
|
@ -833,38 +833,13 @@ class Jp2k(Jp2kBox):
|
|||
"""
|
||||
self._subsampling_sanity_check()
|
||||
|
||||
# Must check the specified rlevel against the maximum.
|
||||
if rlevel != 0:
|
||||
# Must check the specified rlevel against the maximum.
|
||||
codestream = self.get_codestream()
|
||||
max_rlevel = codestream.segment[2].spcod[4]
|
||||
if rlevel == -1:
|
||||
# -1 is shorthand for the largest rlevel
|
||||
rlevel = max_rlevel
|
||||
elif rlevel < -1 or rlevel > max_rlevel:
|
||||
msg = "rlevel must be in the range [-1, {0}] for this image."
|
||||
msg = msg.format(max_rlevel)
|
||||
raise IOError(msg)
|
||||
dparameters = self._populate_dparam(rlevel, ignore_pclr_cmap_cdef)
|
||||
|
||||
with ExitStack() as stack:
|
||||
try:
|
||||
# Set decoding parameters.
|
||||
# TODO: look to refactor, use _populate_dparam
|
||||
dparameters = opj.DecompressionParametersType()
|
||||
opj.set_default_decoder_parameters(ctypes.byref(dparameters))
|
||||
|
||||
if ignore_pclr_cmap_cdef is True:
|
||||
# Return raw codestream components.
|
||||
dparameters.flags |= 1
|
||||
|
||||
dparameters.cp_reduce = rlevel
|
||||
dparameters.decod_format = self._codec_format
|
||||
|
||||
infile = self.filename.encode()
|
||||
nelts = opj.PATH_LEN - len(infile)
|
||||
infile += b'0' * nelts
|
||||
dparameters.infile = infile
|
||||
|
||||
dinfo = opj.create_decompress(dparameters.decod_format)
|
||||
|
||||
event_mgr = opj.EventMgrType()
|
||||
|
|
@ -931,8 +906,8 @@ class Jp2k(Jp2kBox):
|
|||
"""
|
||||
self._subsampling_sanity_check()
|
||||
|
||||
dparam = self._populate_dparam(layer, rlevel, area, tile,
|
||||
ignore_pclr_cmap_cdef)
|
||||
dparam = self._populate_dparam(rlevel, ignore_pclr_cmap_cdef,
|
||||
layer=layer, tile=tile, area=area)
|
||||
|
||||
with ExitStack() as stack:
|
||||
if hasattr(opj2.OPENJP2,
|
||||
|
|
@ -976,8 +951,8 @@ class Jp2k(Jp2kBox):
|
|||
|
||||
return img_array
|
||||
|
||||
def _populate_dparam(self, layer, rlevel, area, tile,
|
||||
ignore_pclr_cmap_cdef):
|
||||
def _populate_dparam(self, rlevel, ignore_pclr_cmap_cdef, tile=None,
|
||||
layer=None, area=None):
|
||||
"""Populate decompression structure with appropriate input parameters.
|
||||
|
||||
Parameters
|
||||
|
|
@ -1000,7 +975,11 @@ class Jp2k(Jp2kBox):
|
|||
dparam : DecompressionParametersType (ctypes)
|
||||
Corresponds to openjp2 decompression parameters structure.
|
||||
"""
|
||||
dparam = opj2.set_default_decoder_parameters()
|
||||
if opj2.OPENJP2 is not None:
|
||||
dparam = opj2.set_default_decoder_parameters()
|
||||
else:
|
||||
dparam = opj.DecompressionParametersType()
|
||||
opj.set_default_decoder_parameters(ctypes.byref(dparam))
|
||||
|
||||
infile = self.filename.encode()
|
||||
nelts = opj2.PATH_LEN - len(infile)
|
||||
|
|
@ -1009,12 +988,22 @@ class Jp2k(Jp2kBox):
|
|||
|
||||
dparam.decod_format = self._codec_format
|
||||
|
||||
dparam.cp_layer = layer
|
||||
if layer is not None:
|
||||
dparam.cp_layer = layer
|
||||
|
||||
if rlevel == -1:
|
||||
# Get the lowest resolution thumbnail.
|
||||
# Must check the specified rlevel against the maximum.
|
||||
if rlevel != 0:
|
||||
# Must check the specified rlevel against the maximum.
|
||||
codestream = self.get_codestream()
|
||||
rlevel = codestream.segment[2].spcod[4]
|
||||
max_rlevel = codestream.segment[2].spcod[4]
|
||||
if rlevel == -1:
|
||||
# -1 is shorthand for the largest rlevel
|
||||
rlevel = max_rlevel
|
||||
elif rlevel < -1 or rlevel > max_rlevel:
|
||||
msg = "rlevel must be in the range [-1, {0}] for this image."
|
||||
msg = msg.format(max_rlevel)
|
||||
raise IOError(msg)
|
||||
|
||||
dparam.cp_reduce = rlevel
|
||||
|
||||
if area is not None:
|
||||
|
|
@ -1088,7 +1077,8 @@ class Jp2k(Jp2kBox):
|
|||
"of OpenJP2 installed before using "
|
||||
"this functionality.")
|
||||
|
||||
dparam = self._populate_dparam(layer, rlevel, area, tile, ignore_pclr_cmap_cdef)
|
||||
dparam = self._populate_dparam(rlevel, ignore_pclr_cmap_cdef,
|
||||
layer=layer, tile=tile, area=area)
|
||||
|
||||
with ExitStack() as stack:
|
||||
if hasattr(opj2.OPENJP2,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue