Jp2dump tests passing, more need to be written

This commit is contained in:
jevans 2015-01-05 20:23:52 -05:00
commit 2755e8edd4
3 changed files with 72 additions and 29 deletions

View file

@ -60,11 +60,19 @@ 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)))
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))
elif print_full_codestream:
print(jp2.get_codestream(header_only=False))
for box in jp2.box:
if box.box_id == 'jp2c':
box._get_codestream(header_only=False)
print(jp2)
else:
print(jp2)

View file

@ -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,16 +1022,16 @@ class ContiguousCodestreamBox(Jp2kBox):
self._filename = None
@property
def main_header(self):
if self._main_header is None:
def codestream(self):
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,
codestream = Codestream(fptr,
self._length,
header_only=True)
self._main_header = main_header
return self._main_header
self._codestream = codestream
return self._codestream
def __repr__(self):
msg = "glymur.jp2box.ContiguousCodeStreamBox(main_header={0})"
@ -1043,7 +1044,7 @@ class ContiguousCodestreamBox(Jp2kBox):
if _printoptions['codestream'] is False:
return msg
for segment in self.main_header.segment:
for segment in self.codestream.segment:
msg += '\n' + self._indent(str(segment), indent_level=4)
return msg
@ -1076,6 +1077,30 @@ class ContiguousCodestreamBox(Jp2kBox):
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.

View file

@ -1055,25 +1055,44 @@ 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):
@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]
@ -1104,12 +1123,3 @@ class TestJp2dump(unittest.TestCase):
expected.extend(lines[104:140])
expected = '\n'.join(expected)
self.assertEqual(actual, expected)
@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: .*")