Refactored out read_common, remove ambiguity on return type.
It was the case that _read_common could return either a list, a view, or an image cube depending upon the jp2 subsampling or the image dimensions. No more. Closed #100
This commit is contained in:
parent
f55963db81
commit
4db8763056
1 changed files with 81 additions and 75 deletions
156
glymur/jp2k.py
156
glymur/jp2k.py
|
|
@ -686,12 +686,12 @@ class Jp2k(Jp2kBox):
|
||||||
if data.shape[2] == 1:
|
if data.shape[2] == 1:
|
||||||
# The third dimension has just a single layer. Make the image
|
# The third dimension has just a single layer. Make the image
|
||||||
# data 2D instead of 3D.
|
# data 2D instead of 3D.
|
||||||
data = data.view()
|
|
||||||
data.shape = data.shape[0:2]
|
data.shape = data.shape[0:2]
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _read_openjp2(self, **kwargs):
|
def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None,
|
||||||
|
verbose=False):
|
||||||
"""Read a JPEG 2000 image using libopenjp2.
|
"""Read a JPEG 2000 image using libopenjp2.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -721,10 +721,46 @@ class Jp2k(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
self._subsampling_sanity_check()
|
self._subsampling_sanity_check()
|
||||||
|
|
||||||
img_array = self._read_common(as_bands=False, **kwargs)
|
dparam = self._populate_dparam(layer, rlevel, area, tile)
|
||||||
|
|
||||||
|
with ExitStack() as stack:
|
||||||
|
if hasattr(opj2.OPENJP2,
|
||||||
|
'opj_stream_create_default_file_stream_v3'):
|
||||||
|
filename = self.filename
|
||||||
|
stream = opj2.stream_create_default_file_stream_v3(filename,
|
||||||
|
True)
|
||||||
|
stack.callback(opj2.stream_destroy_v3, stream)
|
||||||
|
else:
|
||||||
|
fptr = libc.fopen(self.filename, 'rb')
|
||||||
|
stack.callback(libc.fclose, fptr)
|
||||||
|
stream = opj2.stream_create_default_file_stream(fptr, True)
|
||||||
|
stack.callback(opj2.stream_destroy, 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)
|
||||||
|
if verbose:
|
||||||
|
opj2.set_info_handler(codec, _INFO_CALLBACK)
|
||||||
|
else:
|
||||||
|
opj2.set_info_handler(codec, None)
|
||||||
|
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
|
||||||
|
img_array = extract_image_cube(image)
|
||||||
|
|
||||||
if img_array.shape[2] == 1:
|
if img_array.shape[2] == 1:
|
||||||
img_array = img_array.view()
|
|
||||||
img_array.shape = img_array.shape[0:2]
|
img_array.shape = img_array.shape[0:2]
|
||||||
|
|
||||||
return img_array
|
return img_array
|
||||||
|
|
@ -782,76 +818,8 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
return dparam
|
return dparam
|
||||||
|
|
||||||
def _read_common(self, rlevel=0, layer=0, area=None, tile=None,
|
def read_bands(self, rlevel=0, layer=0, area=None, tile=None,
|
||||||
verbose=False, as_bands=False):
|
verbose=False):
|
||||||
"""Read a JPEG 2000 image.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
layer : int, optional
|
|
||||||
Number of quality layer to decode.
|
|
||||||
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)
|
|
||||||
tile : int, optional
|
|
||||||
Number of tile to decode.
|
|
||||||
verbose : bool, optional
|
|
||||||
Print informational messages produced by the OpenJPEG library.
|
|
||||||
as_bands : bool, optional
|
|
||||||
If true, return the individual 2D components in a list.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
img_array : ndarray
|
|
||||||
The individual image components or a single array.
|
|
||||||
"""
|
|
||||||
dparam = self._populate_dparam(layer, rlevel, area, tile)
|
|
||||||
|
|
||||||
with ExitStack() as stack:
|
|
||||||
if hasattr(opj2.OPENJP2,
|
|
||||||
'opj_stream_create_default_file_stream_v3'):
|
|
||||||
filename = self.filename
|
|
||||||
stream = opj2.stream_create_default_file_stream_v3(filename,
|
|
||||||
True)
|
|
||||||
stack.callback(opj2.stream_destroy_v3, stream)
|
|
||||||
else:
|
|
||||||
fptr = libc.fopen(self.filename, 'rb')
|
|
||||||
stack.callback(libc.fclose, fptr)
|
|
||||||
stream = opj2.stream_create_default_file_stream(fptr, True)
|
|
||||||
stack.callback(opj2.stream_destroy, 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)
|
|
||||||
if verbose:
|
|
||||||
opj2.set_info_handler(codec, _INFO_CALLBACK)
|
|
||||||
else:
|
|
||||||
opj2.set_info_handler(codec, None)
|
|
||||||
|
|
||||||
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)
|
|
||||||
else:
|
|
||||||
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)
|
|
||||||
|
|
||||||
if as_bands:
|
|
||||||
data = extract_image_bands(image)
|
|
||||||
else:
|
|
||||||
data = extract_image_cube(image)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def read_bands(self, **kwargs):
|
|
||||||
"""Read a JPEG 2000 image.
|
"""Read a JPEG 2000 image.
|
||||||
|
|
||||||
The only time you should use this method is when the image has
|
The only time you should use this method is when the image has
|
||||||
|
|
@ -898,7 +866,45 @@ class Jp2k(Jp2kBox):
|
||||||
"of OpenJP2 installed before using "
|
"of OpenJP2 installed before using "
|
||||||
"this functionality.")
|
"this functionality.")
|
||||||
|
|
||||||
lst = self._read_common(as_bands=True, **kwargs)
|
dparam = self._populate_dparam(layer, rlevel, area, tile)
|
||||||
|
|
||||||
|
with ExitStack() as stack:
|
||||||
|
if hasattr(opj2.OPENJP2,
|
||||||
|
'opj_stream_create_default_file_stream_v3'):
|
||||||
|
filename = self.filename
|
||||||
|
stream = opj2.stream_create_default_file_stream_v3(filename,
|
||||||
|
True)
|
||||||
|
stack.callback(opj2.stream_destroy_v3, stream)
|
||||||
|
else:
|
||||||
|
fptr = libc.fopen(self.filename, 'rb')
|
||||||
|
stack.callback(libc.fclose, fptr)
|
||||||
|
stream = opj2.stream_create_default_file_stream(fptr, True)
|
||||||
|
stack.callback(opj2.stream_destroy, 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)
|
||||||
|
if verbose:
|
||||||
|
opj2.set_info_handler(codec, _INFO_CALLBACK)
|
||||||
|
else:
|
||||||
|
opj2.set_info_handler(codec, None)
|
||||||
|
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
|
||||||
|
lst = extract_image_bands(image)
|
||||||
|
|
||||||
return lst
|
return lst
|
||||||
|
|
||||||
def get_codestream(self, header_only=True):
|
def get_codestream(self, header_only=True):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue