diff --git a/docs/source/whatsnew/0.8.rst b/docs/source/whatsnew/0.8.rst
index f36b593..5c87f5a 100644
--- a/docs/source/whatsnew/0.8.rst
+++ b/docs/source/whatsnew/0.8.rst
@@ -6,5 +6,7 @@ Changes in 0.8.0
=================
* Simplified writing images by moving data and options into the
- constructor. This is backwards-incompatible with 0.7.x.
+ constructor.
+ * The main_header attribute of the ContiguousCodestream class is now called
+ codestream.
* Deprecated :py:meth:`read` method in favor of array-style slicing.
diff --git a/glymur/command_line.py b/glymur/command_line.py
index ff442f3..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():
@@ -13,23 +13,25 @@ def main():
Entry point for console script jp2dump.
"""
- description = 'Print JPEG2000 metadata.'
- parser = argparse.ArgumentParser(description=description)
+ kwargs = {'description': 'Print JPEG2000 metadata.',
+ 'formatter_class': argparse.ArgumentDefaultsHelpFormatter}
+ parser = argparse.ArgumentParser(**kwargs)
parser.add_argument('-x', '--noxml',
- help='Suppress XML.',
+ help='suppress XML',
action='store_true')
parser.add_argument('-s', '--short',
- help='Only print box id, offset, and length.',
+ help='only print box id, offset, and length',
action='store_true')
- chelp = 'Level of codestream information. 0 suppressed all details, '
- chelp += '1 prints headers, 2 prints the full codestream'
+ chelp = 'Level of codestream information. 0 suppresses all details, '
+ chelp += '1 prints the main header, 2 prints the full codestream.'
parser.add_argument('-c', '--codestream',
help=chelp,
+ metavar='LEVEL',
nargs=1,
type=int,
- default=[0])
+ default=[1])
parser.add_argument('filename')
@@ -45,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
@@ -58,11 +57,14 @@ def main():
# JP2 metadata can be extensive, so don't print any warnings until we
# are done with the metadata.
jp2 = Jp2k(filename)
- if (((jp2._codec_format == lib.openjp2.CODEC_J2K) and
- (codestream_level == 0))):
- print('File: {0}'.format(os.path.basename(filename)))
- elif print_full_codestream:
- print(jp2.get_codestream(header_only=False))
+ if jp2._codec_format == lib.openjp2.CODEC_J2K:
+ if codestream_level == 0:
+ print('File: {0}'.format(os.path.basename(filename)))
+ elif codestream_level == 1:
+ print(jp2)
+ elif codestream_level == 2:
+ print('File: {0}'.format(os.path.basename(filename)))
+ print(jp2.get_codestream(header_only=False))
else:
print(jp2)
diff --git a/glymur/jp2box.py b/glymur/jp2box.py
index e29df28..bc23ebe 100644
--- a/glymur/jp2box.py
+++ b/glymur/jp2box.py
@@ -1001,18 +1001,19 @@ class ContiguousCodestreamBox(Jp2kBox):
offset of the box from the start of the file.
longname : str
more verbose description of the box.
- main_header : Codestream object
- contains list of main header marker/segments
+ codestream : Codestream object
+ Contains list of codestream marker/segments. By default, only the main
+ header is retrieved.
main_header_offset : int
offset of main header from start of file
"""
box_id = 'jp2c'
longname = 'Contiguous Codestream'
- def __init__(self, main_header=None, main_header_offset=None, length=0,
+ def __init__(self, codestream=None, main_header_offset=None, length=0,
offset=-1):
Jp2kBox.__init__(self)
- self._main_header = main_header
+ self._codestream = codestream
self.length = length
self.offset = offset
self.main_header_offset = main_header_offset
@@ -1021,20 +1022,23 @@ class ContiguousCodestreamBox(Jp2kBox):
self._filename = None
@property
- def main_header(self):
- if self._main_header is None:
+ 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)
- main_header = Codestream(fptr,
- self._length,
- header_only=True)
- self._main_header = main_header
- return self._main_header
+ codestream = Codestream(fptr, self._length,
+ header_only=header_only)
+ self._codestream = codestream
+ return self._codestream
def __repr__(self):
- msg = "glymur.jp2box.ContiguousCodeStreamBox(main_header={0})"
- return msg.format(repr(self.main_header))
+ msg = "glymur.jp2box.ContiguousCodeStreamBox(codestream={0})"
+ return msg.format(repr(self.codestream))
def __str__(self):
msg = Jp2kBox.__str__(self)
@@ -1043,9 +1047,8 @@ class ContiguousCodestreamBox(Jp2kBox):
if _printoptions['codestream'] is False:
return msg
- msg += '\n Main header:'
- for segment in self.main_header.segment:
- msg += '\n' + self._indent(str(segment), indent_level=8)
+ for segment in self.codestream.segment:
+ msg += '\n' + self._indent(str(segment), indent_level=4)
return msg
@@ -1067,11 +1070,11 @@ 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
@@ -1320,7 +1323,7 @@ class FileTypeBox(Jp2kBox):
if sys.hexversion >= 0x03000000:
try:
entry = entry.decode('utf-8')
- except UnicodeDecodeError as err:
+ except UnicodeDecodeError:
# The entry is invalid, but we've got code to catch this
# later on.
pass
@@ -3314,19 +3317,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
--------
@@ -3337,9 +3341,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():
@@ -3378,7 +3382,9 @@ def set_printoptions(**kwargs):
When False, printing of the XML contents of any XML boxes or UUID XMP
boxes is suppressed.
codestream : bool, optional
- When False, printing of the codestream contents is suppressed.
+ 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/fixtures.py b/glymur/test/fixtures.py
index c7bab78..dc27b0e 100644
--- a/glymur/test/fixtures.py
+++ b/glymur/test/fixtures.py
@@ -2,6 +2,7 @@
Test fixtures common to more than one test point.
"""
import os
+import platform
import re
import sys
import textwrap
@@ -33,6 +34,14 @@ elif re.match('1.[0-6]', six.__version__) is not None:
WARNING_INFRASTRUCTURE_ISSUE = True
msg = "Cannot run test with version {0} of python-six"
WARNING_INFRASTRUCTURE_MSG = msg.format(six.__version__)
+elif ((re.match('1.8', six.__version__) is not None) and
+ (sys.platform.startswith('linux')) and
+ (platform.linux_distribution() == ('LinuxMint', '17', 'qiana'))):
+ WARNING_INFRASTRUCTURE_ISSUE = True
+ linux_distribution = platform.linux_distribution()
+ msg = "Cannot run test with version {0} of python-six on {1}"
+ WARNING_INFRASTRUCTURE_MSG = msg.format(six.__version__,
+ platform.linux_distribution)
# Cannot reopen a named temporary file in windows.
WINDOWS_TMP_FILE_MSG = "cannot use NamedTemporaryFile like this in windows"
@@ -709,6 +718,190 @@ UUID Box (uuid) @ (77, 3146)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
Contiguous Codestream Box (jp2c) @ (3223, 1132296)"""
+nemo = """JPEG 2000 Signature Box (jP ) @ (0, 12)
+ Signature: 0d0a870a
+File Type Box (ftyp) @ (12, 20)
+ Brand: jp2
+ Compatibility: ['jp2 ']
+JP2 Header Box (jp2h) @ (32, 45)
+ Image Header Box (ihdr) @ (40, 22)
+ Size: [1456 2592 3]
+ Bitdepth: 8
+ Signed: False
+ Compression: wavelet
+ Colorspace Unknown: False
+ Colour Specification Box (colr) @ (62, 15)
+ Method: enumerated colorspace
+ Precedence: 0
+ Colorspace: sRGB
+UUID Box (uuid) @ (77, 3146)
+ UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
+ UUID Data:
+
+
+
+
+ Google
+ 2013-02-09T14:47:53
+
+
+ 1
+ 72/1
+ 72/1
+ 2
+ HTC
+ HTC Glacier
+ 2592
+ 1456
+
+
+ 8
+ 8
+ 8
+
+
+ 2
+ 3
+
+
+ 1343036288/4294967295
+ 1413044224/4294967295
+
+
+
+
+ 2748779008/4294967295
+ 1417339264/4294967295
+ 1288490240/4294967295
+ 2576980480/4294967295
+ 644245120/4294967295
+ 257698032/4294967295
+
+
+
+
+ 1
+ 2528
+ 1424
+ 353/100
+ 0
+ 0/1
+ WGS-84
+ 2013-02-09T14:47:53
+
+
+ 76
+
+
+ 0220
+ 0100
+
+
+ 1
+ 2
+ 3
+ 0
+
+
+ 42,20.56N
+ 71,5.29W
+ 2013-02-09T19:47:53Z
+ NETWORK
+
+
+ 2013-02-09T14:47:53
+
+
+
+
+ Glymur
+ Python XMP Toolkit
+
+
+
+
+
+
+Contiguous Codestream Box (jp2c) @ (3223, 1132296)
+ SOC marker segment @ (3231, 0)
+ SIZ marker segment @ (3233, 47)
+ Profile: no profile
+ Reference Grid Height, Width: (1456 x 2592)
+ Vertical, Horizontal Reference Grid Offset: (0 x 0)
+ Reference Tile Height, Width: (1456 x 2592)
+ Vertical, Horizontal Reference Tile Offset: (0 x 0)
+ Bitdepth: (8, 8, 8)
+ Signed: (False, False, False)
+ Vertical, Horizontal Subsampling: ((1, 1), (1, 1), (1, 1))
+ COD marker segment @ (3282, 12)
+ Coding style:
+ Entropy coder, without partitions
+ SOP marker segments: False
+ EPH marker segments: False
+ Coding style parameters:
+ Progression order: LRCP
+ Number of layers: 2
+ Multiple component transformation usage: reversible
+ Number of resolutions: 2
+ Code block height, width: (64 x 64)
+ Wavelet transform: 5-3 reversible
+ Precinct size: default, 2^15 x 2^15
+ Code block context:
+ Selective arithmetic coding bypass: False
+ Reset context probabilities on coding pass boundaries: False
+ Termination on each coding pass: False
+ Vertically stripe causal context: False
+ Predictable termination: False
+ Segmentation symbols: False
+ QCD marker segment @ (3296, 7)
+ Quantization style: no quantization, 2 guard bits
+ Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]
+ CME marker segment @ (3305, 37)
+ "Created by OpenJPEG version 2.0.0"
+ SOT marker segment @ (3344, 10)
+ Tile part index: 0
+ Tile part length: 1132173
+ Tile part instance: 0
+ Number of tile parts: 1
+ COC marker segment @ (3356, 9)
+ Associated component: 1
+ Coding style for this component: Entropy coder, PARTITION = 0
+ Coding style parameters:
+ Number of resolutions: 2
+ Code block height, width: (64 x 64)
+ Wavelet transform: 5-3 reversible
+ Code block context:
+ Selective arithmetic coding bypass: False
+ Reset context probabilities on coding pass boundaries: False
+ Termination on each coding pass: False
+ Vertically stripe causal context: False
+ Predictable termination: False
+ Segmentation symbols: False
+ QCC marker segment @ (3367, 8)
+ Associated Component: 1
+ Quantization style: no quantization, 2 guard bits
+ Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]
+ COC marker segment @ (3377, 9)
+ Associated component: 2
+ Coding style for this component: Entropy coder, PARTITION = 0
+ Coding style parameters:
+ Number of resolutions: 2
+ Code block height, width: (64 x 64)
+ Wavelet transform: 5-3 reversible
+ Code block context:
+ Selective arithmetic coding bypass: False
+ Reset context probabilities on coding pass boundaries: False
+ Termination on each coding pass: False
+ Vertically stripe causal context: False
+ Predictable termination: False
+ Segmentation symbols: False
+ QCC marker segment @ (3388, 8)
+ Associated Component: 2
+ Quantization style: no quantization, 2 guard bits
+ Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]
+ SOD marker segment @ (3398, 0)
+ EOC marker segment @ (1135517, 0)"""
+
# Output of reader requirements printing for text_GBR.jp2
text_GBR_rreq = r"""Reader Requirements Box (rreq) @ (40, 109)
Fully Understands Aspect Mask: 0xffff
diff --git a/glymur/test/test_glymur_warnings.py b/glymur/test/test_glymur_warnings.py
index ff18c6e..8086004 100644
--- a/glymur/test/test_glymur_warnings.py
+++ b/glymur/test/test_glymur_warnings.py
@@ -20,6 +20,13 @@ from .fixtures import WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG
class TestWarnings(unittest.TestCase):
"""Test suite for warnings issued by glymur."""
+ def test_invalid_compatibility_list_entry(self):
+ """should not error out with invalid compatibility list entry"""
+ filename = opj_data_file('input/nonregression/issue397.jp2')
+ with self.assertWarns(UserWarning):
+ Jp2k(filename)
+ self.assertTrue(True)
+
def test_exceeded_box_length(self):
"""
should warn if reading past end of a box
@@ -62,7 +69,7 @@ class TestWarnings(unittest.TestCase):
\(\d+\)\.""",
re.VERBOSE)
with self.assertWarnsRegex(UserWarning, regex):
- Jp2k(jfile)
+ Jp2k(jfile).get_codestream()
@unittest.skipIf(re.match("1.5|2.0.0", glymur.version.openjpeg_version),
"Test not passing on 1.5.x, not introduced until 2.x")
@@ -77,7 +84,7 @@ class TestWarnings(unittest.TestCase):
\(\d+\)\.""",
re.VERBOSE)
with self.assertWarnsRegex(UserWarning, regex):
- Jp2k(jfile)
+ Jp2k(jfile).get_codestream()
def test_NR_gdal_fuzzer_check_comp_dx_dy_jp2_dump(self):
"""
@@ -90,7 +97,7 @@ class TestWarnings(unittest.TestCase):
dx=\d+,\s*dy=\d+""",
re.VERBOSE)
with self.assertWarnsRegex(UserWarning, regex):
- Jp2k(jfile)
+ Jp2k(jfile).get_codestream()
def test_NR_gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc_patch_jp2(self):
lst = ['input', 'nonregression',
@@ -100,32 +107,32 @@ class TestWarnings(unittest.TestCase):
number\sof\scomponents\sis\sonly\s\d+""",
re.VERBOSE)
with self.assertWarnsRegex(UserWarning, regex):
- Jp2k(jfile)
+ Jp2k(jfile).get_codestream()
def test_bad_rsiz(self):
"""Should warn if RSIZ is bad. Issue196"""
filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2')
with self.assertWarnsRegex(UserWarning, 'Invalid profile'):
- Jp2k(filename)
+ Jp2k(filename).get_codestream()
def test_bad_wavelet_transform(self):
"""Should warn if wavelet transform is bad. Issue195"""
filename = opj_data_file('input/nonregression/edf_c2_10025.jp2')
with self.assertWarnsRegex(UserWarning, 'Invalid wavelet transform'):
- Jp2k(filename)
+ Jp2k(filename).get_codestream()
def test_invalid_progression_order(self):
"""Should still be able to parse even if prog order is invalid."""
jfile = opj_data_file('input/nonregression/2977.pdf.asan.67.2198.jp2')
with self.assertWarnsRegex(UserWarning, 'Invalid progression order'):
- Jp2k(jfile)
+ Jp2k(jfile).get_codestream()
def test_tile_height_is_zero(self):
"""Zero tile height should not cause an exception."""
filename = 'input/nonregression/2539.pdf.SIGFPE.706.1712.jp2'
filename = opj_data_file(filename)
with self.assertWarnsRegex(UserWarning, 'Invalid tile dimensions'):
- Jp2k(filename)
+ Jp2k(filename).get_codestream()
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_unknown_marker_segment(self):
diff --git a/glymur/test/test_jp2box.py b/glymur/test/test_jp2box.py
index 9ccd75b..e43eae6 100644
--- a/glymur/test/test_jp2box.py
+++ b/glymur/test/test_jp2box.py
@@ -1016,7 +1016,7 @@ class TestJp2Boxes(unittest.TestCase):
"""Raw instantiation should not produce a main_header."""
box = ContiguousCodestreamBox()
self.assertEqual(box.box_id, 'jp2c')
- self.assertIsNone(box.main_header)
+ self.assertIsNone(box.codestream)
def test_codestream_main_header_offset(self):
"""main_header_offset is an attribute of the CCS box"""
@@ -1318,7 +1318,7 @@ class TestRepr(MetadataBase):
# Difficult to eval(repr()) this, so just match the general pattern.
regexp = "glymur.jp2box.ContiguousCodeStreamBox"
- regexp += "[(]main_header=[)]"
if sys.hexversion < 0x03000000:
diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py
index 4bc928b..668f8d5 100644
--- a/glymur/test/test_jp2k.py
+++ b/glymur/test/test_jp2k.py
@@ -36,6 +36,9 @@ from .fixtures import OPJ_DATA_ROOT, opj_data_file
from . import fixtures
+def docTearDown(doctest_obj):
+ glymur.set_parseoptions(full_codestream=False)
+
# Doc tests should be run as well.
def load_tests(loader, tests, ignore):
"""Should run doc tests as well"""
@@ -43,7 +46,8 @@ def load_tests(loader, tests, ignore):
# Can't do it on windows, temporary file issue.
return tests
if glymur.lib.openjp2.OPENJP2 is not None:
- tests.addTests(doctest.DocTestSuite('glymur.jp2k'))
+ tests.addTests(doctest.DocTestSuite('glymur.jp2k',
+ tearDown=docTearDown))
return tests
@@ -272,15 +276,6 @@ class TestJp2k(unittest.TestCase):
jp2 = Jp2k(jfile)
self.assertEqual(jp2.shape, (128, 128))
- @unittest.skipIf(OPJ_DATA_ROOT is None,
- "OPJ_DATA_ROOT environment variable not set")
- def test_invalid_compatibility_list_entry(self):
- """should not error out with invalid compatibility list entry"""
- filename = opj_data_file('input/nonregression/issue397.jp2')
- with self.assertWarns(UserWarning):
- Jp2k(filename)
- self.assertTrue(True)
-
def test_shape_j2k(self):
"""verify shape attribute for J2K file
"""
@@ -1052,31 +1047,30 @@ 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)
+ glymur.set_parseoptions(full_codestream=False)
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._main_header)
- jp2c.main_header
- self.assertIsNotNone(jp2c._main_header)
+ self.assertIsNone(jp2c._codestream)
+ jp2c.codestream
+ self.assertIsNotNone(jp2c._codestream)
@unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG)
@@ -1085,6 +1079,9 @@ class TestParsing(unittest.TestCase):
class TestJp2kOpjDataRootWarnings(unittest.TestCase):
"""These tests should be run by just about all configuration."""
+ def tearDown(self):
+ glymur.set_parseoptions(full_codestream=False)
+
def test_undecodeable_box_id(self):
"""Should warn in case of undecodeable box ID but not error out."""
filename = opj_data_file('input/nonregression/edf_c2_1013627.jp2')
diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py
index 431b480..9e8a0eb 100644
--- a/glymur/test/test_opj_suite.py
+++ b/glymur/test/test_opj_suite.py
@@ -385,7 +385,7 @@ class TestSuiteWarns(MetadataBase):
expected = ColourSpecificationBox(colorspace=glymur.core.SRGB)
self.verifyColourSpecificationBox(jp2.box[2].box[1], expected)
- c = jp2.box[3].main_header
+ c = jp2.box[3].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'CME', 'COD', 'QCD', 'QCC', 'QCC']
diff --git a/glymur/test/test_opj_suite_dump.py b/glymur/test/test_opj_suite_dump.py
index 844ce9c..7ac513f 100644
--- a/glymur/test/test_opj_suite_dump.py
+++ b/glymur/test/test_opj_suite_dump.py
@@ -4,6 +4,7 @@ suite.
"""
import re
import unittest
+import warnings
import numpy as np
@@ -52,7 +53,7 @@ class TestSuite(MetadataBase):
colr = glymur.jp2box.ColourSpecificationBox(colorspace=glymur.core.YCC)
self.verifyColourSpecificationBox(jp2.box[2].box[1], colr)
- c = jp2.box[3].main_header
+ c = jp2.box[3].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD']
@@ -2584,7 +2585,7 @@ class TestSuite(MetadataBase):
self.assertEqual(jp2.box[3].box[3].mapping_type, (1, 1, 1))
self.assertEqual(jp2.box[3].box[3].palette_index, (0, 1, 2))
- c = jp2.box[4].main_header
+ c = jp2.box[4].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD']
@@ -2648,7 +2649,7 @@ class TestSuite(MetadataBase):
precedence=2)
self.verifyColourSpecificationBox(jp2.box[3].box[1], colr)
- c = jp2.box[4].main_header
+ c = jp2.box[4].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD']
@@ -2711,7 +2712,7 @@ class TestSuite(MetadataBase):
self.assertEqual(jp2.box[2].box[2].channel_type, (0, 1)) # opacity
self.assertEqual(jp2.box[2].box[2].association, (0, 0)) # both main
- c = jp2.box[3].main_header
+ c = jp2.box[3].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD', 'CME']
@@ -2794,7 +2795,7 @@ class TestSuite(MetadataBase):
self.assertEqual(jp2.box[3].box[3].mapping_type, (1, 1, 1))
self.assertEqual(jp2.box[3].box[3].palette_index, (0, 1, 2))
- c = jp2.box[4].main_header
+ c = jp2.box[4].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD']
@@ -2848,7 +2849,7 @@ class TestSuite(MetadataBase):
colr = glymur.jp2box.ColourSpecificationBox(colorspace=glymur.core.YCC)
self.verifyColourSpecificationBox(jp2.box[2].box[1], colr)
- c = jp2.box[3].main_header
+ c = jp2.box[3].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD', 'POD']
@@ -2913,21 +2914,29 @@ class TestSuiteWarns(MetadataBase):
def test_NR_broken4_jp2_dump(self):
jfile = opj_data_file('input/nonregression/broken4.jp2')
- with self.assertWarns(UserWarning):
- jp2 = Jp2k(jfile)
-
- self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC')
+ with warnings.catch_warnings():
+ # Suppress a warning, all we really care is parsing the entire
+ # file.
+ warnings.simplefilter("ignore")
+ with self.assertWarns(UserWarning):
+ jp2 = Jp2k(jfile)
+ self.assertEqual(jp2.box[-1].codestream.segment[-1].marker_id,
+ 'QCC')
def test_NR_broken2_jp2_dump(self):
"""
Invalid marker ID in the codestream.
"""
jfile = opj_data_file('input/nonregression/broken2.jp2')
- with self.assertWarns(UserWarning):
- # Invalid marker ID on codestream.
- jp2 = Jp2k(jfile)
-
- self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC')
+ with warnings.catch_warnings():
+ # Suppress a warning, all we really care is parsing the entire
+ # file.
+ warnings.simplefilter("ignore")
+ with self.assertWarns(UserWarning):
+ # Invalid marker ID on codestream.
+ jp2 = Jp2k(jfile)
+ self.assertEqual(jp2.box[-1].codestream.segment[-1].marker_id,
+ 'QCC')
def test_NR_file1_dump(self):
jfile = opj_data_file('input/conformance/file1.jp2')
@@ -3243,7 +3252,7 @@ class TestSuiteWarns(MetadataBase):
# Skip the 4th box, it is uknown.
- c = jp2.box[4].main_header
+ c = jp2.box[4].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD', 'CME', 'CME']
@@ -3303,7 +3312,7 @@ class TestSuiteWarns(MetadataBase):
self.assertIsNone(jp2.box[2].box[1].icc_profile)
self.assertIsNone(jp2.box[2].box[1].colorspace)
- c = jp2.box[3].main_header
+ c = jp2.box[3].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD']
@@ -3366,7 +3375,7 @@ class TestSuiteWarns(MetadataBase):
self.assertIsNone(jp2.box[2].box[1].icc_profile)
self.assertIsNone(jp2.box[2].box[1].colorspace)
- c = jp2.box[3].main_header
+ c = jp2.box[3].codestream
ids = [x.marker_id for x in c.segment]
expected = ['SOC', 'SIZ', 'COD', 'QCD']
diff --git a/glymur/test/test_opj_suite_write.py b/glymur/test/test_opj_suite_write.py
index eabb4bc..f44c7b4 100644
--- a/glymur/test/test_opj_suite_write.py
+++ b/glymur/test/test_opj_suite_write.py
@@ -632,7 +632,7 @@ class TestSuiteWrite(fixtures.MetadataBase):
self.assertIsNone(jp2.box[2].box[1].icc_profile)
self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB)
- codestream = jp2.box[3].main_header
+ codestream = jp2.box[3].codestream
kwargs = {'rsiz': 0, 'xysiz': (640, 480), 'xyosiz': (0, 0),
'xytsiz': (640, 480), 'xytosiz': (0, 0),
diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py
index 49fec57..5310fa9 100644
--- a/glymur/test/test_printing.py
+++ b/glymur/test/test_printing.py
@@ -42,7 +42,7 @@ class TestPrinting(unittest.TestCase):
glymur.set_printoptions(short=False, xml=True, codestream=True)
def tearDown(self):
- pass
+ glymur.set_parseoptions(full_codestream=False)
def test_version_info(self):
"""Should be able to print(glymur.version.info)"""
@@ -854,7 +854,7 @@ class TestPrintingOpjDataRootWarns(unittest.TestCase):
"""Should still be able to print if rsiz is bad, issue196"""
filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2')
with self.assertWarns(UserWarning):
- j = Jp2k(filename)
+ j = Jp2k(filename).get_codestream()
with patch('sys.stdout', new=StringIO()):
print(j)
@@ -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
@@ -1055,25 +1056,51 @@ class TestJp2dump(unittest.TestCase):
return actual
def test_default_nemo(self):
- """Should be able to dump a JP2 file's metadata with no codestream."""
+ """by default one should get the main header"""
actual = self.run_jp2dump(['', self.jp2file])
- self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
+ # shave off the non-main-header segments
+ lines = fixtures.nemo.split('\n')
+ expected = lines[0:140]
+ expected = '\n'.join(expected)
+ self.assertEqual(actual, expected)
- def test_codestream_0(self):
+ @unittest.skipIf(sys.hexversion < 0x03000000, "assertRegex not in 2.7")
+ def test_jp2_codestream_0(self):
"""Verify dumping with -c 0, supressing all codestream details."""
actual = self.run_jp2dump(['', '-c', '0', self.jp2file])
expected = fixtures.nemo_dump_no_codestream
self.assertEqual(actual, expected)
- def test_codestream_1(self):
+ def test_jp2_codestream_1(self):
"""Verify dumping with -c 1, print just the header."""
actual = self.run_jp2dump(['', '-c', '1', self.jp2file])
- self.assertEqual(actual, fixtures.nemo_with_codestream_header)
+ # shave off the non-main-header segments
+ lines = fixtures.nemo.split('\n')
+ expected = lines[0:140]
+ expected = '\n'.join(expected)
+ self.assertEqual(actual, expected)
- def test_codestream_2(self):
+ 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."""
+ sys.argv = ['', '-c', '0', self.j2kfile]
+ with patch('sys.stdout', new=StringIO()) as fake_out:
+ command_line.main()
+ actual = fake_out.getvalue().strip()
+ self.assertRegex(actual, "File: .*")
+
+ def test_j2k_codestream_2(self):
"""Verify dumping with -c 2, full details."""
with patch('sys.stdout', new=StringIO()) as fake_out:
sys.argv = ['', '-c', '2', self.j2kfile]
@@ -1098,13 +1125,9 @@ class TestJp2dump(unittest.TestCase):
"""Verify dumping with -x, suppress XML."""
actual = self.run_jp2dump(['', '-x', self.jp2file])
- self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)
-
- @unittest.skipIf(sys.hexversion < 0x03000000, "assertRegex not in 2.7")
- def test_codestream_0_with_j2k_file(self):
- """-c 0 should print just a single line when used on a codestream."""
- sys.argv = ['', '-c', '0', self.j2kfile]
- with patch('sys.stdout', new=StringIO()) as fake_out:
- command_line.main()
- actual = fake_out.getvalue().strip()
- self.assertRegex(actual, "File: .*")
+ # shave off the XML and non-main-header segments
+ lines = fixtures.nemo.split('\n')
+ expected = lines[0:18]
+ expected.extend(lines[104:140])
+ expected = '\n'.join(expected)
+ self.assertEqual(actual, expected)