Passing down XL flag into each box parser. #212

This should prevent having to call the tell method on the file pointer.
This commit is contained in:
John Evans 2014-04-04 13:24:16 -04:00
commit 1485bda7ff

View file

@ -159,18 +159,22 @@ class Jp2kBox(object):
fptr.write(struct.pack('>I', end_pos - orig_pos)) fptr.write(struct.pack('>I', end_pos - orig_pos))
fptr.seek(end_pos) fptr.seek(end_pos)
def _parse_this_box(self, fptr, box_id, start, num_bytes): def _parse_this_box(self, fptr, box_id, start, num_bytes, box_is_XL):
"""Parse the current box. """Parse the current box.
Parameters Parameters
---------- ----------
fptr : file fptr : file
Open file object. Open file object, currently points to start of box payload, not the
start of the box.
box_id : str box_id : str
4-letter identifier for the current box. 4-letter identifier for the current box.
start, num_bytes: int start, num_bytes : int
Byte offset and length of the current box. Byte offset and length of the current box.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
box : Jp2kBox box : Jp2kBox
@ -189,7 +193,7 @@ class Jp2kBox(object):
return box return box
box = parser(fptr, start, num_bytes) box = parser(fptr, start, num_bytes, box_is_XL=box_is_XL)
return box return box
def parse_superbox(self, fptr): def parse_superbox(self, fptr):
@ -221,6 +225,7 @@ class Jp2kBox(object):
warnings.warn(msg) warnings.warn(msg)
return superbox return superbox
box_is_XL = False
(box_length, box_id) = struct.unpack('>I4s', read_buffer) (box_length, box_id) = struct.unpack('>I4s', read_buffer)
if box_length == 0: if box_length == 0:
# The length of the box is presumed to last until the end of # The length of the box is presumed to last until the end of
@ -231,12 +236,14 @@ class Jp2kBox(object):
# The length of the box is in the XL field, a 64-bit value. # The length of the box is in the XL field, a 64-bit value.
read_buffer = fptr.read(8) read_buffer = fptr.read(8)
num_bytes, = struct.unpack('>Q', read_buffer) num_bytes, = struct.unpack('>Q', read_buffer)
box_is_XL = True
else: else:
# The box_length value really is the length of the box! # The box_length value really is the length of the box!
num_bytes = box_length num_bytes = box_length
box = self._parse_this_box(fptr, box_id, start, num_bytes) box = self._parse_this_box(fptr, box_id, start, num_bytes,
box_is_XL)
superbox.append(box) superbox.append(box)
@ -392,7 +399,7 @@ class ColourSpecificationBox(Jp2kBox):
fptr.write(read_buffer) fptr.write(read_buffer)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPEG 2000 color specification box. """Parse JPEG 2000 color specification box.
Parameters Parameters
@ -403,12 +410,16 @@ class ColourSpecificationBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
ColourSpecificationBox instance ColourSpecificationBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
# Read the brand, minor version. # Read the brand, minor version.
(method, precedence, approximation) = struct.unpack_from('>BBB', (method, precedence, approximation) = struct.unpack_from('>BBB',
@ -644,7 +655,7 @@ class ChannelDefinitionBox(Jp2kBox):
self.association[j])) self.association[j]))
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse component definition box. """Parse component definition box.
Parameters Parameters
@ -655,12 +666,16 @@ class ChannelDefinitionBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
ComponentDefinitionBox instance ComponentDefinitionBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
# Read the number of components. # Read the number of components.
@ -714,7 +729,7 @@ class CodestreamHeaderBox(Jp2kBox):
self._write_superbox(fptr, b'jpch') self._write_superbox(fptr, b'jpch')
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse codestream header box. """Parse codestream header box.
Parameters Parameters
@ -725,6 +740,10 @@ class CodestreamHeaderBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -783,7 +802,7 @@ class ColourGroupBox(Jp2kBox):
self._write_superbox(fptr, b'cgrp') self._write_superbox(fptr, b'cgrp')
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse colour group box. """Parse colour group box.
Parameters Parameters
@ -794,6 +813,10 @@ class ColourGroupBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -846,7 +869,7 @@ class CompositingLayerHeaderBox(Jp2kBox):
self._write_superbox(fptr, b'jplh') self._write_superbox(fptr, b'jplh')
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse compositing layer header box. """Parse compositing layer header box.
Parameters Parameters
@ -857,6 +880,10 @@ class CompositingLayerHeaderBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -937,7 +964,7 @@ class ComponentMappingBox(Jp2kBox):
fptr.write(write_buffer) fptr.write(write_buffer)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse component mapping box. """Parse component mapping box.
Parameters Parameters
@ -948,12 +975,16 @@ class ComponentMappingBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
ComponentMappingBox instance ComponentMappingBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
num_components = int(num_bytes/4) num_components = int(num_bytes/4)
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
@ -1007,7 +1038,7 @@ class ContiguousCodestreamBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset=0, length=0): def parse(cls, fptr, offset=0, length=0, box_is_XL=False):
"""Parse a codestream box. """Parse a codestream box.
Parameters Parameters
@ -1018,6 +1049,10 @@ class ContiguousCodestreamBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1105,7 +1140,7 @@ class DataReferenceBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse data reference box. """Parse data reference box.
Parameters Parameters
@ -1116,6 +1151,10 @@ class DataReferenceBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1221,7 +1260,7 @@ class FileTypeBox(Jp2kBox):
fptr.write(item.encode()) fptr.write(item.encode())
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPEG 2000 file type box. """Parse JPEG 2000 file type box.
Parameters Parameters
@ -1232,12 +1271,17 @@ class FileTypeBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
FileTypeBox instance FileTypeBox instance
""" """
read_buffer = fptr.read(length - 8) num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes)
# Extract the brand, minor version. # Extract the brand, minor version.
(brand, minor_version) = struct.unpack_from('>4sI', read_buffer, 0) (brand, minor_version) = struct.unpack_from('>4sI', read_buffer, 0)
if sys.hexversion >= 0x030000: if sys.hexversion >= 0x030000:
@ -1333,7 +1377,7 @@ class FragmentListBox(Jp2kBox):
fptr.write(write_buffer) fptr.write(write_buffer)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPX free box. """Parse JPX free box.
Parameters Parameters
@ -1344,12 +1388,16 @@ class FragmentListBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
FragmentListBox instance FragmentListBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
num_fragments, = struct.unpack_from('>H', read_buffer, offset=0) num_fragments, = struct.unpack_from('>H', read_buffer, offset=0)
@ -1392,7 +1440,7 @@ class FragmentTableBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPX fragment table superbox box. """Parse JPX fragment table superbox box.
Parameters Parameters
@ -1403,6 +1451,10 @@ class FragmentTableBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1463,7 +1515,7 @@ class FreeBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPX free box. """Parse JPX free box.
Parameters Parameters
@ -1474,6 +1526,10 @@ class FreeBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1587,7 +1643,7 @@ class ImageHeaderBox(Jp2kBox):
fptr.write(read_buffer) fptr.write(read_buffer)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPEG 2000 image header box. """Parse JPEG 2000 image header box.
Parameters Parameters
@ -1598,6 +1654,10 @@ class ImageHeaderBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1655,7 +1715,7 @@ class AssociationBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse association box. """Parse association box.
Parameters Parameters
@ -1666,6 +1726,10 @@ class AssociationBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1721,7 +1785,7 @@ class JP2HeaderBox(Jp2kBox):
self._write_superbox(fptr, b'jp2h') self._write_superbox(fptr, b'jp2h')
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPEG 2000 header box. """Parse JPEG 2000 header box.
Parameters Parameters
@ -1732,6 +1796,10 @@ class JP2HeaderBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1789,7 +1857,7 @@ class JPEG2000SignatureBox(Jp2kBox):
fptr.write(struct.pack('>BBBB', *self.signature)) fptr.write(struct.pack('>BBBB', *self.signature))
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse JPEG 2000 signature box. """Parse JPEG 2000 signature box.
Parameters Parameters
@ -1800,6 +1868,10 @@ class JPEG2000SignatureBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -1907,7 +1979,7 @@ class PaletteBox(Jp2kBox):
fptr.write(write_buffer) fptr.write(write_buffer)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse palette box. """Parse palette box.
Parameters Parameters
@ -1918,6 +1990,10 @@ class PaletteBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -2136,7 +2212,7 @@ class ReaderRequirementsBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse reader requirements box. """Parse reader requirements box.
Parameters Parameters
@ -2147,6 +2223,10 @@ class ReaderRequirementsBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -2343,7 +2423,7 @@ class ResolutionBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse Resolution box. """Parse Resolution box.
Parameters Parameters
@ -2354,6 +2434,10 @@ class ResolutionBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -2407,7 +2491,7 @@ class CaptureResolutionBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse CaptureResolutionBox. """Parse CaptureResolutionBox.
Parameters Parameters
@ -2418,6 +2502,10 @@ class CaptureResolutionBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -2470,7 +2558,7 @@ class DisplayResolutionBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse display resolution box. """Parse display resolution box.
Parameters Parameters
@ -2481,6 +2569,10 @@ class DisplayResolutionBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -2538,7 +2630,7 @@ class LabelBox(Jp2kBox):
fptr.write(self.label.encode()) fptr.write(self.label.encode())
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse Label box. """Parse Label box.
Parameters Parameters
@ -2549,12 +2641,16 @@ class LabelBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
LabelBox instance LabelBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
label = read_buffer.decode('utf-8') label = read_buffer.decode('utf-8')
return cls(label, length=length, offset=offset) return cls(label, length=length, offset=offset)
@ -2609,7 +2705,7 @@ class NumberListBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse number list box. """Parse number list box.
Parameters Parameters
@ -2620,12 +2716,16 @@ class NumberListBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
LabelBox instance LabelBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
raw_data = fptr.read(num_bytes) raw_data = fptr.read(num_bytes)
num_associations = int(len(raw_data) / 4) num_associations = int(len(raw_data) / 4)
lst = struct.unpack('>' + 'I' * num_associations, raw_data) lst = struct.unpack('>' + 'I' * num_associations, raw_data)
@ -2713,7 +2813,7 @@ class XMLBox(Jp2kBox):
fptr.write(read_buffer) fptr.write(read_buffer)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse XML box. """Parse XML box.
Parameters Parameters
@ -2724,12 +2824,16 @@ class XMLBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
XMLBox instance XMLBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
try: try:
text = read_buffer.decode('utf-8') text = read_buffer.decode('utf-8')
@ -2813,7 +2917,7 @@ class UUIDListBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse UUIDList box. """Parse UUIDList box.
Parameters Parameters
@ -2824,12 +2928,16 @@ class UUIDListBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
UUIDListBox instance UUIDListBox instance
""" """
num_bytes = offset + length - fptr.tell() num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(num_bytes) read_buffer = fptr.read(num_bytes)
num_uuids, = struct.unpack_from('>H', read_buffer) num_uuids, = struct.unpack_from('>H', read_buffer)
@ -2873,7 +2981,7 @@ class UUIDInfoBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse UUIDInfo super box. """Parse UUIDInfo super box.
Parameters Parameters
@ -2884,6 +2992,10 @@ class UUIDInfoBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
@ -2966,7 +3078,7 @@ class DataEntryURLBox(Jp2kBox):
return msg return msg
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse data entry URL box. """Parse data entry URL box.
Parameters Parameters
@ -2977,19 +3089,22 @@ class DataEntryURLBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
DataEntryURLbox instance DataEntryURLbox instance
""" """
read_buffer = fptr.read(4) num_bytes = length - 16 if box_is_XL else length - 8
data = struct.unpack('>BBBB', read_buffer) read_buffer = fptr.read(num_bytes)
data = struct.unpack_from('>BBBB', read_buffer)
version = data[0] version = data[0]
flag = data[1:4] flag = data[1:4]
numbytes = offset + length - fptr.tell() url = read_buffer[4:].decode('utf-8').rstrip(chr(0))
read_buffer = fptr.read(numbytes)
url = read_buffer.decode('utf-8').rstrip(chr(0))
return cls(version, flag, url, length=length, offset=offset) return cls(version, flag, url, length=length, offset=offset)
@ -3140,7 +3255,7 @@ class UUIDBox(Jp2kBox):
fptr.write(self.raw_data) fptr.write(self.raw_data)
@classmethod @classmethod
def parse(cls, fptr, offset, length): def parse(cls, fptr, offset, length, box_is_XL=False):
"""Parse UUID box. """Parse UUID box.
Parameters Parameters
@ -3151,18 +3266,19 @@ class UUIDBox(Jp2kBox):
Start position of box in bytes. Start position of box in bytes.
length : int length : int
Length of the box in bytes. Length of the box in bytes.
box_is_XL : bool
True if the box has an XL field. In this case, the start of the
box is 16 bytes behind the start of the box payload instead of being
8 bytes behind.
Returns Returns
------- -------
UUIDBox instance UUIDBox instance
""" """
num_bytes = length - 16 if box_is_XL else length - 8
read_buffer = fptr.read(16) read_buffer = fptr.read(num_bytes)
the_uuid = uuid.UUID(bytes=read_buffer) the_uuid = uuid.UUID(bytes=read_buffer[0:16])
return cls(the_uuid, read_buffer[16:], length=length, offset=offset)
numbytes = offset + length - fptr.tell()
read_buffer = fptr.read(numbytes)
return cls(the_uuid, read_buffer, length=length, offset=offset)
# Map each box ID to the corresponding class. # Map each box ID to the corresponding class.