From a24bff0af18512f701ad9441cfca296b74c45be9 Mon Sep 17 00:00:00 2001 From: John Evans Date: Tue, 6 Jan 2015 16:35:38 -0500 Subject: [PATCH] replaced main_header codestream attribute with codestream changed "codestream" parameter of set_parseoptions to "full_codestream" --- glymur/command_line.py | 14 ++------- glymur/jp2box.py | 61 +++++++++++++----------------------- glymur/test/test_jp2k.py | 13 ++++---- glymur/test/test_printing.py | 11 ++++++- 4 files changed, 40 insertions(+), 59 deletions(-) diff --git a/glymur/command_line.py b/glymur/command_line.py index 4cd080d..3d1d57e 100644 --- a/glymur/command_line.py +++ b/glymur/command_line.py @@ -5,7 +5,7 @@ import argparse import os import warnings -from . import Jp2k, set_printoptions, lib +from . import Jp2k, set_printoptions, set_parseoptions, lib def main(): @@ -47,11 +47,8 @@ def main(): if codestream_level == 0: set_printoptions(codestream=False) - print_full_codestream = False - elif codestream_level == 1: - print_full_codestream = False - else: - print_full_codestream = True + elif codestream_level == 2: + set_parseoptions(full_codestream=True) filename = args.filename @@ -68,11 +65,6 @@ def main(): elif codestream_level == 2: print('File: {0}'.format(os.path.basename(filename))) 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: print(jp2) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index c946e6b..1cbd53a 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -1023,13 +1023,17 @@ class ContiguousCodestreamBox(Jp2kBox): @property def codestream(self): + if _parseoptions['full_codestream'] is True: + header_only = False + else: + header_only = True if self._codestream is None: if self._filename is not None: with open(self._filename, 'rb') as fptr: fptr.seek(self.main_header_offset) codestream = Codestream(fptr, self._length, - header_only=True) + header_only=header_only) self._codestream = codestream return self._codestream @@ -1067,40 +1071,16 @@ class ContiguousCodestreamBox(Jp2kBox): ContiguousCodestreamBox instance """ main_header_offset = fptr.tell() - if _parseoptions['codestream'] is True: - main_header = Codestream(fptr, length, header_only=True) + if _parseoptions['full_codestream'] is True: + codestream = Codestream(fptr, length, header_only=False) else: - main_header = None - box = cls(main_header, main_header_offset=main_header_offset, + codestream = None + box = cls(codestream, main_header_offset=main_header_offset, length=length, offset=offset) box._filename = fptr.name box._length = length 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): """Container for Data Reference box information. @@ -3338,19 +3318,20 @@ _BOX_WITH_ID = { b'uuid': UUIDBox, b'xml ': XMLBox} -_parseoptions = {'codestream': True} +_parseoptions = {'full_codestream': False} -def set_parseoptions(codestream=True): +def set_parseoptions(full_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. + full_codestream : bool, defaults to True + When False, only the codestream header is parsed for metadata. This + can results in faster JP2/JPX parsing. When True, the entire + codestream is parsed for metadata. See also -------- @@ -3361,9 +3342,9 @@ def set_parseoptions(codestream=True): To put back the default options, you can use: >>> import glymur - >>> glymur.set_parseoptions(codestream=True) + >>> glymur.set_parseoptions(full_codestream=True) """ - _parseoptions['codestream'] = codestream + _parseoptions['full_codestream'] = full_codestream def get_parseoptions(): @@ -3401,10 +3382,10 @@ def set_printoptions(**kwargs): xml : bool, optional When False, printing of the XML contents of any XML boxes or UUID XMP boxes is suppressed. - siz : bool, optional - When True, only the SIZ segment is printed. When False, the entire - codestream is printed. This option has no effect when the 'short' - option is set to True. + codestream : bool, optional + When False, only the codestream header is printed. When True, the + entire codestream is printed. This option has no effect when the + 'short' option is set to True. See also -------- diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 53f174a..fe18022 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -1043,26 +1043,25 @@ class TestParsing(unittest.TestCase): def setUp(self): self.jp2file = glymur.data.nemo() # Reset parseoptions for every test. - glymur.set_parseoptions(codestream=True) + glymur.set_parseoptions(full_codestream=False) def tearDown(self): - glymur.set_parseoptions(codestream=True) + glymur.set_parseoptions(full_codestream=False) @unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG) def test_bad_rsiz(self): """Should not warn if RSIZ when parsing is turned off.""" filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2') - glymur.set_parseoptions(codestream=False) - Jp2k(filename) + glymur.set_parseoptions(full_codestream=False) + jp2 = Jp2k(filename) - glymur.set_parseoptions(codestream=True) + glymur.set_parseoptions(full_codestream=True) with self.assertWarnsRegex(UserWarning, 'Invalid profile'): Jp2k(filename) 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. - glymur.set_parseoptions(codestream=False) jp2 = Jp2k(self.jp2file) jp2c = jp2.box[4] self.assertIsNone(jp2c._codestream) diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index bef59ad..c141d65 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -1040,9 +1040,10 @@ class TestJp2dump(unittest.TestCase): # Reset printoptions for every test. glymur.set_printoptions(short=False, xml=True, codestream=True) + glymur.set_parseoptions(full_codestream=False) def tearDown(self): - pass + glymur.set_parseoptions(full_codestream=False) def run_jp2dump(self, args): sys.argv = args @@ -1083,6 +1084,14 @@ class TestJp2dump(unittest.TestCase): expected = '\n'.join(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") def test_j2k_codestream_0(self): """-c 0 should print just a single line when used on a codestream."""