diff --git a/glymur/jp2box.py b/glymur/jp2box.py index 401106f..ff0ce85 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -31,6 +31,7 @@ from .core import _colorspace_map_display from .core import _color_type_map_display from .core import _method_display from .core import _reader_requirements_display +from .core import * class Jp2kBox(object): @@ -164,9 +165,22 @@ class ColourSpecificationBox(Jp2kBox): ICC profile header according to ICC profile specification. If colorspace is not None, then icc_profile must be empty. """ - def __init__(self, **kwargs): + def __init__(self, method=ENUMERATED_COLORSPACE, precedence=0, + approximation=1, colorspace=None, icc_profile=None, **kwargs): Jp2kBox.__init__(self, id='', longname='Colour Specification') + + if colorspace is not None and icc_profile is not None: + raise IOError("colorspace and icc_profile cannot both be set.") + if method not in (1, 2, 3, 4): + raise IOError("Invalid method.") + if approximation not in (0, 1, 2, 3, 4): + raise IOError("Invalid approximation.") self.__dict__.update(**kwargs) + self.method = method + self.precedence = precedence + self.approximation = approximation + self.colorspace = colorspace + self.icc_profile = icc_profile def __str__(self): msg = Jp2kBox.__str__(self) @@ -686,29 +700,30 @@ class ImageHeaderBox(Jp2kBox): False if the image components are unsigned. compression : int The compression type, should be 7 if JP2. - cspace_unknown : bool + colorspace_unknown : bool false if the color space is known and correctly specified. ip_provided : bool false if the file does not contain intellectual propery rights information. """ - def __init__(self, *pargs, **kwargs): + def __init__(self, height, width, num_components=1, signed=False, + bits_per_component=8, compression=7, colorspace_unknown=False, + ip_provided=False, **kwargs): """ Examples -------- >>> import glymur - >>> box = glymur.jp2box.ImageHeaderBox([512, 256, 3]) + >>> box = glymur.jp2box.ImageHeaderBox(height=512, width=256) """ Jp2kBox.__init__(self, id='ihdr', longname='Image Header') + self.height = height + self.width = width + self.num_components = num_components + self.signed = signed + self.bits_per_component = bits_per_component + self.compression = compression + self.colorspace_unknown = colorspace_unknown + self.ip_provided = False self.__dict__.update(**kwargs) - if len(pargs) == 1: - self.height = pargs[0][0] - self.width = pargs[0][1] - self.num_components = pargs[0][2] - self.bits_per_component = 8 - self.signed = False - self.compression = 7 - self.cspace_unknown = False - self.ip_provided = False def __str__(self): msg = Jp2kBox.__str__(self) @@ -723,7 +738,7 @@ class ImageHeaderBox(Jp2kBox): self.bits_per_component, self.signed, 'wavelet' if self.compression == 7 else 'unknown', - self.cspace_unknown) + self.colorspace_unknown) return msg @staticmethod @@ -752,16 +767,16 @@ class ImageHeaderBox(Jp2kBox): # Read the box information buffer = f.read(14) params = struct.unpack('>IIHBBBB', buffer) - kwargs['height'] = params[0] - kwargs['width'] = params[1] + height = params[0] + width = params[1] kwargs['num_components'] = params[2] kwargs['bits_per_component'] = (params[3] & 0x7f) + 1 kwargs['signed'] = (params[3] & 0x80) > 1 kwargs['compression'] = params[4] - kwargs['cspace_unknown'] = True if params[5] else False + kwargs['colorspace_unknown'] = True if params[5] else False kwargs['ip_provided'] = True if params[6] else False - box = ImageHeaderBox(**kwargs) + box = ImageHeaderBox(height, width, **kwargs) return box diff --git a/glymur/test/test_jp2box.py b/glymur/test/test_jp2box.py index 8aa57c2..6a68cc5 100644 --- a/glymur/test/test_jp2box.py +++ b/glymur/test/test_jp2box.py @@ -36,13 +36,41 @@ class TestJp2Boxes(unittest.TestCase): def test_default_ImageHeaderBox(self): # Should be able to instantiate an image header box. - b = glymur.jp2box.ImageHeaderBox([512, 256, 3]) + b = glymur.jp2box.ImageHeaderBox(height=512, width=256, + num_components=3) self.assertEqual(b.height, 512) self.assertEqual(b.width, 256) self.assertEqual(b.num_components, 3) self.assertEqual(b.bits_per_component, 8) self.assertFalse(b.signed) - self.assertFalse(b.cspace_unknown) + self.assertFalse(b.colorspace_unknown) + + def test_default_ColourSpecificationBox(self): + b = glymur.jp2box.ColourSpecificationBox(colorspace=glymur.core.SRGB) + self.assertEqual(b.method, glymur.core.ENUMERATED_COLORSPACE) + self.assertEqual(b.precedence, 0) + self.assertEqual(b.approximation, 1) + self.assertEqual(b.colorspace, glymur.core.SRGB) + self.assertIsNone(b.icc_profile) + + def test_ColourSpecificationBox_with_colorspace_and_icc(self): + # Colour specification boxes can't have both. + with self.assertRaises(IOError): + colorspace = glymur.core.SRGB + icc_profile = b'\x01\x02\x03\x04' + b = glymur.jp2box.ColourSpecificationBox(colorspace, icc_profile) + + def test_ColourSpecificationBox_with_bad_method(self): + colorspace = glymur.core.SRGB + method = -1 + with self.assertRaises(IOError): + b = glymur.jp2box.ColourSpecificationBox(colorspace, method) + + def test_ColourSpecificationBox_with_bad_approximation(self): + colorspace = glymur.core.SRGB + approximation = -1 + with self.assertRaises(IOError): + b = glymur.jp2box.ColourSpecificationBox(colorspace, approximation) if __name__ == "__main__": diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 3c25cca..b15ca35 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -213,7 +213,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2k.box[2].box[0].signed, False) self.assertEqual(jp2k.box[2].box[0].compression, 7) - self.assertEqual(jp2k.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2k.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2k.box[2].box[0].ip_provided, False) self.assertEqual(jp2k.box[2].box[1].id, 'colr') diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 9a7efde..0566d6c 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -4116,7 +4116,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 8) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -4158,7 +4158,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -4204,7 +4204,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -4250,7 +4250,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -4292,7 +4292,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].num_components, 3) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -4338,7 +4338,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 12) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -4387,7 +4387,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 16) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -4436,7 +4436,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -4488,7 +4488,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Palette box. @@ -5985,7 +5985,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -6118,7 +6118,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -6246,7 +6246,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -6386,7 +6386,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 8) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -6497,7 +6497,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -6597,7 +6597,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 8) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -6694,7 +6694,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -6813,7 +6813,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 1) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -6927,7 +6927,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 4) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header @@ -7035,7 +7035,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -7142,7 +7142,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -7241,7 +7241,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header @@ -7343,7 +7343,7 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(jp2.box[3].box[0].bits_per_component, 8) self.assertEqual(jp2.box[3].box[0].signed, False) self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[3].box[0].cspace_unknown, True) + self.assertEqual(jp2.box[3].box[0].colorspace_unknown, True) self.assertEqual(jp2.box[3].box[0].ip_provided, False) # Jp2 Header diff --git a/glymur/test/test_opj_suite_write.py b/glymur/test/test_opj_suite_write.py index 0526fc3..fc86768 100644 --- a/glymur/test/test_opj_suite_write.py +++ b/glymur/test/test_opj_suite_write.py @@ -686,7 +686,7 @@ class TestSuiteWrite(unittest.TestCase): self.assertEqual(jp2.box[2].box[0].bits_per_component, 8) self.assertEqual(jp2.box[2].box[0].signed, False) self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet - self.assertEqual(jp2.box[2].box[0].cspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False) self.assertEqual(jp2.box[2].box[0].ip_provided, False) # Jp2 Header