Support for opj_version, opj_set_default_decoder_parameters.
This commit is contained in:
parent
0f0f0d5b87
commit
5a7c410288
6 changed files with 207 additions and 6 deletions
|
|
@ -186,4 +186,3 @@ _reader_requirements_display = {
|
|||
+ 'requirements in M.9.2.3',
|
||||
73: 'YPbPr(1125/60) enumerated colourspace',
|
||||
74: 'YPbPr(1250/50) enumerated colourspace'}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import numpy as np
|
|||
from .codestream import Codestream
|
||||
from .core import *
|
||||
from .jp2box import *
|
||||
from .lib import openjpeg as opj
|
||||
from .lib import openjp2 as opj2
|
||||
|
||||
_cspace_map = {'rgb': opj2._CLRSPC_SRGB,
|
||||
|
|
@ -544,16 +545,17 @@ class Jp2k(Jp2kBox):
|
|||
jp2 = Jp2k(filename)
|
||||
return jp2
|
||||
|
||||
def read(self, reduce=0, layer=0, area=None, tile=None, verbose=False):
|
||||
def read(self, **kwargs):
|
||||
"""Read a JPEG 2000 image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
layer : int, optional
|
||||
Number of quality layer to decode.
|
||||
reduce : int, optional
|
||||
Factor by which to reduce output resolution. Use -1 to get the
|
||||
lowest resolution thumbnail.
|
||||
lowest resolution thumbnail. This is the only keyword option
|
||||
available to use when only OpenJPEG version 1.5.1 is present.
|
||||
layer : int, optional
|
||||
Number of quality layer to decode.
|
||||
area : tuple, optional
|
||||
Specifies decoding image area,
|
||||
(first_row, first_col, last_row, last_col)
|
||||
|
|
@ -587,6 +589,62 @@ class Jp2k(Jp2kBox):
|
|||
>>> thumbnail.shape
|
||||
(46, 81, 3)
|
||||
"""
|
||||
if opj2._OPENJP2 is not None:
|
||||
img_array = self._read_openjp2(**kwargs)
|
||||
else:
|
||||
img_array = self._read_openjpeg(**kwargs)
|
||||
return img_array
|
||||
|
||||
def _read_openjpeg(self, reduce=0):
|
||||
"""Read a JPEG 2000 image using libopenjpeg.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
reduce : int, optional
|
||||
Factor by which to reduce output resolution. Use -1 to get the
|
||||
lowest resolution thumbnail.
|
||||
|
||||
Returns
|
||||
-------
|
||||
img_array : ndarray
|
||||
The image data.
|
||||
|
||||
Raises
|
||||
------
|
||||
IOError
|
||||
If the image has differing subsample factors.
|
||||
"""
|
||||
raise NotImplementedError("not there yet")
|
||||
|
||||
def _read_openjp2(self, reduce=0, layer=0, area=None, tile=None,
|
||||
verbose=False):
|
||||
"""Read a JPEG 2000 image using libopenjp2.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
layer : int, optional
|
||||
Number of quality layer to decode.
|
||||
reduce : int, optional
|
||||
Factor by which to reduce output resolution. Use -1 to get the
|
||||
lowest resolution thumbnail.
|
||||
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.
|
||||
|
||||
Returns
|
||||
-------
|
||||
img_array : ndarray
|
||||
The image data.
|
||||
|
||||
Raises
|
||||
------
|
||||
IOError
|
||||
If the image has differing subsample factors.
|
||||
"""
|
||||
# Check for differing subsample factors.
|
||||
codestream = self.get_codestream(header_only=True)
|
||||
dxs = np.array(codestream.segment[1].XRsiz)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
"""This package organizes individual libraries employed by glymur."""
|
||||
from . import openjp2
|
||||
from . import test
|
||||
from . import openjpeg
|
||||
#from . import test
|
||||
|
|
|
|||
58
glymur/lib/openjpeg.py
Normal file
58
glymur/lib/openjpeg.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"""Wraps library calls to openjpeg.
|
||||
"""
|
||||
|
||||
import ctypes
|
||||
from ctypes.util import find_library
|
||||
import platform
|
||||
import os
|
||||
|
||||
if os.name == "nt":
|
||||
_OPENJPEG = ctypes.windll.LoadLibrary('openjpeg')
|
||||
else:
|
||||
if platform.system() == 'Darwin':
|
||||
_OPENJPEG = ctypes.CDLL('/opt/local/lib/libopenjpeg.dylib')
|
||||
if _OPENJPEG is None:
|
||||
# Make one last attempt. Does the system know where it is?
|
||||
_OPENJPEG = find_library('openjpeg')
|
||||
|
||||
OPJ_PATH_LEN = 4096 # maximum allowed size for filenames
|
||||
|
||||
|
||||
class dparameters_t(ctypes.Structure):
|
||||
# cp_reduce: the number of highest resolution levels to be discarded
|
||||
_fields_ = [("cp_reduce", ctypes.c_int),
|
||||
# cp_layer: the maximum number of quality layers to decode
|
||||
("cp_layer", ctypes.c_int),
|
||||
# infile: input file name
|
||||
("infile", ctypes.c_char * OPJ_PATH_LEN),
|
||||
# outfile: output file name
|
||||
("outfile", ctypes.c_char * OPJ_PATH_LEN),
|
||||
# decod_format: input file format 0: J2K, 1: JP2, 2: JPT
|
||||
("decod_format", ctypes.c_int),
|
||||
# cod_format: output file format 0: PGX, 1: PxM, 2: BMP
|
||||
("cod_format", ctypes.c_int),
|
||||
# jpwl_correct: activates the JPWL correction capabilities
|
||||
("jpwl_correct", ctypes.c_bool),
|
||||
# jpwl_exp_comps: expected number of components
|
||||
("jpwl_exp_comps", ctypes.c_int),
|
||||
# jpwl_max_tiles: maximum number of tiles
|
||||
("jpwl_max_tiles", ctypes.c_int),
|
||||
# cp_limit_decoding: whether decoding should be done on the
|
||||
# entire codestream or be limited to the main header
|
||||
("cp_limit_decoding", ctypes.c_int),
|
||||
("flags", ctypes.c_uint)]
|
||||
|
||||
|
||||
def _set_default_decoder_parameters(dparams_p):
|
||||
"""Wrapper for opj_set_default_decoder_parameters.
|
||||
"""
|
||||
argtypes = [ctypes.POINTER(dparameters_t)]
|
||||
_OPENJPEG.opj_set_default_decoder_parameters.argtypes = argtypes
|
||||
_OPENJPEG.opj_set_default_decoder_parameters(dparams_p)
|
||||
|
||||
|
||||
def _version():
|
||||
"""Wrapper for opj_version library routine."""
|
||||
_OPENJPEG.opj_version.restype = ctypes.c_char_p
|
||||
v = _OPENJPEG.opj_version()
|
||||
return v.decode('utf-8')
|
||||
38
glymur/lib/test/test_openjpeg.py
Normal file
38
glymur/lib/test/test_openjpeg.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import ctypes
|
||||
import unittest
|
||||
|
||||
import glymur
|
||||
|
||||
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
|
||||
"Missing openjpeg library.")
|
||||
class TestOpenJPEG(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_version(self):
|
||||
v = glymur.lib.openjpeg._version()
|
||||
parts = v.split('.')
|
||||
self.assertEqual(parts[0], '1')
|
||||
self.assertEqual(parts[1], '5')
|
||||
|
||||
def test_set_default_decoder_parameters(self):
|
||||
# Verify that we properly set the default decode parameters.
|
||||
dp = glymur.lib.openjpeg.dparameters_t()
|
||||
glymur.lib.openjpeg._set_default_decoder_parameters(ctypes.byref(dp))
|
||||
|
||||
self.assertEqual(dp.cp_reduce, 0)
|
||||
self.assertEqual(dp.cp_layer, 0)
|
||||
self.assertEqual(dp.infile, b'')
|
||||
self.assertEqual(dp.outfile, b'')
|
||||
self.assertEqual(dp.decod_format, -1)
|
||||
self.assertEqual(dp.cod_format, -1)
|
||||
self.assertEqual(dp.jpwl_correct, 0)
|
||||
self.assertEqual(dp.jpwl_exp_comps, 0)
|
||||
self.assertEqual(dp.jpwl_max_tiles, 0)
|
||||
self.assertEqual(dp.cp_limit_decoding, 0)
|
||||
self.assertEqual(dp.flags, 0)
|
||||
|
||||
47
glymur/test/test_jp2k_15.py
Normal file
47
glymur/test/test_jp2k_15.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import os
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import glymur
|
||||
from glymur import Jp2k
|
||||
from glymur.lib import openjpeg as opj
|
||||
|
||||
try:
|
||||
data_root = os.environ['OPJ_DATA_ROOT']
|
||||
except KeyError:
|
||||
data_root = None
|
||||
except:
|
||||
raise
|
||||
|
||||
|
||||
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
|
||||
"Missing openjpeg library.")
|
||||
class TestJp2k15(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.jp2file = glymur.data.nemo()
|
||||
self.j2kfile = glymur.data.goodstuff()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_layers(self):
|
||||
# Layers not allowed for 1.5.1.
|
||||
self.assertTrue(False)
|
||||
|
||||
def test_area(self):
|
||||
# Area option not allowed for 1.5.1.
|
||||
self.assertTrue(False)
|
||||
|
||||
def test_tile(self):
|
||||
# Tile option not allowed for 1.5.1.
|
||||
self.assertTrue(False)
|
||||
|
||||
def test_verbose(self):
|
||||
# Verbose option not allowed for 1.5.1.
|
||||
self.assertTrue(False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue