Added two negative tests for ChannelDefinition.
This commit is contained in:
parent
511f32f2ce
commit
2ea53f35cf
4 changed files with 71 additions and 32 deletions
|
|
@ -392,7 +392,7 @@ class _ICCProfile(object):
|
|||
self.header = header
|
||||
|
||||
|
||||
class ComponentDefinitionBox(Jp2kBox):
|
||||
class ChannelDefinitionBox(Jp2kBox):
|
||||
"""Container for component definition box information.
|
||||
|
||||
Attributes
|
||||
|
|
@ -405,27 +405,43 @@ class ComponentDefinitionBox(Jp2kBox):
|
|||
offset of the box from the start of the file.
|
||||
longname : str
|
||||
more verbose description of the box.
|
||||
component_number : int
|
||||
number of the component
|
||||
component_type : int
|
||||
type of the component
|
||||
index : int
|
||||
number of the channel
|
||||
channel_type : int
|
||||
type of the channel
|
||||
association : int
|
||||
number of the associated color
|
||||
index of the associated color
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
Jp2kBox.__init__(self, id='', longname='Component Definition')
|
||||
def __init__(self, index, channel_type, association, **kwargs):
|
||||
Jp2kBox.__init__(self, id='cdef', longname='Channel Definition')
|
||||
if len(index) != len(channel_type) or len(index) != len(association):
|
||||
msg = "Length of channel definition box inputs must be the same."
|
||||
raise IOError(msg)
|
||||
|
||||
# channel types must be one of 0, 1, 2, 65535
|
||||
if any(x not in [0, 1, 2, 65535] for x in channel_type):
|
||||
msg = "Channel types must be in the set of\n\n"
|
||||
msg += " 0 - colour image data for associated color\n"
|
||||
msg += " 1 - opacity\n"
|
||||
msg += " 2 - premultiplied opacity\n"
|
||||
msg += " 65535 - unspecified"
|
||||
raise IOError(msg)
|
||||
|
||||
self.index = index
|
||||
self.channel_type = channel_type
|
||||
self.association = association
|
||||
self.__dict__.update(**kwargs)
|
||||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
for j in range(len(self.association)):
|
||||
color_type_string = _color_type_map_display[self.component_type[j]]
|
||||
color_type_string = _color_type_map_display[self.channel_type[j]]
|
||||
if self.association[j] == 0:
|
||||
assn = 'whole image'
|
||||
else:
|
||||
assn = str(self.association[j])
|
||||
msg += '\n Component {0} ({1}) ==> ({2})'
|
||||
msg = msg.format(self.component_number[j], color_type_string, assn)
|
||||
msg += '\n Channel {0} ({1}) ==> ({2})'
|
||||
msg = msg.format(self.index[j], color_type_string, assn)
|
||||
return msg
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -456,17 +472,17 @@ class ComponentDefinitionBox(Jp2kBox):
|
|||
buffer = f.read(2)
|
||||
N, = struct.unpack('>H', buffer)
|
||||
|
||||
component_number = []
|
||||
component_type = []
|
||||
index = []
|
||||
chan_type = []
|
||||
association = []
|
||||
|
||||
buffer = f.read(N * 6)
|
||||
data = struct.unpack('>' + 'HHH' * N, buffer)
|
||||
kwargs['component_number'] = data[0:N * 6:3]
|
||||
kwargs['component_type'] = data[1:N * 6:3]
|
||||
kwargs['association'] = data[2:N * 6:3]
|
||||
index = data[0:N * 6:3]
|
||||
channel_type = data[1:N * 6:3]
|
||||
association = data[2:N * 6:3]
|
||||
|
||||
box = ComponentDefinitionBox(**kwargs)
|
||||
box = ChannelDefinitionBox(index, channel_type, association, **kwargs)
|
||||
return box
|
||||
|
||||
|
||||
|
|
@ -2426,7 +2442,7 @@ class _ExifInteroperabilityIfd(_Ifd):
|
|||
# Map each box ID to the corresponding class.
|
||||
_box_with_id = {
|
||||
'asoc': AssociationBox,
|
||||
'cdef': ComponentDefinitionBox,
|
||||
'cdef': ChannelDefinitionBox,
|
||||
'cmap': ComponentMappingBox,
|
||||
'colr': ColourSpecificationBox,
|
||||
'jP ': JPEG2000SignatureBox,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,34 @@ def load_tests(loader, tests, ignore):
|
|||
return tests
|
||||
|
||||
|
||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
||||
"Missing openjp2 library.")
|
||||
class TestChannelDefinition(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.jp2file = glymur.data.nemo()
|
||||
self.j2kfile = glymur.data.goodstuff()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_bad_type(self):
|
||||
# Channel types are limited to 0, 1, 2, 65535
|
||||
# Should reject if not all of index, channel_type, association the
|
||||
# same length.
|
||||
with self.assertRaises(IOError):
|
||||
box = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0, 3],
|
||||
association=[0, 1, 2])
|
||||
|
||||
def test_wrong_lengths(self):
|
||||
# Should reject if not all of index, channel_type, association the
|
||||
# same length.
|
||||
with self.assertRaises(IOError):
|
||||
box = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0],
|
||||
association=[0, 1, 2])
|
||||
|
||||
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
|
||||
"Missing openjp2 library.")
|
||||
class TestJp2Boxes(unittest.TestCase):
|
||||
|
|
@ -225,11 +253,6 @@ class TestJp2Boxes(unittest.TestCase):
|
|||
with self.assertRaises(NotImplementedError):
|
||||
j2k.wrap(tfile.name, boxes=boxes)
|
||||
|
||||
def test_default_component_definition(self):
|
||||
# Should be able to specify a component definition box in order to,
|
||||
# say, create an image with an alpha layer.
|
||||
self.assertTrue(False)
|
||||
|
||||
def test_first_2_boxes_not_jP_and_ftyp(self):
|
||||
j2k = Jp2k(self.raw_codestream)
|
||||
c = j2k.get_codestream()
|
||||
|
|
|
|||
|
|
@ -4170,8 +4170,8 @@ class TestSuiteDump(unittest.TestCase):
|
|||
|
||||
# Jp2 Header
|
||||
# Channel Definition
|
||||
self.assertEqual(jp2.box[2].box[2].component_number, (0, 1, 2))
|
||||
self.assertEqual(jp2.box[2].box[2].component_type, (0, 0, 0)) # color
|
||||
self.assertEqual(jp2.box[2].box[2].index, (0, 1, 2))
|
||||
self.assertEqual(jp2.box[2].box[2].channel_type, (0, 0, 0)) # color
|
||||
self.assertEqual(jp2.box[2].box[2].association, (3, 2, 1)) # reverse
|
||||
|
||||
def test_NR_file3_dump(self):
|
||||
|
|
@ -6706,8 +6706,8 @@ class TestSuiteDump(unittest.TestCase):
|
|||
|
||||
# Jp2 Header
|
||||
# Channel Definition
|
||||
self.assertEqual(jp2.box[2].box[2].component_number, (0, 1))
|
||||
self.assertEqual(jp2.box[2].box[2].component_type, (0, 1)) # opacity
|
||||
self.assertEqual(jp2.box[2].box[2].index, (0, 1))
|
||||
self.assertEqual(jp2.box[2].box[2].channel_type, (0, 1)) # opacity
|
||||
self.assertEqual(jp2.box[2].box[2].association, (0, 0)) # both main
|
||||
|
||||
c = jp2.box[3].main_header
|
||||
|
|
|
|||
|
|
@ -676,15 +676,15 @@ class TestPrinting(unittest.TestCase):
|
|||
|
||||
@unittest.skipIf(data_root is None,
|
||||
"OPJ_DATA_ROOT environment variable not set")
|
||||
def test_component_definition(self):
|
||||
def test_channel_definition(self):
|
||||
filename = os.path.join(data_root, 'input/conformance/file2.jp2')
|
||||
j = glymur.Jp2k(filename)
|
||||
print(j.box[2].box[2])
|
||||
actual = sys.stdout.getvalue().strip()
|
||||
lines = ['Component Definition Box (cdef) @ (81, 28)',
|
||||
' Component 0 (color) ==> (3)',
|
||||
' Component 1 (color) ==> (2)',
|
||||
' Component 2 (color) ==> (1)']
|
||||
lines = ['Channel Definition Box (cdef) @ (81, 28)',
|
||||
' Channel 0 (color) ==> (3)',
|
||||
' Channel 1 (color) ==> (2)',
|
||||
' Channel 2 (color) ==> (1)']
|
||||
expected = '\n'.join(lines)
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue