Merge branch 'issue145' into devel
This commit is contained in:
commit
f08b89fc64
3 changed files with 164 additions and 4 deletions
|
|
@ -1,6 +1,7 @@
|
|||
Feb 01, 2014 - Added read support for JPX FreeBox, NumberListBox, Data Reference
|
||||
Box. Palette box now a 2D numpy array instead of a list of 1D arrays.
|
||||
JP2 super box constructors now take optional box list argument.
|
||||
Feb 01, 2014 - Added read support for JPX free, number list, data reference,
|
||||
fragment table, and fragment list boxes. Palette box now a 2D numpy array
|
||||
instead of a list of 1D arrays. JP2 super box constructors now take
|
||||
optional box list argument.
|
||||
|
||||
Jan 28, 2014 - v0.5.10 Fixed bad warning when reader requirements box mask
|
||||
length is unsupported.
|
||||
|
|
|
|||
132
glymur/jp2box.py
132
glymur/jp2box.py
|
|
@ -835,7 +835,7 @@ class DataReferenceBox(Jp2kBox):
|
|||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
for box in enumerate(self.DR):
|
||||
for box in self.DR:
|
||||
msg += '\n ' + str(box)
|
||||
return msg
|
||||
|
||||
|
|
@ -984,6 +984,134 @@ class FileTypeBox(Jp2kBox):
|
|||
return box
|
||||
|
||||
|
||||
class FragmentListBox(Jp2kBox):
|
||||
"""Container for JPX fragment list box information.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
box_id : str
|
||||
4-character identifier for the box.
|
||||
length : int
|
||||
length of the box in bytes.
|
||||
offset : int
|
||||
offset of the box from the start of the file.
|
||||
longname : str
|
||||
more verbose description of the box.
|
||||
"""
|
||||
def __init__(self, fragment_offset, fragment_length, data_reference,
|
||||
length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='flst', longname='Fragment List')
|
||||
self.fragment_offset = fragment_offset
|
||||
self.fragment_length = fragment_length
|
||||
self.data_reference = data_reference
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.FragmentListBox()"
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
for j in range(len(self.fragment_offset)):
|
||||
msg += "\n Offset {0}: {1}"
|
||||
msg += "\n Fragment Length {2}: {3}"
|
||||
msg += "\n Data Reference {4}: {5}"
|
||||
msg = msg.format(j, self.fragment_offset[j],
|
||||
j, self.fragment_length[j],
|
||||
j, self.data_reference[j])
|
||||
|
||||
return msg
|
||||
|
||||
@staticmethod
|
||||
def parse(fptr, offset, length):
|
||||
"""Parse JPX free box.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
f : file
|
||||
Open file object.
|
||||
offset : int
|
||||
Start position of box in bytes.
|
||||
length : int
|
||||
Length of the box in bytes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
FreeBox instance
|
||||
"""
|
||||
read_buffer = fptr.read(2)
|
||||
nf, = struct.unpack('>H', read_buffer)
|
||||
|
||||
read_buffer = fptr.read(nf * 14)
|
||||
lst = struct.unpack('>' + 'QIH' * nf, read_buffer)
|
||||
frag_offset = lst[0::3]
|
||||
frag_len = lst[1::3]
|
||||
data_reference = lst[2::3]
|
||||
return FragmentListBox(frag_offset, frag_len, data_reference,
|
||||
length=length, offset=offset)
|
||||
|
||||
|
||||
class FragmentTableBox(Jp2kBox):
|
||||
"""Container for JPX fragment table box information.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
box_id : str
|
||||
4-character identifier for the box.
|
||||
length : int
|
||||
length of the box in bytes.
|
||||
offset : int
|
||||
offset of the box from the start of the file.
|
||||
longname : str
|
||||
more verbose description of the box.
|
||||
"""
|
||||
def __init__(self, length=0, offset=-1):
|
||||
Jp2kBox.__init__(self, box_id='ftbl', longname='Fragment Table')
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
msg = "glymur.jp2box.FragmentTableBox()"
|
||||
return msg
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
for box in self.box:
|
||||
boxstr = str(box)
|
||||
|
||||
# Add indentation.
|
||||
strs = [('\n ' + x) for x in boxstr.split('\n')]
|
||||
msg += ''.join(strs)
|
||||
return msg
|
||||
|
||||
@staticmethod
|
||||
def parse(fptr, offset, length):
|
||||
"""Parse JPX fragment table superbox box.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
f : file
|
||||
Open file object.
|
||||
offset : int
|
||||
Start position of box in bytes.
|
||||
length : int
|
||||
Length of the box in bytes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
FreeBox instance
|
||||
"""
|
||||
box = FragmentTableBox(length=length, offset=offset)
|
||||
|
||||
# The FragmentTable box is a superbox, so go ahead and parse its child
|
||||
# boxes.
|
||||
box.box = box.parse_superbox(fptr)
|
||||
|
||||
return box
|
||||
|
||||
|
||||
|
||||
class FreeBox(Jp2kBox):
|
||||
"""Container for JPX free box information.
|
||||
|
||||
|
|
@ -2999,6 +3127,8 @@ _BOX_WITH_ID = {
|
|||
'jplh': CompositingLayerHeaderBox,
|
||||
'jp2c': ContiguousCodestreamBox,
|
||||
'free': FreeBox,
|
||||
'flst': FragmentListBox,
|
||||
'ftbl': FragmentTableBox,
|
||||
'jp2h': JP2HeaderBox,
|
||||
'lbl ': LabelBox,
|
||||
'nlst': NumberListBox,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,35 @@ class TestJPXOther(unittest.TestCase):
|
|||
self.assertEqual(len(jpx.box[-1].DR), 2)
|
||||
|
||||
|
||||
def test_ftbl(self):
|
||||
"""Verify that we can interpret Fragment Table boxes."""
|
||||
# Copy the existing JPX file, add a fragment table box onto the end.
|
||||
with tempfile.NamedTemporaryFile(suffix='.jpx') as tfile:
|
||||
with open(self.jpxfile, 'rb') as ifile:
|
||||
tfile.write(ifile.read())
|
||||
write_buffer = struct.pack('>I4s', 32, b'ftbl')
|
||||
tfile.write(write_buffer)
|
||||
|
||||
# Just one fragment list box
|
||||
write_buffer = struct.pack('>I4s', 24, b'flst')
|
||||
tfile.write(write_buffer)
|
||||
|
||||
# Simple offset, length, reference
|
||||
write_buffer = struct.pack('>HQIH', 1, 4237, 170246, 3)
|
||||
tfile.write(write_buffer)
|
||||
|
||||
tfile.flush()
|
||||
|
||||
with self.assertWarns(UserWarning):
|
||||
jpx = Jp2k(tfile.name)
|
||||
|
||||
self.assertEqual(jpx.box[-1].box_id, 'ftbl')
|
||||
self.assertEqual(jpx.box[-1].box[0].box_id, 'flst')
|
||||
self.assertEqual(jpx.box[-1].box[0].fragment_offset, (4237,))
|
||||
self.assertEqual(jpx.box[-1].box[0].fragment_length, (170246,))
|
||||
self.assertEqual(jpx.box[-1].box[0].data_reference, (3,))
|
||||
|
||||
|
||||
def test_nlst(self):
|
||||
"""Verify that we can handle a free box."""
|
||||
with warnings.catch_warnings():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue