This commit is contained in:
jevans 2014-11-18 20:45:25 -05:00
commit 373afb692e
2 changed files with 46 additions and 8 deletions

View file

@ -62,9 +62,15 @@ class Jp2k(Jp2kBox):
raw codestream. raw codestream.
shape : tuple shape : tuple
Size of the image. Size of the image.
Properties
----------
ignore_pclr_cmap_cdef : bool ignore_pclr_cmap_cdef : bool
Whether or not to ignore the pclr, cmap, or cdef boxes during any whether or not to ignore the pclr, cmap, or cdef boxes during any
color transformation. Defaults to False. color transformation, defaults to False.
verbose : bool
whether or not to print informational messages produced by the
OpenJPEG library, defaults to false
Examples Examples
-------- --------
@ -100,7 +106,9 @@ class Jp2k(Jp2kBox):
self._codec_format = None self._codec_format = None
self._colorspace = None self._colorspace = None
self._shape = None self._shape = None
self._ignore_pclr_cmap_cdef = False self._ignore_pclr_cmap_cdef = False
self._verbose = False
# Parse the file for JP2/JPX contents only if we are reading it. # Parse the file for JP2/JPX contents only if we are reading it.
if mode == 'rb': if mode == 'rb':
@ -114,6 +122,14 @@ class Jp2k(Jp2kBox):
def ignore_pclr_cmap_cdef(self, ignore_pclr_cmap_cdef): def ignore_pclr_cmap_cdef(self, ignore_pclr_cmap_cdef):
self._ignore_pclr_cmap_cdef = ignore_pclr_cmap_cdef self._ignore_pclr_cmap_cdef = ignore_pclr_cmap_cdef
@property
def verbose(self):
return self._verbose
@verbose.setter
def verbose(self, verbose):
self._verbose = verbose
@property @property
def shape(self): def shape(self):
if self._shape is not None: if self._shape is not None:
@ -671,7 +687,11 @@ class Jp2k(Jp2kBox):
codec = opj2.create_compress(self._cparams.codec_fmt) codec = opj2.create_compress(self._cparams.codec_fmt)
stack.callback(opj2.destroy_codec, codec) stack.callback(opj2.destroy_codec, codec)
info_handler = _INFO_CALLBACK if verbose else None if self._verbose or verbose:
info_handler = _INFO_CALLBACK
else:
info_handler = None
opj2.set_info_handler(codec, info_handler) opj2.set_info_handler(codec, info_handler)
opj2.set_warning_handler(codec, _WARNING_CALLBACK) opj2.set_warning_handler(codec, _WARNING_CALLBACK)
opj2.set_error_handler(codec, _ERROR_CALLBACK) opj2.set_error_handler(codec, _ERROR_CALLBACK)
@ -1183,7 +1203,8 @@ class Jp2k(Jp2kBox):
opj2.set_error_handler(codec, _ERROR_CALLBACK) opj2.set_error_handler(codec, _ERROR_CALLBACK)
opj2.set_warning_handler(codec, _WARNING_CALLBACK) opj2.set_warning_handler(codec, _WARNING_CALLBACK)
if verbose:
if self._verbose or verbose:
opj2.set_info_handler(codec, _INFO_CALLBACK) opj2.set_info_handler(codec, _INFO_CALLBACK)
else: else:
opj2.set_info_handler(codec, None) opj2.set_info_handler(codec, None)

View file

@ -39,7 +39,7 @@ class TestCallbacks(unittest.TestCase):
"Missing openjp2 library.") "Missing openjp2 library.")
@unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG) @unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG)
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_info_callback_on_write(self): def test_info_callback_on_write_backwards_compatibility(self):
"""Verify messages printed when writing an image in verbose mode.""" """Verify messages printed when writing an image in verbose mode."""
j = glymur.Jp2k(self.jp2file) j = glymur.Jp2k(self.jp2file)
with self.assertWarns(UserWarning): with self.assertWarns(UserWarning):
@ -52,20 +52,37 @@ class TestCallbacks(unittest.TestCase):
expected = '[INFO] tile number 1 / 1' expected = '[INFO] tile number 1 / 1'
self.assertEqual(actual, expected) self.assertEqual(actual, expected)
@unittest.skipIf(glymur.version.openjpeg_version[0] != '2',
"Missing openjp2 library.")
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_info_callback_on_write(self):
"""Verify messages printed when writing an image in verbose mode."""
j = glymur.Jp2k(self.jp2file)
tiledata = j[:]
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
jp2 = glymur.Jp2k(tfile.name, 'wb')
with patch('sys.stdout', new=StringIO()) as fake_out:
jp2.verbose = True
jp2[:] = tiledata
actual = fake_out.getvalue().strip()
expected = '[INFO] tile number 1 / 1'
self.assertEqual(actual, expected)
def test_info_callbacks_on_read(self): def test_info_callbacks_on_read(self):
"""stdio output when info callback handler is enabled""" """stdio output when info callback handler is enabled"""
# Verify that we get the expected stdio output when our internal info # Verify that we get the expected stdio output when our internal info
# callback handler is enabled. # callback handler is enabled.
j = glymur.Jp2k(self.j2kfile) jp2 = glymur.Jp2k(self.j2kfile)
with patch('sys.stdout', new=StringIO()) as fake_out: with patch('sys.stdout', new=StringIO()) as fake_out:
j.read(rlevel=1, verbose=True) jp2.verbose = True
jp2[::2, ::2]
actual = fake_out.getvalue().strip() actual = fake_out.getvalue().strip()
if glymur.version.openjpeg_version[0] == '2': if glymur.version.openjpeg_version[0] == '2':
lines = ['[INFO] Start to read j2k main header (0).', lines = ['[INFO] Start to read j2k main header (0).',
'[INFO] Main header has been correctly decoded.', '[INFO] Main header has been correctly decoded.',
'[INFO] No decoded area parameters, set the decoded area to the whole image', '[INFO] Setting decoding area to 0,0,480,800',
'[INFO] Header of tile 0 / 0 has been read.', '[INFO] Header of tile 0 / 0 has been read.',
'[INFO] Tile 1/1 has been decoded.', '[INFO] Tile 1/1 has been decoded.',
'[INFO] Image data has been updated with tile 1.'] '[INFO] Image data has been updated with tile 1.']