Added Colour group box support. #188
This commit is contained in:
parent
8a448600d2
commit
cf4317df57
2 changed files with 113 additions and 0 deletions
|
|
@ -754,6 +754,75 @@ class CodestreamHeaderBox(Jp2kBox):
|
|||
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):
|
||||
"""Container for compositing layer header box information.
|
||||
|
||||
|
|
@ -3101,6 +3170,7 @@ class UUIDBox(Jp2kBox):
|
|||
_BOX_WITH_ID = {
|
||||
b'asoc': AssociationBox,
|
||||
b'cdef': ChannelDefinitionBox,
|
||||
b'cgrp': ColourGroupBox,
|
||||
b'cmap': ComponentMappingBox,
|
||||
b'colr': ColourSpecificationBox,
|
||||
b'dtbl': DataReferenceBox,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import glymur
|
|||
from glymur import Jp2k
|
||||
from glymur.jp2box import DataEntryURLBox, FileTypeBox, JPEG2000SignatureBox
|
||||
from glymur.jp2box import DataReferenceBox, FragmentListBox, FragmentTableBox
|
||||
from glymur.jp2box import ColourSpecificationBox
|
||||
|
||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||
class TestJPXWrap(unittest.TestCase):
|
||||
|
|
@ -109,6 +110,48 @@ class TestJPXWrap(unittest.TestCase):
|
|||
with self.assertRaises(IOError):
|
||||
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):
|
||||
"""Write a fragment table box."""
|
||||
# Add a negative test where offset < 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue