Merge branch 'issue200' into issue212
This commit is contained in:
commit
807a0e5d3c
5 changed files with 124 additions and 38 deletions
|
|
@ -9,6 +9,7 @@ __version__ = version.version
|
||||||
from .jp2k import Jp2k
|
from .jp2k import Jp2k
|
||||||
from .jp2dump import jp2dump
|
from .jp2dump import jp2dump
|
||||||
from .jp2box import get_printoptions, set_printoptions
|
from .jp2box import get_printoptions, set_printoptions
|
||||||
|
from .jp2box import get_parseoptions, set_parseoptions
|
||||||
|
|
||||||
from . import data
|
from . import data
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1048,7 +1048,11 @@ class ContiguousCodestreamBox(Jp2kBox):
|
||||||
-------
|
-------
|
||||||
ContiguousCodestreamBox instance
|
ContiguousCodestreamBox instance
|
||||||
"""
|
"""
|
||||||
box = cls(None, length=length, offset=offset)
|
if _parseoptions['codestream'] is True:
|
||||||
|
main_header = Codestream(fptr, length, header_only=True)
|
||||||
|
else:
|
||||||
|
main_header = None
|
||||||
|
box = cls(main_header, length=length, offset=offset)
|
||||||
box._filename = fptr.name
|
box._filename = fptr.name
|
||||||
box._length = length
|
box._length = length
|
||||||
box._offset = offset
|
box._offset = offset
|
||||||
|
|
@ -3233,6 +3237,50 @@ _BOX_WITH_ID = {
|
||||||
b'uuid': UUIDBox,
|
b'uuid': UUIDBox,
|
||||||
b'xml ': XMLBox}
|
b'xml ': XMLBox}
|
||||||
|
|
||||||
|
_parseoptions = {'codestream': True}
|
||||||
|
|
||||||
|
def set_parseoptions(codestream=True):
|
||||||
|
"""Set parsing options.
|
||||||
|
|
||||||
|
These options determine the way JPEG 2000 boxes are parsed.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
codestream : bool, defaults to True
|
||||||
|
When False, the codestream header is only parsed when accessed. This
|
||||||
|
can results in faster JP2/JPX parsing.
|
||||||
|
|
||||||
|
See also
|
||||||
|
--------
|
||||||
|
get_parseoptions
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
To put back the default options, you can use:
|
||||||
|
|
||||||
|
>>> import glymur
|
||||||
|
>>> glymur.set_parseoptions(codestream=True)
|
||||||
|
"""
|
||||||
|
_parseoptions['codestream'] = codestream
|
||||||
|
|
||||||
|
def get_parseoptions():
|
||||||
|
"""Return the current parsing options.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
print_opts : dict
|
||||||
|
Dictionary of current print options with keys
|
||||||
|
|
||||||
|
- codestream : bool
|
||||||
|
|
||||||
|
For a full description of these options, see `set_parseoptions`.
|
||||||
|
|
||||||
|
See also
|
||||||
|
--------
|
||||||
|
set_parseoptions
|
||||||
|
"""
|
||||||
|
return _parseoptions
|
||||||
|
|
||||||
_printoptions = {'short': False, 'xml': True, 'codestream': True}
|
_printoptions = {'short': False, 'xml': True, 'codestream': True}
|
||||||
|
|
||||||
def set_printoptions(**kwargs):
|
def set_printoptions(**kwargs):
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class TestICC(unittest.TestCase):
|
||||||
# The file has a bad compatibility list entry. Not important here.
|
# The file has a bad compatibility list entry. Not important here.
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
j = Jp2k(filename)
|
j = Jp2k(filename)
|
||||||
profile = j.box[2].box[1].icc_profile
|
profile = j.box[3].box[1].icc_profile
|
||||||
self.assertEqual(profile['Size'], 546)
|
self.assertEqual(profile['Size'], 546)
|
||||||
self.assertEqual(profile['Preferred CMM Type'], 0)
|
self.assertEqual(profile['Preferred CMM Type'], 0)
|
||||||
self.assertEqual(profile['Version'], '2.2.0')
|
self.assertEqual(profile['Version'], '2.2.0')
|
||||||
|
|
|
||||||
|
|
@ -754,6 +754,35 @@ class TestJp2k_2_1(unittest.TestCase):
|
||||||
with self.assertRaisesRegex((IOError, OSError), regexp):
|
with self.assertRaisesRegex((IOError, OSError), regexp):
|
||||||
j.read(rlevel=1)
|
j.read(rlevel=1)
|
||||||
|
|
||||||
|
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
||||||
|
"OPJ_DATA_ROOT environment variable not set")
|
||||||
|
class TestParsing(unittest.TestCase):
|
||||||
|
"""Tests for verifying how paring may be altered."""
|
||||||
|
def setUp(self):
|
||||||
|
# Reset parseoptions for every test.
|
||||||
|
glymur.set_parseoptions(codestream=True)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_bad_rsiz(self):
|
||||||
|
"""Should not warn if RSIZ when parsing is turned off."""
|
||||||
|
# Actually there are three warning triggered by this codestream.
|
||||||
|
filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2')
|
||||||
|
glymur.set_parseoptions(codestream=False)
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
j = Jp2k(filename)
|
||||||
|
self.assertEqual(len(w), 0)
|
||||||
|
|
||||||
|
glymur.set_parseoptions(codestream=True)
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
j = Jp2k(filename)
|
||||||
|
self.assertEqual(len(w), 3)
|
||||||
|
|
||||||
|
if sys.hexversion >= 0x03000000:
|
||||||
|
with self.assertWarns(UserWarning):
|
||||||
|
jp2 = Jp2k(filename)
|
||||||
|
|
||||||
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
||||||
"OPJ_DATA_ROOT environment variable not set")
|
"OPJ_DATA_ROOT environment variable not set")
|
||||||
class TestJp2kOpjDataRoot(unittest.TestCase):
|
class TestJp2kOpjDataRoot(unittest.TestCase):
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,10 @@ class TestSuite(unittest.TestCase):
|
||||||
|
|
||||||
def test_ETS_JP2_file5(self):
|
def test_ETS_JP2_file5(self):
|
||||||
jfile = opj_data_file('input/conformance/file5.jp2')
|
jfile = opj_data_file('input/conformance/file5.jp2')
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
# There's a warning for an unknown compatibility entry.
|
||||||
|
# Ignore it here.
|
||||||
|
warnings.simplefilter("ignore")
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
jpdata = jp2k.read()
|
jpdata = jp2k.read()
|
||||||
self.assertEqual(jpdata.shape, (512, 768, 3))
|
self.assertEqual(jpdata.shape, (512, 768, 3))
|
||||||
|
|
@ -3306,40 +3310,44 @@ class TestSuiteDump(unittest.TestCase):
|
||||||
# profile and using the JPX-defined enumerated code for the ROMM-RGB
|
# profile and using the JPX-defined enumerated code for the ROMM-RGB
|
||||||
# colourspace.
|
# colourspace.
|
||||||
jfile = opj_data_file('input/conformance/file5.jp2')
|
jfile = opj_data_file('input/conformance/file5.jp2')
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
# There's a warning for an unknown compatibility entry.
|
||||||
|
# Ignore it here.
|
||||||
|
warnings.simplefilter("ignore")
|
||||||
jp2 = Jp2k(jfile)
|
jp2 = Jp2k(jfile)
|
||||||
|
|
||||||
ids = [box.box_id for box in jp2.box]
|
ids = [box.box_id for box in jp2.box]
|
||||||
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
|
self.assertEqual(ids, ['jP ', 'ftyp', 'rreq', 'jp2h', 'jp2c'])
|
||||||
|
|
||||||
ids = [box.box_id for box in jp2.box[2].box]
|
ids = [box.box_id for box in jp2.box[3].box]
|
||||||
self.assertEqual(ids, ['ihdr', 'colr'])
|
self.assertEqual(ids, ['ihdr', 'colr', 'colr'])
|
||||||
|
|
||||||
# Signature box. Check for corruption.
|
# Signature box. Check for corruption.
|
||||||
self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10))
|
self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10))
|
||||||
|
|
||||||
# File type box.
|
# File type box.
|
||||||
self.assertEqual(jp2.box[1].brand, 'jp2 ')
|
self.assertEqual(jp2.box[1].brand, 'jpx ')
|
||||||
self.assertEqual(jp2.box[1].minor_version, 0)
|
self.assertEqual(jp2.box[1].minor_version, 0)
|
||||||
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
|
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
|
||||||
|
|
||||||
# Jp2 Header
|
# Jp2 Header
|
||||||
# Image header
|
# Image header
|
||||||
self.assertEqual(jp2.box[2].box[0].height, 512)
|
self.assertEqual(jp2.box[3].box[0].height, 512)
|
||||||
self.assertEqual(jp2.box[2].box[0].width, 768)
|
self.assertEqual(jp2.box[3].box[0].width, 768)
|
||||||
self.assertEqual(jp2.box[2].box[0].num_components, 3)
|
self.assertEqual(jp2.box[3].box[0].num_components, 3)
|
||||||
self.assertEqual(jp2.box[2].box[0].signed, False)
|
self.assertEqual(jp2.box[3].box[0].signed, False)
|
||||||
self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet
|
self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet
|
||||||
self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False)
|
self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False)
|
||||||
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
|
self.assertEqual(jp2.box[3].box[0].ip_provided, False)
|
||||||
|
|
||||||
# Jp2 Header
|
# Jp2 Header
|
||||||
# Colour specification
|
# Colour specification
|
||||||
self.assertEqual(jp2.box[2].box[1].method,
|
self.assertEqual(jp2.box[3].box[1].method,
|
||||||
glymur.core.RESTRICTED_ICC_PROFILE) # enumerated
|
glymur.core.RESTRICTED_ICC_PROFILE) # enumerated
|
||||||
self.assertEqual(jp2.box[2].box[1].precedence, 0)
|
self.assertEqual(jp2.box[3].box[1].precedence, 0)
|
||||||
self.assertEqual(jp2.box[2].box[1].approximation, 1) # JPX exact
|
self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact
|
||||||
self.assertEqual(jp2.box[2].box[1].icc_profile['Size'], 546)
|
self.assertEqual(jp2.box[3].box[1].icc_profile['Size'], 546)
|
||||||
self.assertIsNone(jp2.box[2].box[1].colorspace)
|
self.assertIsNone(jp2.box[3].box[1].colorspace)
|
||||||
|
|
||||||
def test_NR_file6_dump(self):
|
def test_NR_file6_dump(self):
|
||||||
jfile = opj_data_file('input/conformance/file6.jp2')
|
jfile = opj_data_file('input/conformance/file6.jp2')
|
||||||
|
|
@ -3390,37 +3398,37 @@ class TestSuiteDump(unittest.TestCase):
|
||||||
jp2 = Jp2k(jfile)
|
jp2 = Jp2k(jfile)
|
||||||
|
|
||||||
ids = [box.box_id for box in jp2.box]
|
ids = [box.box_id for box in jp2.box]
|
||||||
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
|
self.assertEqual(ids, ['jP ', 'ftyp', 'rreq', 'jp2h', 'jp2c'])
|
||||||
|
|
||||||
ids = [box.box_id for box in jp2.box[2].box]
|
ids = [box.box_id for box in jp2.box[3].box]
|
||||||
self.assertEqual(ids, ['ihdr', 'colr'])
|
self.assertEqual(ids, ['ihdr', 'colr', 'colr'])
|
||||||
|
|
||||||
# Signature box. Check for corruption.
|
# Signature box. Check for corruption.
|
||||||
self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10))
|
self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10))
|
||||||
|
|
||||||
# File type box.
|
# File type box.
|
||||||
self.assertEqual(jp2.box[1].brand, 'jp2 ')
|
self.assertEqual(jp2.box[1].brand, 'jpx ')
|
||||||
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
|
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
|
||||||
|
|
||||||
# Jp2 Header
|
# Jp2 Header
|
||||||
# Image header
|
# Image header
|
||||||
self.assertEqual(jp2.box[2].box[0].height, 640)
|
self.assertEqual(jp2.box[3].box[0].height, 640)
|
||||||
self.assertEqual(jp2.box[2].box[0].width, 480)
|
self.assertEqual(jp2.box[3].box[0].width, 480)
|
||||||
self.assertEqual(jp2.box[2].box[0].num_components, 3)
|
self.assertEqual(jp2.box[3].box[0].num_components, 3)
|
||||||
self.assertEqual(jp2.box[2].box[0].bits_per_component, 16)
|
self.assertEqual(jp2.box[3].box[0].bits_per_component, 16)
|
||||||
self.assertEqual(jp2.box[2].box[0].signed, False)
|
self.assertEqual(jp2.box[3].box[0].signed, False)
|
||||||
self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet
|
self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet
|
||||||
self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False)
|
self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False)
|
||||||
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
|
self.assertEqual(jp2.box[3].box[0].ip_provided, False)
|
||||||
|
|
||||||
# Jp2 Header
|
# Jp2 Header
|
||||||
# Colour specification
|
# Colour specification
|
||||||
self.assertEqual(jp2.box[2].box[1].method,
|
self.assertEqual(jp2.box[3].box[1].method,
|
||||||
glymur.core.RESTRICTED_ICC_PROFILE)
|
glymur.core.RESTRICTED_ICC_PROFILE)
|
||||||
self.assertEqual(jp2.box[2].box[1].precedence, 0)
|
self.assertEqual(jp2.box[3].box[1].precedence, 0)
|
||||||
self.assertEqual(jp2.box[2].box[1].approximation, 1)
|
self.assertEqual(jp2.box[3].box[1].approximation, 1)
|
||||||
self.assertEqual(jp2.box[2].box[1].icc_profile['Size'], 13332)
|
self.assertEqual(jp2.box[3].box[1].icc_profile['Size'], 13332)
|
||||||
self.assertIsNone(jp2.box[2].box[1].colorspace)
|
self.assertIsNone(jp2.box[3].box[1].colorspace)
|
||||||
|
|
||||||
def test_NR_file8_dump(self):
|
def test_NR_file8_dump(self):
|
||||||
# One 8-bit component in a gamma 1.8 space. The colourspace is
|
# One 8-bit component in a gamma 1.8 space. The colourspace is
|
||||||
|
|
@ -3447,7 +3455,7 @@ class TestSuiteDump(unittest.TestCase):
|
||||||
# Image header
|
# Image header
|
||||||
self.assertEqual(jp2.box[2].box[0].height, 400)
|
self.assertEqual(jp2.box[2].box[0].height, 400)
|
||||||
self.assertEqual(jp2.box[2].box[0].width, 700)
|
self.assertEqual(jp2.box[2].box[0].width, 700)
|
||||||
self.assertEqual(jp2.box[2].box[0].num_components, 3)
|
self.assertEqual(jp2.box[2].box[0].num_components, 1)
|
||||||
self.assertEqual(jp2.box[2].box[0].bits_per_component, 8)
|
self.assertEqual(jp2.box[2].box[0].bits_per_component, 8)
|
||||||
self.assertEqual(jp2.box[2].box[0].signed, False)
|
self.assertEqual(jp2.box[2].box[0].signed, False)
|
||||||
self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet
|
self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue