Added write support for Label box. #168

This commit is contained in:
jevans 2014-02-14 21:45:40 -05:00
commit 5ba6fd5d53
3 changed files with 49 additions and 4 deletions

View file

@ -2286,6 +2286,14 @@ class LabelBox(Jp2kBox):
msg = 'glymur.jp2box.LabelBox("{0}")'.format(self.label)
return msg
def write(self, fptr):
"""Write a Label box to file.
"""
length = 8 + len(self.label.encode())
fptr.write(struct.pack('>I', length))
fptr.write(self.box_id.encode())
fptr.write(self.label.encode())
@staticmethod
def parse(fptr, offset, length):
"""Parse Label box.

View file

@ -1119,6 +1119,7 @@ def _validate_jp2_box_sequence(boxes):
_validate_jp2h(boxes)
_validate_jp2c(boxes)
_validate_association(boxes)
_validate_label(boxes)
_validate_jpx_brand(boxes, boxes[1].brand)
_validate_jpx_compatibility(boxes, boxes[1].compatibility_list)
_validate_singletons(boxes)
@ -1304,6 +1305,21 @@ def _validate_jpx_compatibility(boxes, compatibility_list):
# Same set of checks on any child boxes.
_validate_jpx_compatibility(box.box, compatibility_list)
def _validate_label(boxes):
"""
Label boxes can only be inside association, codestream headers, or
compositing layer header boxes.
"""
for box in boxes:
if box.box_id != 'asoc':
if hasattr(box, 'box'):
for boxi in box.box:
if boxi.box_id == 'lbl ':
msg = "A label box cannot be nested inside a {0} box."
msg = msg.format(box.box_id)
raise IOError(msg)
# Same set of checks on any child boxes.
_validate_label(box.box)
def _validate_association(boxes):
"""

View file

@ -67,8 +67,8 @@ class TestJPXWrap(unittest.TestCase):
self.assertEqual(ET.tostring(jpx.box[-1].box[1].xml.getroot()),
b'<data>0</data>')
def test_association_box(self):
"""Wrap JP2 to JPX with asoc(nlst, xml)"""
def test_association_label_box(self):
"""Wrap JP2 to JPX with asoc, label, and nlst boxes"""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
@ -76,11 +76,13 @@ class TestJPXWrap(unittest.TestCase):
boxes[1].brand = 'jpx '
boxes[1].compatibility_list = ['jp2 ', 'jpx ']
label = 'this is a test'
lblb = glymur.jp2box.LabelBox(label)
numbers = (0, 1)
nlst = glymur.jp2box.NumberListBox(numbers)
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
xmlb = glymur.jp2box.XMLBox(xml=the_xml)
asoc = glymur.jp2box.AssociationBox([nlst, xmlb])
asoc = glymur.jp2box.AssociationBox([nlst, xmlb, lblb])
boxes.append(asoc)
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
@ -89,10 +91,12 @@ class TestJPXWrap(unittest.TestCase):
self.assertEqual(jpx.box[1].compatibility_list, ['jp2 ', 'jpx '])
self.assertEqual(jpx.box[-1].box_id, 'asoc')
self.assertEqual(jpx.box[-1].box[0].box_id, 'nlst')
self.assertEqual(jpx.box[-1].box[1].box_id, 'xml ')
self.assertEqual(jpx.box[-1].box[0].associations, numbers)
self.assertEqual(jpx.box[-1].box[1].box_id, 'xml ')
self.assertEqual(ET.tostring(jpx.box[-1].box[1].xml.getroot()),
b'<data>0</data>')
self.assertEqual(jpx.box[-1].box[2].box_id, 'lbl ')
self.assertEqual(jpx.box[-1].box[2].label, label)
def test_only_one_data_reference(self):
"""Data reference boxes cannot be inside a superbox ."""
@ -111,6 +115,23 @@ class TestJPXWrap(unittest.TestCase):
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
def test_lbl_at_top_level(self):
"""Label boxes can only be inside a asoc box ."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
flag = 0
version = (0, 0, 0)
url = 'file:////usr/local/bin'
lblb = glymur.jp2box.LabelBox('hi there')
# Put it inside the jp2 header box.
boxes[2].box.append(lblb)
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
def test_data_reference_not_at_top_level(self):
"""Data reference boxes cannot be inside a superbox ."""
jp2 = Jp2k(self.jp2file)