Added Colour group box support. #188

This commit is contained in:
jevans 2014-03-19 20:14:46 -04:00
commit cf4317df57
2 changed files with 113 additions and 0 deletions

View file

@ -754,6 +754,75 @@ class CodestreamHeaderBox(Jp2kBox):
return box return box
class ColourGroupBox(Jp2kBox):
"""Container for colour group 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.
box : list
List of boxes contained in this superbox.
"""
def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='cgrp', longname='Colour Group')
self.length = length
self.offset = offset
self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.ColourGroupBox(box={0})".format(self.box)
return msg
def __str__(self):
msg = self._str_superbox()
return msg
def _validate(self, writing=True):
"""Verify that the box obeys the specifications."""
if any([box.box_id != 'colr' for box in self.box]):
msg = "Colour group boxes can only contain colour specification "
msg += "boxes."
self._dispatch_validation_error(msg, writing=writing)
def write(self, fptr):
"""Write an association box to file.
"""
self._validate(writing=True)
self._write_superbox(fptr)
@staticmethod
def parse(fptr, offset, length):
"""Parse colour group box.
Parameters
----------
fptr : file
Open file object.
offset : int
Start position of box in bytes.
length : int
Length of the box in bytes.
Returns
-------
ColourGroupBox instance
"""
box = ColourGroupBox(length=length, offset=offset)
# The colour group box is a superbox, so go ahead and parse its
# child boxes.
box.box = box.parse_superbox(fptr)
return box
class CompositingLayerHeaderBox(Jp2kBox): class CompositingLayerHeaderBox(Jp2kBox):
"""Container for compositing layer header box information. """Container for compositing layer header box information.
@ -3101,6 +3170,7 @@ class UUIDBox(Jp2kBox):
_BOX_WITH_ID = { _BOX_WITH_ID = {
b'asoc': AssociationBox, b'asoc': AssociationBox,
b'cdef': ChannelDefinitionBox, b'cdef': ChannelDefinitionBox,
b'cgrp': ColourGroupBox,
b'cmap': ComponentMappingBox, b'cmap': ComponentMappingBox,
b'colr': ColourSpecificationBox, b'colr': ColourSpecificationBox,
b'dtbl': DataReferenceBox, b'dtbl': DataReferenceBox,

View file

@ -16,6 +16,7 @@ import glymur
from glymur import Jp2k from glymur import Jp2k
from glymur.jp2box import DataEntryURLBox, FileTypeBox, JPEG2000SignatureBox from glymur.jp2box import DataEntryURLBox, FileTypeBox, JPEG2000SignatureBox
from glymur.jp2box import DataReferenceBox, FragmentListBox, FragmentTableBox from glymur.jp2box import DataReferenceBox, FragmentListBox, FragmentTableBox
from glymur.jp2box import ColourSpecificationBox
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
class TestJPXWrap(unittest.TestCase): class TestJPXWrap(unittest.TestCase):
@ -109,6 +110,48 @@ class TestJPXWrap(unittest.TestCase):
with self.assertRaises(IOError): with self.assertRaises(IOError):
jp2.wrap(tfile.name, boxes=boxes) jp2.wrap(tfile.name, boxes=boxes)
def test_cgrp(self):
"""Write a color group box."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
# The ftyp box must be modified to jpx.
boxes[1].brand = 'jpx '
boxes[1].compatibility_list = ['jp2 ', 'jpxb']
colr_rgb = ColourSpecificationBox(colorspace=glymur.core.SRGB)
colr_gr = ColourSpecificationBox(colorspace=glymur.core.GREYSCALE)
box = [colr_rgb, colr_gr]
cgrp = glymur.jp2box.ColourGroupBox(box=box)
boxes.append(cgrp)
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
jpx = jp2.wrap(tfile.name, boxes=boxes)
self.assertEqual(jpx.box[-1].box_id, 'cgrp')
self.assertEqual(jpx.box[-1].box[0].box_id, 'colr')
self.assertEqual(jpx.box[-1].box[1].box_id, 'colr')
def test_cgrp_neg(self):
"""Can't write a cgrp with anything but colr sub boxes"""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
# The ftyp box must be modified to jpx.
boxes[1].brand = 'jpx '
boxes[1].compatibility_list = ['jp2 ', 'jpxb']
lblb = glymur.jp2box.LabelBox("Just a test")
box = [lblb]
cgrp = glymur.jp2box.ColourGroupBox(box=box)
boxes.append(cgrp)
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
def test_ftbl(self): def test_ftbl(self):
"""Write a fragment table box.""" """Write a fragment table box."""
# Add a negative test where offset < 0 # Add a negative test where offset < 0