replaced main_header codestream attribute with codestream

changed "codestream" parameter of set_parseoptions to "full_codestream"
This commit is contained in:
John Evans 2015-01-06 16:35:38 -05:00
commit a24bff0af1
4 changed files with 40 additions and 59 deletions

View file

@ -5,7 +5,7 @@ import argparse
import os import os
import warnings import warnings
from . import Jp2k, set_printoptions, lib from . import Jp2k, set_printoptions, set_parseoptions, lib
def main(): def main():
@ -47,11 +47,8 @@ def main():
if codestream_level == 0: if codestream_level == 0:
set_printoptions(codestream=False) set_printoptions(codestream=False)
print_full_codestream = False elif codestream_level == 2:
elif codestream_level == 1: set_parseoptions(full_codestream=True)
print_full_codestream = False
else:
print_full_codestream = True
filename = args.filename filename = args.filename
@ -68,11 +65,6 @@ def main():
elif codestream_level == 2: elif codestream_level == 2:
print('File: {0}'.format(os.path.basename(filename))) print('File: {0}'.format(os.path.basename(filename)))
print(jp2.get_codestream(header_only=False)) print(jp2.get_codestream(header_only=False))
elif print_full_codestream:
for box in jp2.box:
if box.box_id == 'jp2c':
box._get_codestream(header_only=False)
print(jp2)
else: else:
print(jp2) print(jp2)

View file

@ -1023,13 +1023,17 @@ class ContiguousCodestreamBox(Jp2kBox):
@property @property
def codestream(self): def codestream(self):
if _parseoptions['full_codestream'] is True:
header_only = False
else:
header_only = True
if self._codestream is None: if self._codestream is None:
if self._filename is not None: if self._filename is not None:
with open(self._filename, 'rb') as fptr: with open(self._filename, 'rb') as fptr:
fptr.seek(self.main_header_offset) fptr.seek(self.main_header_offset)
codestream = Codestream(fptr, codestream = Codestream(fptr,
self._length, self._length,
header_only=True) header_only=header_only)
self._codestream = codestream self._codestream = codestream
return self._codestream return self._codestream
@ -1067,40 +1071,16 @@ class ContiguousCodestreamBox(Jp2kBox):
ContiguousCodestreamBox instance ContiguousCodestreamBox instance
""" """
main_header_offset = fptr.tell() main_header_offset = fptr.tell()
if _parseoptions['codestream'] is True: if _parseoptions['full_codestream'] is True:
main_header = Codestream(fptr, length, header_only=True) codestream = Codestream(fptr, length, header_only=False)
else: else:
main_header = None codestream = None
box = cls(main_header, main_header_offset=main_header_offset, box = cls(codestream, main_header_offset=main_header_offset,
length=length, offset=offset) length=length, offset=offset)
box._filename = fptr.name box._filename = fptr.name
box._length = length box._length = length
return box return box
def _get_codestream(self, header_only=True):
"""retrieve codestream
Parameters
----------
header_only : bool, optional
If True, only marker segments in the main header are parsed.
Supplying False may impose a large performance penalty.
"""
with open(self.filename, 'rb') as fptr:
fptr.seek(self.offset)
read_buffer = fptr.read(8)
(box_length, _) = struct.unpack('>I4s', read_buffer)
if box_length == 0:
# The length of the box is presumed to last until the end
# of the file. Compute the effective length of the box.
box_length = os.path.getsize(fptr.name) - fptr.tell() + 8
elif box_length == 1:
# Seek past the XL field.
read_buffer = fptr.read(8)
box_length, = struct.unpack('>Q', read_buffer)
self._codestream = Codestream(fptr, box_length - 8,
header_only=header_only)
class DataReferenceBox(Jp2kBox): class DataReferenceBox(Jp2kBox):
"""Container for Data Reference box information. """Container for Data Reference box information.
@ -3338,19 +3318,20 @@ _BOX_WITH_ID = {
b'uuid': UUIDBox, b'uuid': UUIDBox,
b'xml ': XMLBox} b'xml ': XMLBox}
_parseoptions = {'codestream': True} _parseoptions = {'full_codestream': False}
def set_parseoptions(codestream=True): def set_parseoptions(full_codestream=True):
"""Set parsing options. """Set parsing options.
These options determine the way JPEG 2000 boxes are parsed. These options determine the way JPEG 2000 boxes are parsed.
Parameters Parameters
---------- ----------
codestream : bool, defaults to True full_codestream : bool, defaults to True
When False, the codestream header is only parsed when accessed. This When False, only the codestream header is parsed for metadata. This
can results in faster JP2/JPX parsing. can results in faster JP2/JPX parsing. When True, the entire
codestream is parsed for metadata.
See also See also
-------- --------
@ -3361,9 +3342,9 @@ def set_parseoptions(codestream=True):
To put back the default options, you can use: To put back the default options, you can use:
>>> import glymur >>> import glymur
>>> glymur.set_parseoptions(codestream=True) >>> glymur.set_parseoptions(full_codestream=True)
""" """
_parseoptions['codestream'] = codestream _parseoptions['full_codestream'] = full_codestream
def get_parseoptions(): def get_parseoptions():
@ -3401,10 +3382,10 @@ def set_printoptions(**kwargs):
xml : bool, optional xml : bool, optional
When False, printing of the XML contents of any XML boxes or UUID XMP When False, printing of the XML contents of any XML boxes or UUID XMP
boxes is suppressed. boxes is suppressed.
siz : bool, optional codestream : bool, optional
When True, only the SIZ segment is printed. When False, the entire When False, only the codestream header is printed. When True, the
codestream is printed. This option has no effect when the 'short' entire codestream is printed. This option has no effect when the
option is set to True. 'short' option is set to True.
See also See also
-------- --------

View file

@ -1043,26 +1043,25 @@ class TestParsing(unittest.TestCase):
def setUp(self): def setUp(self):
self.jp2file = glymur.data.nemo() self.jp2file = glymur.data.nemo()
# Reset parseoptions for every test. # Reset parseoptions for every test.
glymur.set_parseoptions(codestream=True) glymur.set_parseoptions(full_codestream=False)
def tearDown(self): def tearDown(self):
glymur.set_parseoptions(codestream=True) glymur.set_parseoptions(full_codestream=False)
@unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG) @unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG)
def test_bad_rsiz(self): def test_bad_rsiz(self):
"""Should not warn if RSIZ when parsing is turned off.""" """Should not warn if RSIZ when parsing is turned off."""
filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2') filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2')
glymur.set_parseoptions(codestream=False) glymur.set_parseoptions(full_codestream=False)
Jp2k(filename) jp2 = Jp2k(filename)
glymur.set_parseoptions(codestream=True) glymur.set_parseoptions(full_codestream=True)
with self.assertWarnsRegex(UserWarning, 'Invalid profile'): with self.assertWarnsRegex(UserWarning, 'Invalid profile'):
Jp2k(filename) Jp2k(filename)
def test_main_header(self): def test_main_header(self):
"""Verify that the main header isn't loaded when parsing turned off.""" """verify that the main header isn't loaded during normal parsing"""
# The hidden _main_header attribute should show up after accessing it. # The hidden _main_header attribute should show up after accessing it.
glymur.set_parseoptions(codestream=False)
jp2 = Jp2k(self.jp2file) jp2 = Jp2k(self.jp2file)
jp2c = jp2.box[4] jp2c = jp2.box[4]
self.assertIsNone(jp2c._codestream) self.assertIsNone(jp2c._codestream)

View file

@ -1040,9 +1040,10 @@ class TestJp2dump(unittest.TestCase):
# Reset printoptions for every test. # Reset printoptions for every test.
glymur.set_printoptions(short=False, xml=True, codestream=True) glymur.set_printoptions(short=False, xml=True, codestream=True)
glymur.set_parseoptions(full_codestream=False)
def tearDown(self): def tearDown(self):
pass glymur.set_parseoptions(full_codestream=False)
def run_jp2dump(self, args): def run_jp2dump(self, args):
sys.argv = args sys.argv = args
@ -1083,6 +1084,14 @@ class TestJp2dump(unittest.TestCase):
expected = '\n'.join(expected) expected = '\n'.join(expected)
self.assertEqual(actual, expected) self.assertEqual(actual, expected)
def test_jp2_codestream_2(self):
"""Verify dumping with -c 2, print entire jp2 jacket, codestream."""
actual = self.run_jp2dump(['', '-c', '2', self.jp2file])
# shave off the non-main-header segments
expected = fixtures.nemo
self.assertEqual(actual, expected)
@unittest.skipIf(sys.hexversion < 0x03000000, "assertRegex not in 2.7") @unittest.skipIf(sys.hexversion < 0x03000000, "assertRegex not in 2.7")
def test_j2k_codestream_0(self): def test_j2k_codestream_0(self):
"""-c 0 should print just a single line when used on a codestream.""" """-c 0 should print just a single line when used on a codestream."""