Added validation step for jp2 brand / any icc profile mismatch. #77
text_GBR.jp2 also shows this issue.
This commit is contained in:
parent
83b53c5f9b
commit
de7e6e1f0f
5 changed files with 55 additions and 9 deletions
|
|
@ -6,7 +6,7 @@ from .jp2k import Jp2k
|
|||
from .jp2dump import jp2dump
|
||||
|
||||
from . import data
|
||||
from . import test
|
||||
#from . import test
|
||||
|
||||
|
||||
def runtests():
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from .codestream import Codestream
|
|||
from .core import SRGB
|
||||
from .core import GREYSCALE
|
||||
from .core import PROGRESSION_ORDER
|
||||
from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE
|
||||
from .jp2box import Jp2kBox
|
||||
from .jp2box import JPEG2000SignatureBox
|
||||
from .jp2box import FileTypeBox
|
||||
|
|
@ -159,6 +160,23 @@ class Jp2k(Jp2kBox):
|
|||
# boxes) here.
|
||||
fptr.seek(0)
|
||||
self.box = self.parse_superbox(fptr)
|
||||
self._validate()
|
||||
|
||||
def _validate(self):
|
||||
"""Validate the JPEG 2000 outermost superbox.
|
||||
"""
|
||||
# A jp2-branded file cannot contain an "any ICC profile
|
||||
ftyp = self.box[1]
|
||||
jp2h = [box for box in self.box if box.box_id == 'jp2h'][0]
|
||||
colr = [box for box in jp2h.box if box.box_id == 'colr'][0]
|
||||
if (((ftyp.brand == 'jp2 ') and
|
||||
(colr.method not in (ENUMERATED_COLORSPACE,
|
||||
RESTRICTED_ICC_PROFILE)))):
|
||||
msg = "Color Specification box method must specify either an "
|
||||
msg += "enumerated colorspace or a restricted ICC profile if the "
|
||||
msg += "file type box brand is 'jp2 '."
|
||||
warnings.warn(msg)
|
||||
|
||||
|
||||
# pylint: disable-msg=W0221
|
||||
def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None,
|
||||
|
|
|
|||
|
|
@ -81,5 +81,16 @@ class TestSuite(unittest.TestCase):
|
|||
#with self.assertRaises(OSError):
|
||||
# j2k.read(rlevel=-1)
|
||||
|
||||
def test_jp2_brand_vs_any_icc_profile(self):
|
||||
# If 'jp2 ', then the method cannot be any icc profile.
|
||||
jfile = os.path.join(data_root,
|
||||
'jp2k-test/icc/balloon_eciRGBv2_ps_adobeplugin.jpf')
|
||||
with self.assertWarns(UserWarning):
|
||||
j2k = Jp2k(jfile)
|
||||
|
||||
# Should error out, it does not.
|
||||
#with self.assertRaises(OSError):
|
||||
# j2k.read(rlevel=-1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -990,7 +990,11 @@ class TestSuite(unittest.TestCase):
|
|||
def test_NR_DEC_text_GBR_jp2_29_decode(self):
|
||||
jfile = os.path.join(data_root,
|
||||
'input/nonregression/text_GBR.jp2')
|
||||
data = Jp2k(jfile).read()
|
||||
with warnings.catch_warnings():
|
||||
# brand is 'jp2 ', but has any icc profile.
|
||||
warnings.simplefilter("ignore")
|
||||
jp2 = Jp2k(jfile)
|
||||
data = jp2.read()
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_NR_DEC_pacs_ge_j2k_30_decode(self):
|
||||
|
|
@ -7260,7 +7264,10 @@ class TestSuiteDump(unittest.TestCase):
|
|||
def test_NR_text_GBR_dump(self):
|
||||
jfile = os.path.join(data_root,
|
||||
'input/nonregression/text_GBR.jp2')
|
||||
jp2 = Jp2k(jfile)
|
||||
with warnings.catch_warnings():
|
||||
# brand is 'jp2 ', but has any icc profile.
|
||||
warnings.simplefilter("ignore")
|
||||
jp2 = Jp2k(jfile)
|
||||
|
||||
ids = [box.box_id for box in jp2.box]
|
||||
lst = ['jP ', 'ftyp', 'rreq', 'jp2h',
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import pkg_resources
|
|||
import struct
|
||||
import sys
|
||||
import tempfile
|
||||
import warnings
|
||||
|
||||
if sys.hexversion < 0x02070000:
|
||||
import unittest2 as unittest
|
||||
|
|
@ -277,9 +278,12 @@ class TestPrinting(unittest.TestCase):
|
|||
"OPJ_DATA_ROOT environment variable not set")
|
||||
def test_icc_profile(self):
|
||||
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
||||
j = glymur.Jp2k(filename)
|
||||
with warnings.catch_warnings():
|
||||
# brand is 'jp2 ', but has any icc profile.
|
||||
warnings.simplefilter("ignore")
|
||||
jp2 = Jp2k(filename)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
print(j.box[3].box[1])
|
||||
print(jp2.box[3].box[1])
|
||||
actual = fake_out.getvalue().strip()
|
||||
lin27 = ["Colour Specification Box (colr) @ (179, 1339)",
|
||||
" Method: any ICC profile",
|
||||
|
|
@ -902,10 +906,13 @@ class TestPrinting(unittest.TestCase):
|
|||
# ICC profiles may be used in JP2, but the approximation field should
|
||||
# be zero unless we have jpx. This file does both.
|
||||
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
||||
j = glymur.Jp2k(filename)
|
||||
with warnings.catch_warnings():
|
||||
# brand is 'jp2 ', but has any icc profile.
|
||||
warnings.simplefilter("ignore")
|
||||
jp2 = Jp2k(filename)
|
||||
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
print(j.box[3].box[1])
|
||||
print(jp2.box[3].box[1])
|
||||
actual = fake_out.getvalue().strip()
|
||||
lines = ["Colour Specification Box (colr) @ (179, 1339)",
|
||||
" Method: any ICC profile",
|
||||
|
|
@ -942,10 +949,13 @@ class TestPrinting(unittest.TestCase):
|
|||
def test_uuid(self):
|
||||
# UUID box
|
||||
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
||||
j = glymur.Jp2k(filename)
|
||||
with warnings.catch_warnings():
|
||||
# brand is 'jp2 ', but has any icc profile.
|
||||
warnings.simplefilter("ignore")
|
||||
jp2 = Jp2k(filename)
|
||||
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
print(j.box[4])
|
||||
print(jp2.box[4])
|
||||
actual = fake_out.getvalue().strip()
|
||||
lines = ['UUID Box (uuid) @ (1544, 25)',
|
||||
' UUID: 3a0d0218-0ae9-4115-b376-4bca41ce0e71',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue