From 331f901dae997b6babf9440d48fda26d33daba43 Mon Sep 17 00:00:00 2001 From: jevans Date: Sun, 16 Feb 2014 22:03:33 -0500 Subject: [PATCH] Refactored superbox parsing. #175 --- glymur/jp2box.py | 77 ++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index 4810834..d2e374b 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -120,6 +120,53 @@ class Jp2kBox(object): fptr.write(struct.pack('>I', end_pos - orig_pos)) fptr.seek(end_pos) + def parse_this_box(self, fptr, box_id, start, num_bytes): + """Parse the current box. + + Parameters + ---------- + fptr : file + Open file object. + box_id : str + 4-letter identifier for the current box. + start, num_bytes: int + Byte offset and length of the current box. + + Returns + ------- + box : Jp2kBox + object corresponding to the current box + """ + try: + box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes) + except KeyError as err: + msg = 'Unrecognized box ({0}) encountered.'.format(box_id) + warnings.warn(msg) + box = Jp2kBox(box_id, offset=start, length=num_bytes, + 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) + + return box + def parse_superbox(self, fptr): """Parse a superbox (box consisting of nothing but other boxes. @@ -159,36 +206,10 @@ class Jp2kBox(object): num_bytes, = struct.unpack('>Q', read_buffer) else: + # The box_length value really is the length of the box! num_bytes = box_length - # Call the proper parser for the given box with ID "T". - try: - box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes) - except KeyError as err: - msg = 'Unrecognized box ({0}) encountered.'.format(box_id) - warnings.warn(msg) - box = Jp2kBox(box_id, offset=start, length=num_bytes, - 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) + box = self.parse_this_box(fptr, box_id, start, num_bytes) superbox.append(box)