Not decoding box ID anymore. #197
We don't actually use the box ID as parsed from the file, so there was no need to decode it. This means that unrecognized box IDs are actually kept as bytes, but no big deal. The code is simplified a bit because of this.
This commit is contained in:
parent
2a75fcfff2
commit
55a01cbc39
6 changed files with 61 additions and 40 deletions
|
|
@ -43,7 +43,7 @@ def tiff_header(read_buffer):
|
|||
endian = '>'
|
||||
else:
|
||||
msg = "Bad byte order indication: {0}".format(read_buffer[6:8])
|
||||
raise RuntimeError(msg)
|
||||
raise IOError(msg)
|
||||
|
||||
_, offset = struct.unpack(endian + 'HI', read_buffer[8:14])
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,13 @@ class Jp2kBox(object):
|
|||
"""
|
||||
try:
|
||||
box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes)
|
||||
|
||||
except UnicodeDecodeError:
|
||||
msg = 'Unrecognized box ({0}) encountered.'.format(box_id)
|
||||
warnings.warn(msg)
|
||||
box = UnknownBox(' ', offset=start, length=num_bytes,
|
||||
longname='Unknown')
|
||||
|
||||
except KeyError:
|
||||
msg = 'Unrecognized box ({0}) encountered.'.format(box_id)
|
||||
warnings.warn(msg)
|
||||
|
|
@ -194,7 +201,6 @@ class Jp2kBox(object):
|
|||
pos = fptr.tell()
|
||||
read_buffer = fptr.read(8)
|
||||
_, 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.
|
||||
|
|
@ -230,16 +236,12 @@ class Jp2kBox(object):
|
|||
break
|
||||
|
||||
read_buffer = fptr.read(8)
|
||||
try:
|
||||
(box_length, box_id) = struct.unpack('>I4s', read_buffer)
|
||||
except Exception as err:
|
||||
if len(read_buffer) < 8:
|
||||
msg = "Extra bytes at end of file ignored."
|
||||
warnings.warn(msg)
|
||||
return superbox
|
||||
|
||||
if sys.hexversion >= 0x03000000:
|
||||
box_id = box_id.decode('utf-8')
|
||||
|
||||
(box_length, box_id) = 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.
|
||||
|
|
@ -2998,7 +3000,11 @@ class UUIDBox(Jp2kBox):
|
|||
|
||||
try:
|
||||
self._parse_raw_data()
|
||||
except RuntimeError as error:
|
||||
except KeyError as error:
|
||||
# Such as when an Exif tag is unrecognized.
|
||||
warnings.warn(str(error))
|
||||
except IOError as error:
|
||||
# Such as when Exif byte order is unrecognized.
|
||||
warnings.warn(str(error))
|
||||
|
||||
def _parse_raw_data(self):
|
||||
|
|
@ -3088,33 +3094,33 @@ class UUIDBox(Jp2kBox):
|
|||
|
||||
# Map each box ID to the corresponding class.
|
||||
_BOX_WITH_ID = {
|
||||
'asoc': AssociationBox,
|
||||
'cdef': ChannelDefinitionBox,
|
||||
'cmap': ComponentMappingBox,
|
||||
'colr': ColourSpecificationBox,
|
||||
'dtbl': DataReferenceBox,
|
||||
'ftyp': FileTypeBox,
|
||||
'ihdr': ImageHeaderBox,
|
||||
'jP ': JPEG2000SignatureBox,
|
||||
'jpch': CodestreamHeaderBox,
|
||||
'jplh': CompositingLayerHeaderBox,
|
||||
'jp2c': ContiguousCodestreamBox,
|
||||
'free': FreeBox,
|
||||
'flst': FragmentListBox,
|
||||
'ftbl': FragmentTableBox,
|
||||
'jp2h': JP2HeaderBox,
|
||||
'lbl ': LabelBox,
|
||||
'nlst': NumberListBox,
|
||||
'pclr': PaletteBox,
|
||||
'res ': ResolutionBox,
|
||||
'resc': CaptureResolutionBox,
|
||||
'resd': DisplayResolutionBox,
|
||||
'rreq': ReaderRequirementsBox,
|
||||
'uinf': UUIDInfoBox,
|
||||
'ulst': UUIDListBox,
|
||||
'url ': DataEntryURLBox,
|
||||
'uuid': UUIDBox,
|
||||
'xml ': XMLBox}
|
||||
b'asoc': AssociationBox,
|
||||
b'cdef': ChannelDefinitionBox,
|
||||
b'cmap': ComponentMappingBox,
|
||||
b'colr': ColourSpecificationBox,
|
||||
b'dtbl': DataReferenceBox,
|
||||
b'ftyp': FileTypeBox,
|
||||
b'ihdr': ImageHeaderBox,
|
||||
b'jP ': JPEG2000SignatureBox,
|
||||
b'jpch': CodestreamHeaderBox,
|
||||
b'jplh': CompositingLayerHeaderBox,
|
||||
b'jp2c': ContiguousCodestreamBox,
|
||||
b'free': FreeBox,
|
||||
b'flst': FragmentListBox,
|
||||
b'ftbl': FragmentTableBox,
|
||||
b'jp2h': JP2HeaderBox,
|
||||
b'lbl ': LabelBox,
|
||||
b'nlst': NumberListBox,
|
||||
b'pclr': PaletteBox,
|
||||
b'res ': ResolutionBox,
|
||||
b'resc': CaptureResolutionBox,
|
||||
b'resd': DisplayResolutionBox,
|
||||
b'rreq': ReaderRequirementsBox,
|
||||
b'uinf': UUIDInfoBox,
|
||||
b'ulst': UUIDListBox,
|
||||
b'url ': DataEntryURLBox,
|
||||
b'uuid': UUIDBox,
|
||||
b'xml ': XMLBox}
|
||||
|
||||
_printoptions = {'short': False, 'xml': True, 'codestream': True}
|
||||
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ class TestJPX(unittest.TestCase):
|
|||
|
||||
with self.assertWarns(UserWarning):
|
||||
jpx = Jp2k(tfile.name)
|
||||
self.assertEqual(jpx.box[-1].box_id, 'grp ')
|
||||
self.assertEqual(jpx.box[-1].box_id, b'grp ')
|
||||
self.assertEqual(jpx.box[-1].box[0].box_id, 'free')
|
||||
|
||||
def test_free_box(self):
|
||||
|
|
|
|||
|
|
@ -758,7 +758,22 @@ class TestJp2k_2_1(unittest.TestCase):
|
|||
class TestJp2kOpjDataRoot(unittest.TestCase):
|
||||
"""These tests should be run by just about all configuration."""
|
||||
|
||||
@unittest.skipIf(sys.hexversion < 0x03000000, "Test requires Python 3.3+")
|
||||
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')
|
||||
if sys.hexversion < 0x03000000:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
jp2 = Jp2k(filename)
|
||||
else:
|
||||
with self.assertWarns(UserWarning):
|
||||
jp2 = Jp2k(filename)
|
||||
|
||||
# Now make sure we got all of the boxes. Ignore the last, which was
|
||||
# bad.
|
||||
box_ids = [box.box_id for box in jp2.box[:-1]]
|
||||
self.assertEqual(box_ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
|
||||
|
||||
def test_invalid_approximation(self):
|
||||
"""Should warn in case of bad ftyp brand."""
|
||||
filename = opj_data_file('input/nonregression/edf_c2_1000290.jp2')
|
||||
|
|
|
|||
|
|
@ -5482,7 +5482,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
jp2 = Jp2k(jfile)
|
||||
|
||||
ids = [box.box_id for box in jp2.box]
|
||||
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'XML ', 'jp2c'])
|
||||
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', b'XML ', 'jp2c'])
|
||||
|
||||
ids = [box.box_id for box in jp2.box[2].box]
|
||||
self.assertEqual(ids, ['ihdr', 'colr'])
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class TestPrinting(unittest.TestCase):
|
|||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
print(jpx.box[-1])
|
||||
actual = fake_out.getvalue().strip()
|
||||
lines = ['Unknown Box (grp ) @ (695609, 20)',
|
||||
lines = ["Unknown Box (b'grp ') @ (695609, 20)",
|
||||
' Free Box (free) @ (695617, 12)']
|
||||
expected = '\n'.join(lines)
|
||||
self.assertEqual(actual, expected)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue