From 01524dcb9930b7f42d8a73a48d5a4123387476ca Mon Sep 17 00:00:00 2001 From: John Evans Date: Tue, 18 Mar 2014 15:02:41 -0400 Subject: [PATCH] Hardened the handling of RSIZ and profiles. #196 Did not have an entry for RSIZ=4 ==> Profile 4 for cinema 4K. --- glymur/codestream.py | 20 +++++++++++++++++++- glymur/core.py | 6 ------ glymur/jp2k.py | 2 +- glymur/test/fixtures.py | 4 ++-- glymur/test/test_codestream.py | 13 ++++++++++++- glymur/test/test_printing.py | 13 +++++++++++-- 6 files changed, 45 insertions(+), 13 deletions(-) diff --git a/glymur/codestream.py b/glymur/codestream.py index 756277d..9751e14 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -28,7 +28,6 @@ import numpy as np from .core import LRCP, RLCP, RPCL, PCRL, CPRL from .core import WAVELET_XFORM_9X7_IRREVERSIBLE from .core import WAVELET_XFORM_5X3_REVERSIBLE -from .core import _CAPABILITIES_DISPLAY from .lib import openjp2 as opj2 class _keydefaultdict(collections.defaultdict): @@ -56,6 +55,22 @@ _WAVELET_TRANSFORM_DISPLAY = _keydefaultdict(_factory, { WAVELET_XFORM_9X7_IRREVERSIBLE: '9-7 irreversible', WAVELET_XFORM_5X3_REVERSIBLE: '5-3 reversible'}) +_NO_PROFILE = 0 +_PROFILE_0 = 1 +_PROFILE_1 = 2 +_PROFILE_3 = 3 +_PROFILE_4 = 4 + +_KNOWN_PROFILES = [_NO_PROFILE, _PROFILE_0, _PROFILE_1, _PROFILE_3, _PROFILE_4] + +# How to display the codestream profile. +_CAPABILITIES_DISPLAY = _keydefaultdict(_factory, + { _NO_PROFILE: 'no profile', + _PROFILE_0: '0', + _PROFILE_1: '1', + _PROFILE_3: '3', + _PROFILE_4: '4'} ) + # Need a catch-all list of valid markers. # See table A-1 in ISO/IEC FCD15444-1. _VALID_MARKERS = [0xff00, 0xff01, 0xfffe] @@ -672,6 +687,9 @@ class Codestream(object): data = struct.unpack('>HIIIIIIIIH', xy_buffer) rsiz = data[0] + if rsiz not in _KNOWN_PROFILES: + warnings.warn("Invalid profile: (Rsiz={0}).".format(rsiz)) + xysiz = (data[1], data[2]) xyosiz = (data[3], data[4]) xytsiz = (data[5], data[6]) diff --git a/glymur/core.py b/glymur/core.py index 95e1cbf..e593bd7 100644 --- a/glymur/core.py +++ b/glymur/core.py @@ -90,9 +90,3 @@ _COLORSPACE = {SRGB: {"R": 1, "G": 2, "B": 3}, E_SRGB: {"R": 1, "G": 2, "B": 3}, ROMM_RGB: {"R": 1, "G": 2, "B": 3}} -# How to display the codestream profile. -_CAPABILITIES_DISPLAY = { - 0: '2', - 1: '0', - 2: '1', - 3: '3'} diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 8f97e10..1ae7839 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -1095,7 +1095,7 @@ class Jp2k(Jp2kBox): >>> codestream = jp2.get_codestream() >>> print(codestream.segment[1]) SIZ marker segment @ (3233, 47) - Profile: 2 + Profile: no profile Reference Grid Height, Width: (1456 x 2592) Vertical, Horizontal Reference Grid Offset: (0 x 0) Reference Tile Height, Width: (1456 x 2592) diff --git a/glymur/test/fixtures.py b/glymur/test/fixtures.py index a1fa2ec..1ac2af9 100644 --- a/glymur/test/fixtures.py +++ b/glymur/test/fixtures.py @@ -412,7 +412,7 @@ Contiguous Codestream Box (jp2c) @ (3223, 1132296) Main header: SOC marker segment @ (3231, 0) SIZ marker segment @ (3233, 47) - Profile: 2 + Profile: no profile Reference Grid Height, Width: (1456 x 2592) Vertical, Horizontal Reference Grid Offset: (0 x 0) Reference Tile Height, Width: (1456 x 2592) @@ -477,7 +477,7 @@ Contiguous Codestream Box (jp2c) @ (3223, 1132296) Main header: SOC marker segment @ (3231, 0) SIZ marker segment @ (3233, 47) - Profile: 2 + Profile: no profile Reference Grid Height, Width: (1456 x 2592) Vertical, Horizontal Reference Grid Offset: (0 x 0) Reference Tile Height, Width: (1456 x 2592) diff --git a/glymur/test/test_codestream.py b/glymur/test/test_codestream.py index 9aba31c..8bac19c 100644 --- a/glymur/test/test_codestream.py +++ b/glymur/test/test_codestream.py @@ -51,8 +51,19 @@ class TestCodestreamOpjData(unittest.TestCase): def tearDown(self): pass + def test_bad_rsiz(self): + """Should warn if RSIZ is bad. Issue196""" + filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2') + if sys.hexversion < 0x03000000: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + j = Jp2k(filename) + else: + with self.assertWarns(UserWarning): + j = Jp2k(filename) + def test_bad_wavelet_transform(self): - """Should warn if wavelet transform is bad. Issue129""" + """Should warn if wavelet transform is bad. Issue195""" filename = opj_data_file('input/nonregression/edf_c2_10025.jp2') if sys.hexversion < 0x03000000: with warnings.catch_warnings(): diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index df73f3f..51af6e0 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -349,7 +349,7 @@ class TestPrinting(unittest.TestCase): actual = fake_out.getvalue().strip() lines = ['SIZ marker segment @ (3233, 47)', - ' Profile: 2', + ' Profile: no profile', ' Reference Grid Height, Width: (1456 x 2592)', ' Vertical, Horizontal Reference Grid Offset: (0 x 0)', ' Reference Tile Height, Width: (1456 x 2592)', @@ -422,7 +422,7 @@ class TestPrinting(unittest.TestCase): lst = ['Codestream:', ' SOC marker segment @ (3231, 0)', ' SIZ marker segment @ (3233, 47)', - ' Profile: 2', + ' Profile: no profile', ' Reference Grid Height, Width: (1456 x 2592)', ' Vertical, Horizontal Reference Grid Offset: (0 x 0)', ' Reference Tile Height, Width: (1456 x 2592)', @@ -653,6 +653,15 @@ class TestPrintingOpjDataRoot(unittest.TestCase): def tearDown(self): pass + def test_bad_rsiz(self): + """Should still be able to print if rsiz is bad, issue196""" + filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2') + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + j = Jp2k(filename) + with patch('sys.stdout', new=StringIO()) as fake_out: + print(j) + def test_bad_wavelet_transform(self): """Should still be able to print if wavelet xform is bad, issue195""" filename = opj_data_file('input/nonregression/edf_c2_10025.jp2')