Merge branch 'issue197' into devel

This commit is contained in:
John Evans 2014-03-19 15:17:11 -04:00
commit 4e3d58ed20
6 changed files with 61 additions and 40 deletions

View file

@ -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])

View file

@ -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}

View file

@ -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):

View file

@ -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')

View file

@ -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'])

View file

@ -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)