From cc10537c14412c322496cfb22fce3538fc436c70 Mon Sep 17 00:00:00 2001 From: jevans Date: Thu, 12 Sep 2013 21:07:58 -0400 Subject: [PATCH] Using existing openjp2 handlers for now. #112 Seems a little greasy, but it works. Probably should think about a separate error handler, though. --- glymur/jp2k.py | 91 +++++++++++++++++++++++------------------- glymur/lib/openjp2.py | 2 +- glymur/lib/openjpeg.py | 3 +- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 413179b..72fc4ff 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -428,8 +428,13 @@ class Jp2k(Jp2kBox): # set encode format cinfo = opj.create_compress(cparams.codec_fmt) - event_mgr = opj.EventMgrType(None, None, None) - #opj.set_event_mgr(cparams, ctypes.byref(event_mgr), None) + event_mgr = opj.EventMgrType() + _info_handler = _INFO_CALLBACK if verbose else None + event_mgr.info_handler = _info_handler + 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.setup_encoder(cinfo, ctypes.byref(cparams), image) @@ -437,7 +442,9 @@ class Jp2k(Jp2kBox): # allocate memory for all tiles cio = opj.cio_open(cinfo) - opj.encode(cinfo, cio, image) + if not opj.encode(cinfo, cio, image): + raise IOError("Encode error.") + pos = opj.cio_tell(cio) ss = ctypes.string_at(cio.contents.buffer, pos) @@ -773,41 +780,45 @@ class Jp2k(Jp2kBox): raise IOError(msg) with ExitStack() as stack: - # Set decoding parameters. - dparameters = opj.DecompressionParametersType() - opj.set_default_decoder_parameters(ctypes.byref(dparameters)) - dparameters.cp_reduce = rlevel - dparameters.decod_format = self._codec_format + try: + # Set decoding parameters. + 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) + infile += b'0' * nelts + dparameters.infile = infile + + dinfo = opj.create_decompress(dparameters.decod_format) + + 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)) + + opj.setup_decoder(dinfo, dparameters) + + with open(self.filename, 'rb') as fptr: + src = fptr.read() + cio = opj.cio_open(dinfo, src) + + image = opj.decode(dinfo, cio) + + stack.callback(opj.image_destroy, image) + stack.callback(opj.destroy_decompress, dinfo) + stack.callback(opj.cio_close, cio) + + data = extract_image_cube(image) - 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() - 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)) - - opj.setup_decoder(dinfo, dparameters) - - with open(self.filename, 'rb') as fptr: - src = fptr.read() - cio = opj.cio_open(dinfo, src) - - image = opj.decode(dinfo, cio) - - stack.callback(opj.image_destroy, image) - stack.callback(opj.destroy_decompress, dinfo) - stack.callback(opj.cio_close, cio) - - data = extract_image_cube(image) + except ValueError: + opj2.check_error(0) if data.shape[2] == 1: # The third dimension has just a single layer. Make the image @@ -1465,18 +1476,18 @@ _CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p) def _default_error_handler(msg, _): - """Default error handler callback for openjpeg library.""" + """Default error handler callback for libopenjp2.""" msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip()) opj2.set_error_message(msg) def _default_info_handler(msg, _): - """Default info handler callback for openjpeg library.""" + """Default info handler callback.""" print("[INFO] {0}".format(msg.decode('utf-8').rstrip())) def _default_warning_handler(library_msg, _): - """Default warning handler callback for openjpeg library.""" + """Default warning handler callback.""" library_msg = library_msg.decode('utf-8').rstrip() msg = "OpenJPEG library warning: {0}".format(library_msg) warnings.warn(msg) diff --git a/glymur/lib/openjp2.py b/glymur/lib/openjp2.py index f0f72c0..8c0ae32 100644 --- a/glymur/lib/openjp2.py +++ b/glymur/lib/openjp2.py @@ -685,7 +685,7 @@ def check_error(status): raise IOError("OpenJPEG function failure.") # These library functions all return an error status. Circumvent that and -# force # them to raise an exception. +# force them to raise an exception. FCNS = ['opj_decode', 'opj_decode_tile_data', 'opj_end_compress', 'opj_encode', 'opj_end_decompress', 'opj_get_decoded_tile', 'opj_read_header', 'opj_read_tile_header', 'opj_set_decode_area', diff --git a/glymur/lib/openjpeg.py b/glymur/lib/openjpeg.py index 3ea424a..5b1183f 100644 --- a/glymur/lib/openjpeg.py +++ b/glymur/lib/openjpeg.py @@ -527,8 +527,7 @@ def encode(cinfo, cio, image): OPENJPEG.opj_encode.argtypes = argtypes OPENJPEG.opj_encode.restype = ctypes.c_int status = OPENJPEG.opj_encode(cinfo, cio, image) - if not status: - raise RuntimeError("opj_encode failed") + return status def destroy_decompress(dinfo):