More negative tests. #175
This commit is contained in:
parent
4276a978ea
commit
4caa13a955
3 changed files with 69 additions and 12 deletions
|
|
@ -29,6 +29,7 @@ import numpy as np
|
||||||
from .codestream import Codestream
|
from .codestream import Codestream
|
||||||
from .core import _COLORSPACE_MAP_DISPLAY
|
from .core import _COLORSPACE_MAP_DISPLAY
|
||||||
from .core import _COLOR_TYPE_MAP_DISPLAY
|
from .core import _COLOR_TYPE_MAP_DISPLAY
|
||||||
|
from .core import SRGB, GREYSCALE, YCC
|
||||||
from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE
|
from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE
|
||||||
from .core import ANY_ICC_PROFILE, VENDOR_COLOR_METHOD
|
from .core import ANY_ICC_PROFILE, VENDOR_COLOR_METHOD
|
||||||
from .core import _pretty_print_xml
|
from .core import _pretty_print_xml
|
||||||
|
|
@ -270,13 +271,6 @@ class ColourSpecificationBox(Jp2kBox):
|
||||||
approximation=0, colorspace=None, icc_profile=None,
|
approximation=0, colorspace=None, icc_profile=None,
|
||||||
length=0, offset=-1):
|
length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='colr', longname='Colour Specification')
|
Jp2kBox.__init__(self, box_id='colr', 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.method = method
|
self.method = method
|
||||||
self.precedence = precedence
|
self.precedence = precedence
|
||||||
self.approximation = approximation
|
self.approximation = approximation
|
||||||
|
|
@ -284,6 +278,33 @@ class ColourSpecificationBox(Jp2kBox):
|
||||||
self.icc_profile = icc_profile
|
self.icc_profile = icc_profile
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
self._validate()
|
||||||
|
|
||||||
|
def _validate(self):
|
||||||
|
"""Verify that the box obeys the specifications."""
|
||||||
|
if self.colorspace is not None and self.icc_profile is not None:
|
||||||
|
raise IOError("colorspace and icc_profile cannot both be set.")
|
||||||
|
if self.method not in (1, 2, 3, 4):
|
||||||
|
raise IOError("Invalid method.")
|
||||||
|
if self.approximation not in (0, 1, 2, 3, 4):
|
||||||
|
raise IOError("Invalid approximation.")
|
||||||
|
|
||||||
|
def _write_validate(self):
|
||||||
|
"""In addition to constructor validation steps, run validation steps
|
||||||
|
for writing."""
|
||||||
|
if self.colorspace is None:
|
||||||
|
msg = "Writing Colour Specification boxes without enumerated "
|
||||||
|
msg += "colorspaces is not supported at this time."
|
||||||
|
raise IOError(msg)
|
||||||
|
|
||||||
|
if self.icc_profile is None:
|
||||||
|
if self.colorspace not in [SRGB, GREYSCALE, YCC]:
|
||||||
|
msg = "Colorspace should correspond to one of SRGB, GREYSCALE, "
|
||||||
|
msg += "or YCC."
|
||||||
|
raise IOError(msg)
|
||||||
|
|
||||||
|
self._validate()
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.ColourSpecificationBox("
|
msg = "glymur.jp2box.ColourSpecificationBox("
|
||||||
|
|
@ -327,10 +348,7 @@ class ColourSpecificationBox(Jp2kBox):
|
||||||
def write(self, fptr):
|
def write(self, fptr):
|
||||||
"""Write an Colour Specification box to file.
|
"""Write an Colour Specification box to file.
|
||||||
"""
|
"""
|
||||||
if self.colorspace is None:
|
self._write_validate()
|
||||||
msg = "Writing Colour Specification boxes without enumerated "
|
|
||||||
msg += "colorspaces is not supported at this time."
|
|
||||||
raise NotImplementedError(msg)
|
|
||||||
length = 15 if self.icc_profile is None else 11 + len(self.icc_profile)
|
length = 15 if self.icc_profile is None else 11 + len(self.icc_profile)
|
||||||
fptr.write(struct.pack('>I', length))
|
fptr.write(struct.pack('>I', length))
|
||||||
fptr.write('colr'.encode())
|
fptr.write('colr'.encode())
|
||||||
|
|
@ -923,10 +941,20 @@ class DataReferenceBox(Jp2kBox):
|
||||||
self.DR = data_entry_url_boxes
|
self.DR = data_entry_url_boxes
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
self._validate()
|
||||||
|
|
||||||
|
def _validate(self):
|
||||||
|
"""Verify that the box obeys the specifications."""
|
||||||
|
for box in self.DR:
|
||||||
|
if box.box_id != 'url ':
|
||||||
|
msg = 'All child boxes of a data reference box must be data '
|
||||||
|
msg += 'entry URL boxes.'
|
||||||
|
raise IOError(msg)
|
||||||
|
|
||||||
def write(self, fptr):
|
def write(self, fptr):
|
||||||
"""Write a Data Reference box to file.
|
"""Write a Data Reference box to file.
|
||||||
"""
|
"""
|
||||||
|
self._validate()
|
||||||
|
|
||||||
# Very similar to the say a superbox is written.
|
# Very similar to the say a superbox is written.
|
||||||
orig_pos = fptr.tell()
|
orig_pos = fptr.tell()
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,7 @@ class TestColourSpecificationBox(unittest.TestCase):
|
||||||
boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
|
||||||
boxes[2].box = [self.ihdr, ColourSpecificationBox(colorspace=None)]
|
boxes[2].box = [self.ihdr, ColourSpecificationBox(colorspace=None)]
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||||
with self.assertRaises(NotImplementedError):
|
with self.assertRaises(IOError):
|
||||||
j2k.wrap(tfile.name, boxes=boxes)
|
j2k.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||||
|
|
@ -440,6 +440,16 @@ class TestColourSpecificationBox(unittest.TestCase):
|
||||||
glymur.jp2box.ColourSpecificationBox(colorspace=colorspace,
|
glymur.jp2box.ColourSpecificationBox(colorspace=colorspace,
|
||||||
approximation=approx)
|
approximation=approx)
|
||||||
|
|
||||||
|
def test_colr_with_bad_color(self):
|
||||||
|
"""colr must have a valid color, strange as though that may sound."""
|
||||||
|
colorspace = -1
|
||||||
|
approx = 0
|
||||||
|
colr = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace,
|
||||||
|
approximation=approx)
|
||||||
|
with tempfile.TemporaryFile() as tfile:
|
||||||
|
with self.assertRaises(IOError):
|
||||||
|
colr.write(tfile)
|
||||||
|
|
||||||
|
|
||||||
class TestAppend(unittest.TestCase):
|
class TestAppend(unittest.TestCase):
|
||||||
"""Tests for append method."""
|
"""Tests for append method."""
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,25 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
self.assertEqual(jpx.box[-1].box_id, 'dtbl')
|
self.assertEqual(jpx.box[-1].box_id, 'dtbl')
|
||||||
self.assertEqual(len(jpx.box[-1].box), 0)
|
self.assertEqual(len(jpx.box[-1].box), 0)
|
||||||
|
|
||||||
|
def test_deurl_child_of_dtbl(self):
|
||||||
|
"""Data reference boxes can only contain data entry url boxes."""
|
||||||
|
jp2 = Jp2k(self.jp2file)
|
||||||
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
|
||||||
|
ftyp = glymur.jp2box.FileTypeBox()
|
||||||
|
with self.assertRaises(IOError):
|
||||||
|
dref = glymur.jp2box.DataReferenceBox([ftyp])
|
||||||
|
|
||||||
|
# Try to get around it by appending the ftyp box after creation.
|
||||||
|
dref = glymur.jp2box.DataReferenceBox()
|
||||||
|
dref.DR.append(ftyp)
|
||||||
|
|
||||||
|
boxes.append(dref)
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
|
with self.assertRaises(IOError):
|
||||||
|
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_only_one_data_reference(self):
|
def test_only_one_data_reference(self):
|
||||||
"""Data reference boxes cannot be inside a superbox ."""
|
"""Data reference boxes cannot be inside a superbox ."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue