Parsing unknown superboxes with known 1st sub box. #175
This commit is contained in:
parent
75785e4ab0
commit
3c333e999d
2 changed files with 41 additions and 1 deletions
|
|
@ -164,12 +164,32 @@ class Jp2kBox(object):
|
||||||
# Call the proper parser for the given box with ID "T".
|
# Call the proper parser for the given box with ID "T".
|
||||||
try:
|
try:
|
||||||
box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes)
|
box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes)
|
||||||
except KeyError:
|
except KeyError as err:
|
||||||
msg = 'Unrecognized box ({0}) encountered.'.format(box_id)
|
msg = 'Unrecognized box ({0}) encountered.'.format(box_id)
|
||||||
warnings.warn(msg)
|
warnings.warn(msg)
|
||||||
box = Jp2kBox(box_id, offset=start, length=num_bytes,
|
box = Jp2kBox(box_id, offset=start, length=num_bytes,
|
||||||
longname='Unknown box')
|
longname='Unknown box')
|
||||||
|
|
||||||
|
if fptr.tell() != start + 8:
|
||||||
|
# If the file pointer has advanced, then the KeyError
|
||||||
|
# ocurred during the parsing of the box.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Could it be a superbox with recognizable child boxes?
|
||||||
|
# Peek ahead to see.
|
||||||
|
pos = fptr.tell()
|
||||||
|
read_buffer = fptr.read(8)
|
||||||
|
sub_length, sub_id = struct.unpack('>I4s', read_buffer)
|
||||||
|
sub_id = sub_id.decode('utf-8')
|
||||||
|
|
||||||
|
# Regardless of whether or not we recognize the box, rewind back
|
||||||
|
# to properly advance to the next box.
|
||||||
|
fptr.seek(pos)
|
||||||
|
|
||||||
|
# Now process any child boxes if we actually did recognize it.
|
||||||
|
if sub_id in _BOX_WITH_ID.keys():
|
||||||
|
box.box = box.parse_superbox(fptr)
|
||||||
|
|
||||||
superbox.append(box)
|
superbox.append(box)
|
||||||
|
|
||||||
# Position to the start of the next box.
|
# Position to the start of the next box.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ Test suite specifically targeting JPX box layout.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
@ -202,6 +203,25 @@ class TestJPX(unittest.TestCase):
|
||||||
self.assertEqual(jpx.box[2].standard_flag,
|
self.assertEqual(jpx.box[2].standard_flag,
|
||||||
(5, 42, 45, 2, 18, 19, 1, 8, 12, 31, 20))
|
(5, 42, 45, 2, 18, 19, 1, 8, 12, 31, 20))
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.hexversion < 0x03000000, "Needs unittest in 3.x.")
|
||||||
|
def test_unknown_superbox(self):
|
||||||
|
"""Verify that we can handle an unknown superbox."""
|
||||||
|
with tempfile.NamedTemporaryFile(suffix='.jpx') as tfile:
|
||||||
|
with open(self.jpxfile, 'rb') as ifile:
|
||||||
|
tfile.write(ifile.read())
|
||||||
|
|
||||||
|
# Add the header for an unknwon superbox.
|
||||||
|
write_buffer = struct.pack('>I4s', 20, 'grp '.encode())
|
||||||
|
tfile.write(write_buffer)
|
||||||
|
write_buffer = struct.pack('>I4sI', 12, 'free'.encode(), 0)
|
||||||
|
tfile.write(write_buffer)
|
||||||
|
tfile.flush()
|
||||||
|
|
||||||
|
with self.assertWarns(UserWarning):
|
||||||
|
jpx = Jp2k(tfile.name)
|
||||||
|
self.assertEqual(jpx.box[-1].box_id, 'grp ')
|
||||||
|
self.assertEqual(jpx.box[-1].box[0].box_id, 'free')
|
||||||
|
|
||||||
def test_free_box(self):
|
def test_free_box(self):
|
||||||
"""Verify that we can handle a free box."""
|
"""Verify that we can handle a free box."""
|
||||||
j = Jp2k(self.jpxfile)
|
j = Jp2k(self.jpxfile)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue