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