Hooked up openjpeg event handlers. #67

This commit is contained in:
John Evans 2013-07-06 07:21:02 -04:00
commit 39e2859a66
4 changed files with 85 additions and 5 deletions

View file

@ -595,7 +595,7 @@ class Jp2k(Jp2kBox):
img = self._read_openjpeg(**kwargs)
return img
def _read_openjpeg(self, reduce=0):
def _read_openjpeg(self, reduce=0, verbose=False):
"""Read a JPEG 2000 image using libopenjpeg.
Parameters
@ -603,6 +603,8 @@ class Jp2k(Jp2kBox):
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
lowest resolution thumbnail.
verbose : bool, optional
Print informational messages produced by the OpenJPEG library.
Returns
-------
@ -629,6 +631,15 @@ class Jp2k(Jp2kBox):
dinfo = opj._create_decompress(dparameters.decod_format)
event_mgr = opj.event_mgr_t()
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 fp:

View file

@ -166,6 +166,16 @@ def _set_default_decoder_parameters(dparams_p):
_OPENJPEG.opj_set_default_decoder_parameters(dparams_p)
def _set_event_mgr(dinfo, event_mgr, context=None):
"""Wrapper for openjpeg library function opj_set_event_mgr.
"""
argtypes = [ctypes.POINTER(common_struct_t),
ctypes.POINTER(event_mgr_t),
ctypes.c_void_p]
_OPENJPEG.opj_set_event_mgr(ctypes.cast(dinfo,
ctypes.POINTER(common_struct_t)),
event_mgr, context)
def _setup_decoder(dinfo, dparams):
"""Wrapper for openjpeg library function opj_setup_decoder."""
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(dparameters_t)]

View file

@ -59,5 +59,50 @@ class TestCallbacks(unittest.TestCase):
self.assertEqual(actual, expected)
@unittest.skipIf(glymur.lib.openjp2._OPENJPEG is None,
"Missing openjpeg library.")
class TestCallbacks15(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
cls.openjp2 = glymur.lib.openjp2._OPENJP2
glymur.lib.openjp2._OPENJP2 = None
@classmethod
def tearDownClass(cls):
# Restore OPENJP2
glymur.lib.openjp2._OPENJP2 = cls.openjp2
def setUp(self):
# Save sys.stdout.
self.stdout = sys.stdout
sys.stdout = StringIO()
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
# Restore stdout.
sys.stdout = self.stdout
def test_info_callbacks_on_read(self):
# Verify that we get the expected stdio output when our internal info
# callback handler is enabled.
j = glymur.Jp2k(self.j2kfile)
d = j.read(reduce=1, verbose=True)
actual = sys.stdout.getvalue().strip()
# We can't actually match this because the times will be different.
lines = ['[INFO] tile 1 of 1',
'[INFO] - tiers-1 took 0.050149 s',
'[INFO] - dwt took 0.004188 s',
'[INFO] - tile decoded in 0.058203 s']
expected = '\n'.join(lines)
self.assertTrue('[INFO]' in actual)
self.assertTrue('dwt took' in actual)
if __name__ == "__main__":
unittest.main()

View file

@ -35,6 +35,7 @@ class TestJp2k(unittest.TestCase):
glymur.lib.openjp2._OPENJP2 = cls.openjp2
def setUp(self):
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
@ -64,10 +65,17 @@ class TestJp2k(unittest.TestCase):
with self.assertRaises(TypeError) as ce:
d = j2k.read(layer=1)
def test_basic(self):
def test_basic_jp2(self):
# This test is only useful when openjp2 is not available
# and OPJ_DATA_ROOT is not set. We need at least one
# working read test.
# working JP2 test.
j2k = Jp2k(self.jp2file)
d = j2k.read(reduce=1)
def test_basic_j2k(self):
# This test is only useful when openjp2 is not available
# and OPJ_DATA_ROOT is not set. We need at least one
# working J2K test.
j2k = Jp2k(self.j2kfile)
d = j2k.read()
@ -309,7 +317,10 @@ class TestSuite(unittest.TestCase):
def test_ETS_C1P0_p0_10_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_10.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_10_0.pgx')
pgxdata = read_pgx(pgxfile)
@ -695,7 +706,10 @@ class TestSuite(unittest.TestCase):
def test_NR_DEC_kakadu_v4_4_openjpegv2_broken_j2k_16_decode(self):
relpath = 'input/nonregression/kakadu_v4-4_openjpegv2_broken.j2k'
jfile = os.path.join(data_root, relpath)
data = Jp2k(jfile).read()
with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_MarkerIsNotCompliant_j2k_17_decode(self):