Added write support for Label box. #168
This commit is contained in:
parent
f264bb00f3
commit
5ba6fd5d53
3 changed files with 49 additions and 4 deletions
|
|
@ -2286,6 +2286,14 @@ class LabelBox(Jp2kBox):
|
||||||
msg = 'glymur.jp2box.LabelBox("{0}")'.format(self.label)
|
msg = 'glymur.jp2box.LabelBox("{0}")'.format(self.label)
|
||||||
return msg
|
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
|
@staticmethod
|
||||||
def parse(fptr, offset, length):
|
def parse(fptr, offset, length):
|
||||||
"""Parse Label box.
|
"""Parse Label box.
|
||||||
|
|
|
||||||
|
|
@ -1119,6 +1119,7 @@ def _validate_jp2_box_sequence(boxes):
|
||||||
_validate_jp2h(boxes)
|
_validate_jp2h(boxes)
|
||||||
_validate_jp2c(boxes)
|
_validate_jp2c(boxes)
|
||||||
_validate_association(boxes)
|
_validate_association(boxes)
|
||||||
|
_validate_label(boxes)
|
||||||
_validate_jpx_brand(boxes, boxes[1].brand)
|
_validate_jpx_brand(boxes, boxes[1].brand)
|
||||||
_validate_jpx_compatibility(boxes, boxes[1].compatibility_list)
|
_validate_jpx_compatibility(boxes, boxes[1].compatibility_list)
|
||||||
_validate_singletons(boxes)
|
_validate_singletons(boxes)
|
||||||
|
|
@ -1304,6 +1305,21 @@ def _validate_jpx_compatibility(boxes, compatibility_list):
|
||||||
# Same set of checks on any child boxes.
|
# Same set of checks on any child boxes.
|
||||||
_validate_jpx_compatibility(box.box, compatibility_list)
|
_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):
|
def _validate_association(boxes):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,8 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
self.assertEqual(ET.tostring(jpx.box[-1].box[1].xml.getroot()),
|
self.assertEqual(ET.tostring(jpx.box[-1].box[1].xml.getroot()),
|
||||||
b'<data>0</data>')
|
b'<data>0</data>')
|
||||||
|
|
||||||
def test_association_box(self):
|
def test_association_label_box(self):
|
||||||
"""Wrap JP2 to JPX with asoc(nlst, xml)"""
|
"""Wrap JP2 to JPX with asoc, label, and nlst boxes"""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
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].brand = 'jpx '
|
||||||
boxes[1].compatibility_list = ['jp2 ', 'jpx ']
|
boxes[1].compatibility_list = ['jp2 ', 'jpx ']
|
||||||
|
|
||||||
|
label = 'this is a test'
|
||||||
|
lblb = glymur.jp2box.LabelBox(label)
|
||||||
numbers = (0, 1)
|
numbers = (0, 1)
|
||||||
nlst = glymur.jp2box.NumberListBox(numbers)
|
nlst = glymur.jp2box.NumberListBox(numbers)
|
||||||
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
|
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
|
||||||
xmlb = glymur.jp2box.XMLBox(xml=the_xml)
|
xmlb = glymur.jp2box.XMLBox(xml=the_xml)
|
||||||
asoc = glymur.jp2box.AssociationBox([nlst, xmlb])
|
asoc = glymur.jp2box.AssociationBox([nlst, xmlb, lblb])
|
||||||
boxes.append(asoc)
|
boxes.append(asoc)
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
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].compatibility_list, ['jp2 ', 'jpx '])
|
||||||
self.assertEqual(jpx.box[-1].box_id, 'asoc')
|
self.assertEqual(jpx.box[-1].box_id, 'asoc')
|
||||||
self.assertEqual(jpx.box[-1].box[0].box_id, 'nlst')
|
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[0].associations, numbers)
|
||||||
|
self.assertEqual(jpx.box[-1].box[1].box_id, 'xml ')
|
||||||
self.assertEqual(ET.tostring(jpx.box[-1].box[1].xml.getroot()),
|
self.assertEqual(ET.tostring(jpx.box[-1].box[1].xml.getroot()),
|
||||||
b'<data>0</data>')
|
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):
|
def test_only_one_data_reference(self):
|
||||||
"""Data reference boxes cannot be inside a superbox ."""
|
"""Data reference boxes cannot be inside a superbox ."""
|
||||||
|
|
@ -111,6 +115,23 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
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):
|
def test_data_reference_not_at_top_level(self):
|
||||||
"""Data reference boxes cannot be inside a superbox ."""
|
"""Data reference boxes cannot be inside a superbox ."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue