Checking for proper location of jp2h children. #157

Certain boxes can only reside in jp2h or jpch (which is not currently
supported for writing purposed).
This commit is contained in:
John Evans 2014-02-10 16:47:09 -05:00
commit 87cbf87ed7
2 changed files with 43 additions and 0 deletions

View file

@ -1198,6 +1198,22 @@ def _validate_jp2_box_sequence(boxes):
_jpx_compatibility(boxes, boxes[1].compatibility_list)
_check_for_singletons(boxes)
_check_top_level(boxes)
_check_jp2h_child_boxes(boxes, 'top-level')
JP2H_CHILDREN = set(['bpcc', 'cmap', 'ihdr', 'pclr'])
def _check_jp2h_child_boxes(boxes, parent_box_name):
"""Certain boxes can only reside in the JP2 header."""
box_ids = set([box.box_id for box in boxes])
intersection = box_ids.intersection(JP2H_CHILDREN)
if len(intersection) > 0 and parent_box_name != 'jp2h':
msg = "A '{0}' box can only be nested in a JP2 header box."
raise IOError(msg.format(list(intersection)[0]))
# Recursively check any contained superboxes.
for box in boxes:
if hasattr(box, 'box'):
_check_jp2h_child_boxes(box.box, box.box_id)
def _collect_box_count(boxes):
"""Count the occurences of each box type."""

View file

@ -679,6 +679,33 @@ class TestWrap(unittest.TestCase):
with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes)
def test_pclr_not_in_jp2h(self):
"""A palette box must reside in a JP2 header box."""
palette = np.array([[255, 0, 255], [0, 255, 0]], dtype=np.int32)
bps = (8, 8, 8)
signed = (True, False, True)
pclr = glymur.jp2box.PaletteBox(palette=palette, bits_per_component=bps,
signed=(True, False, True))
j2k = Jp2k(self.j2kfile)
codestream = j2k.get_codestream()
height = codestream.segment[1].ysiz
width = codestream.segment[1].xsiz
num_components = len(codestream.segment[1].xrsiz)
jp2b = JPEG2000SignatureBox()
ftyp = FileTypeBox()
jp2h = JP2HeaderBox()
jp2c = ContiguousCodestreamBox()
colr = ColourSpecificationBox(colorspace=glymur.core.SRGB)
ihdr = ImageHeaderBox(height=height, width=width,
num_components=num_components)
jp2h.box = [ihdr, colr]
boxes = [jp2b, ftyp, jp2h, jp2c, pclr]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes)
def test_jp2h_not_preceeding_jp2c(self):
"""jp2h must precede jp2c"""
j2k = Jp2k(self.j2kfile)