From 61126d6a8b13f68e4b0102aeb6b1c21287aa551e Mon Sep 17 00:00:00 2001 From: John Evans Date: Sun, 17 Aug 2014 19:03:29 -0400 Subject: [PATCH 1/6] Using 3.x warning infrastructure exclusively. --- glymur/test/test_codestream_warnings.py | 31 +++++++------------------ 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/glymur/test/test_codestream_warnings.py b/glymur/test/test_codestream_warnings.py index 8b50bf2..7fc79f6 100644 --- a/glymur/test/test_codestream_warnings.py +++ b/glymur/test/test_codestream_warnings.py @@ -20,7 +20,8 @@ import glymur from .fixtures import opj_data_file, OPJ_DATA_ROOT -@unittest.skipIf(sys.platform.startswith('linux'), 'warnings failing on linux') +@unittest.skipIf(sys.hexversion < 0x03030000, + "assertWarn methods introduced in 3.x") @unittest.skipIf(OPJ_DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") class TestCodestreamOpjDataWarnings(unittest.TestCase): @@ -29,39 +30,26 @@ class TestCodestreamOpjDataWarnings(unittest.TestCase): def test_bad_rsiz(self): """Should warn if RSIZ is bad. Issue196""" filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with self.assertWarnsRegex(UserWarning, 'Invalid profile'): j = Jp2k(filename) - self.assertEqual(len(w), 3) - self.assertTrue(issubclass(w[0].category, UserWarning)) - self.assertTrue('Invalid profile' in str(w[0].message)) def test_bad_wavelet_transform(self): """Should warn if wavelet transform is bad. Issue195""" filename = opj_data_file('input/nonregression/edf_c2_10025.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with self.assertWarnsRegex(UserWarning, 'Invalid wavelet transform'): j = Jp2k(filename) - self.assertTrue(issubclass(w[0].category, UserWarning)) - self.assertTrue('Invalid wavelet transform' in str(w[0].message)) def test_invalid_progression_order(self): """Should still be able to parse even if prog order is invalid.""" jfile = opj_data_file('input/nonregression/2977.pdf.asan.67.2198.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with self.assertWarnsRegex(UserWarning, 'Invalid progression order'): Jp2k(jfile) - self.assertTrue(issubclass(w[0].category, UserWarning)) - self.assertTrue('Invalid progression order' in str(w[0].message)) def test_tile_height_is_zero(self): """Zero tile height should not cause an exception.""" filename = opj_data_file('input/nonregression/2539.pdf.SIGFPE.706.1712.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with self.assertWarnsRegex(UserWarning, 'Invalid tile dimensions'): Jp2k(filename) - self.assertTrue(issubclass(w[0].category, UserWarning)) - self.assertTrue('Invalid tile dimensions' in str(w[0].message)) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_unknown_marker_segment(self): @@ -84,12 +72,9 @@ class TestCodestreamOpjDataWarnings(unittest.TestCase): read_buffer = ifile.read() tfile.write(read_buffer) tfile.flush() - - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + + with self.assertWarnsRegex(UserWarning, 'Unrecognized marker'): codestream = Jp2k(tfile.name).get_codestream() - self.assertTrue(issubclass(w[0].category, UserWarning)) - self.assertTrue('Unrecognized marker' in str(w[0].message)) self.assertEqual(codestream.segment[2].marker_id, '0xff79') self.assertEqual(codestream.segment[2].length, 3) From 7e52996cc89df5854284be090ec9ca33b49514f4 Mon Sep 17 00:00:00 2001 From: jevans Date: Mon, 18 Aug 2014 19:55:00 -0400 Subject: [PATCH 2/6] Using 3.x warning infrastructure exclusively. --- glymur/test/test_opj_suite_warn.py | 47 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/glymur/test/test_opj_suite_warn.py b/glymur/test/test_opj_suite_warn.py index c39b810..f63e9d0 100644 --- a/glymur/test/test_opj_suite_warn.py +++ b/glymur/test/test_opj_suite_warn.py @@ -42,6 +42,8 @@ from .fixtures import OPJ_DATA_ROOT from .fixtures import mse, peak_tolerance, read_pgx, opj_data_file +@unittest.skipIf(sys.hexversion < 0x03030000, + "assertWarn methods introduced in 3.x") @unittest.skipIf(OPJ_DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") class TestSuiteDumpWarnings(unittest.TestCase): @@ -54,8 +56,7 @@ class TestSuiteDumpWarnings(unittest.TestCase): def test_NR_broken_jp2_dump(self): jfile = opj_data_file('input/nonregression/broken.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + with self.assertWarnsRegex(UserWarning, 'incorrect box length'): # colr box has bad length. jp2 = Jp2k(jfile) @@ -180,8 +181,8 @@ class TestSuiteDumpWarnings(unittest.TestCase): def test_NR_broken2_jp2_dump(self): # Invalid marker ID on codestream. jfile = opj_data_file('input/nonregression/broken2.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + msg = 'Invalid marker id encountered at byte' + with self.assertWarnsRegex(UserWarning, msg): jp2 = Jp2k(jfile) self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC') @@ -195,8 +196,8 @@ class TestSuiteDumpWarnings(unittest.TestCase): length of over 1GB. Don't run it on 32-bit platforms. """ jfile = opj_data_file('input/nonregression/broken3.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + msg = r'box has incorrect box length \(\d+\)' + with self.assertWarnsRegex(UserWarning, msg): jp2 = Jp2k(jfile) ids = [box.box_id for box in jp2.box] @@ -320,8 +321,8 @@ class TestSuiteDumpWarnings(unittest.TestCase): def test_NR_broken4_jp2_dump(self): # Has an invalid marker in the main header jfile = opj_data_file('input/nonregression/broken4.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + regex = r'Invalid marker id encountered at byte \d+ in codestream' + with self.assertWarnsRegex(UserWarning, regex): jp2 = Jp2k(jfile) self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC') @@ -330,15 +331,20 @@ class TestSuiteDumpWarnings(unittest.TestCase): lst = ['input', 'nonregression', 'gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc.patch.jp2'] jfile = opj_data_file('/'.join(lst)) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + regex = re.compile(r"""Invalid\scomponent\snumber\s\(\d+\),\s + number\sof\scomponents\sis\sonly\s\d+""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): Jp2k(jfile) def test_NR_gdal_fuzzer_check_comp_dx_dy_jp2_dump(self): lst = ['input', 'nonregression', 'gdal_fuzzer_check_comp_dx_dy.jp2'] jfile = opj_data_file('/'.join(lst)) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + regex = re.compile(r"""Invalid\ssubsampling\svalue\sfor\scomponent\s + \d+:\s+ + dx=\d+,\s*dy=\d+""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): Jp2k(jfile) def test_NR_gdal_fuzzer_check_number_of_tiles(self): @@ -346,8 +352,10 @@ class TestSuiteDumpWarnings(unittest.TestCase): lst = ['input', 'nonregression', 'gdal_fuzzer_check_number_of_tiles.jp2'] jfile = opj_data_file('/'.join(lst)) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + regex = re.compile(r"""Invalid\snumber\sof\stiles\s + \(\d+\)\.""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): Jp2k(jfile) def test_NR_gdal_fuzzer_unchecked_numresolutions_dump(self): @@ -355,8 +363,10 @@ class TestSuiteDumpWarnings(unittest.TestCase): lst = ['input', 'nonregression', 'gdal_fuzzer_unchecked_numresolutions.jp2'] jfile = opj_data_file('/'.join(lst)) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + regex = re.compile(r"""Invalid\snumber\sof\sresolutions\s + \(\d+\)\.""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): Jp2k(jfile) @unittest.skipIf(re.match("1.5|2.0.0", glymur.version.openjpeg_version), @@ -366,8 +376,9 @@ class TestSuiteDumpWarnings(unittest.TestCase): # really does deserve a warning. relpath = 'input/nonregression/issue188_beach_64bitsbox.jp2' jfile = opj_data_file(relpath) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') + regex = re.compile(r"""Unrecognized\sbox\s\(b'XML\s'\)\sencountered.""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): j = Jp2k(jfile) d = j.read() From 701aa3ba952fb1519630c46cb943c33ec926cabc Mon Sep 17 00:00:00 2001 From: jevans Date: Thu, 21 Aug 2014 08:44:20 -0400 Subject: [PATCH 3/6] Starting to clearly separate warning testing from any other testing. --- glymur/codestream.py | 2 +- ...am_warnings.py => test_glymur_warnings.py} | 29 +++- glymur/test/test_opj_suite.py | 126 +++++++++++++++++ glymur/test/test_opj_suite_dump.py | 15 +- glymur/test/test_opj_suite_warn.py | 133 ------------------ glymur/test/test_printing.py | 34 +++-- 6 files changed, 187 insertions(+), 152 deletions(-) rename glymur/test/{test_codestream_warnings.py => test_glymur_warnings.py} (75%) diff --git a/glymur/codestream.py b/glymur/codestream.py index acc7791..88babe5 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -202,7 +202,7 @@ class Codestream(object): msg = 'Invalid marker id encountered at byte {0:d} ' msg += 'in codestream: "0x{1:x}"' msg = msg.format(self._offset, self._marker_id) - warnings.warn(msg) + warnings.warn(msg, UserWarning) break self.segment.append(segment) diff --git a/glymur/test/test_codestream_warnings.py b/glymur/test/test_glymur_warnings.py similarity index 75% rename from glymur/test/test_codestream_warnings.py rename to glymur/test/test_glymur_warnings.py index 7fc79f6..1f65cc8 100644 --- a/glymur/test/test_codestream_warnings.py +++ b/glymur/test/test_glymur_warnings.py @@ -1,5 +1,5 @@ """ -Test suite for codestream parsing. +Test suite for warnings issued by glymur. """ # unittest doesn't work well with R0904. @@ -9,6 +9,7 @@ Test suite for codestream parsing. # pylint: disable=E1101 import os +import re import struct import sys import tempfile @@ -24,8 +25,30 @@ from .fixtures import opj_data_file, OPJ_DATA_ROOT "assertWarn methods introduced in 3.x") @unittest.skipIf(OPJ_DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") -class TestCodestreamOpjDataWarnings(unittest.TestCase): - """Test suite for unusual codestream cases. Uses OPJ_DATA_ROOT""" +class TestWarnings(unittest.TestCase): + """Test suite for warnings issued by glymur.""" + + def test_NR_broken_jp2_dump(self): + """ + The colr box has a ridiculously incorrect box length. + """ + jfile = opj_data_file('input/nonregression/broken.jp2') + regex = re.compile(r'''b'colr'\sbox\shas\sincorrect\sbox\slength\s + \(\d+\)''', + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + jp2 = Jp2k(jfile) + + def test_NR_broken2_jp2_dump(self): + """ + Invalid marker ID on codestream. + """ + jfile = opj_data_file('input/nonregression/broken2.jp2') + regex = re.compile(r'''Invalid\smarker\sid\sencountered\sat\sbyte\s + \d+\sin\scodestream:\s*"0x[a-fA-F0-9]{4}"''', + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + jp2 = Jp2k(jfile) def test_bad_rsiz(self): """Should warn if RSIZ is bad. Issue196""" diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 1e658a3..9c725c4 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -287,6 +287,132 @@ class TestSuite(unittest.TestCase): jpdata = jp2k.read() self.assertEqual(jpdata.shape, (512, 768, 3)) + def test_NR_broken_jp2_dump(self): + jfile = opj_data_file('input/nonregression/broken.jp2') + + with warnings.catch_warnings(): + # colr box has bad length. + warnings.simplefilter("ignore") + jp2 = Jp2k(jfile) + + ids = [box.box_id for box in jp2.box] + self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) + + ids = [box.box_id for box in jp2.box[2].box] + self.assertEqual(ids, ['ihdr', 'colr']) + + # Signature box. Check for corruption. + self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10)) + + # File type box. + self.assertEqual(jp2.box[1].brand, 'jp2 ') + self.assertEqual(jp2.box[1].minor_version, 0) + self.assertEqual(jp2.box[1].compatibility_list[0], 'jp2 ') + + # Jp2 Header + # Image header + self.assertEqual(jp2.box[2].box[0].height, 152) + self.assertEqual(jp2.box[2].box[0].width, 203) + self.assertEqual(jp2.box[2].box[0].num_components, 3) + 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].colorspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].ip_provided, False) + + # Jp2 Header + # Colour specification + self.assertEqual(jp2.box[2].box[1].method, + glymur.core.ENUMERATED_COLORSPACE) + self.assertEqual(jp2.box[2].box[1].precedence, 0) + self.assertEqual(jp2.box[2].box[1].approximation, 0) # not allowed? + self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB) + + c = jp2.box[3].main_header + + ids = [x.marker_id for x in c.segment] + expected = ['SOC', 'SIZ', 'CME', 'COD', 'QCD', 'QCC', 'QCC'] + self.assertEqual(ids, expected) + + # SIZ: Image and tile size + # Profile: + self.assertEqual(c.segment[1].rsiz, 0) + # Reference grid size + self.assertEqual(c.segment[1].xsiz, 203) + self.assertEqual(c.segment[1].ysiz, 152) + # Reference grid offset + self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + # Tile size + self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), (203, 152)) + # Tile offset + self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) + # bitdepth + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) + # signed + self.assertEqual(c.segment[1].signed, (False, False, False)) + # subsampling + self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + [(1, 1)] * 3) + + # COM: comment + # Registration + self.assertEqual(c.segment[2].rcme, glymur.core.RCME_ISO_8859_1) + # Comment value + self.assertEqual(c.segment[2].ccme.decode('latin-1'), + "Creator: JasPer Version 1.701.0") + + # COD: Coding style default + self.assertFalse(c.segment[3].scod & 2) # no sop + self.assertFalse(c.segment[3].scod & 4) # no eph + self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP) + self.assertEqual(c.segment[3].layers, 1) # layers = 1 + self.assertEqual(c.segment[3].spcod[3], 1) # mct + self.assertEqual(c.segment[3].spcod[4], 5) # level + self.assertEqual(tuple(c.segment[3].code_block_size), + (64, 64)) # cblk + # Selective arithmetic coding bypass + self.assertFalse(c.segment[3].spcod[7] & 0x01) + # Reset context probabilities + self.assertFalse(c.segment[3].spcod[7] & 0x02) + # Termination on each coding pass + self.assertFalse(c.segment[3].spcod[7] & 0x04) + # Vertically causal context + self.assertFalse(c.segment[3].spcod[7] & 0x08) + # Predictable termination + self.assertFalse(c.segment[3].spcod[7] & 0x0010) + # Segmentation symbols + self.assertFalse(c.segment[3].spcod[7] & 0x0020) + self.assertEqual(c.segment[3].spcod[8], + glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) + self.assertEqual(len(c.segment[3].spcod), 9) + + # QCD: Quantization default + self.assertEqual(c.segment[4].sqcd & 0x1f, 0) + self.assertEqual(c.segment[4].guard_bits, 2) + self.assertEqual(c.segment[4].mantissa, [0] * 16) + self.assertEqual(c.segment[4].exponent, + [8] + [9, 9, 10] * 5) + + # QCC: Quantization component + # associated component + self.assertEqual(c.segment[5].cqcc, 1) + self.assertEqual(c.segment[5].guard_bits, 2) + # quantization type + self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none + self.assertEqual(c.segment[5].mantissa, [0] * 16) + self.assertEqual(c.segment[5].exponent, + [8] + [9, 9, 10] * 5) + + # QCC: Quantization component + # associated component + self.assertEqual(c.segment[6].cqcc, 2) + self.assertEqual(c.segment[6].guard_bits, 2) + # quantization type + self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none + self.assertEqual(c.segment[6].mantissa, [0] * 16) + self.assertEqual(c.segment[6].exponent, + [8] + [9, 9, 10] * 5) + def test_NR_DEC_Bretagne2_j2k_1_decode(self): jfile = opj_data_file('input/nonregression/Bretagne2.j2k') jp2 = Jp2k(jfile) diff --git a/glymur/test/test_opj_suite_dump.py b/glymur/test/test_opj_suite_dump.py index e24f53f..138f72b 100644 --- a/glymur/test/test_opj_suite_dump.py +++ b/glymur/test/test_opj_suite_dump.py @@ -52,6 +52,18 @@ class TestSuiteDump(unittest.TestCase): def tearDown(self): pass + def test_NR_broken2_jp2_dump(self): + """ + Invalid marker ID in the codestream. + """ + jfile = opj_data_file('input/nonregression/broken2.jp2') + with warnings.catch_warnings(): + # Invalid marker ID on codestream. + warnings.simplefilter("ignore") + jp2 = Jp2k(jfile) + + self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC') + def test_NR_file409752(self): jfile = opj_data_file('input/nonregression/file409752.jp2') jp2 = Jp2k(jfile) @@ -4594,8 +4606,7 @@ class TestSuiteDump(unittest.TestCase): lst = ['input', 'nonregression', 'issue188_beach_64bitsbox.jp2'] jfile = opj_data_file('/'.join(lst)) with warnings.catch_warnings(): - # There's a warning for an unknown box. We explicitly test for - # that down below. + # There's a warning for an unknown box. warnings.simplefilter("ignore") jp2 = Jp2k(jfile) diff --git a/glymur/test/test_opj_suite_warn.py b/glymur/test/test_opj_suite_warn.py index f63e9d0..d5ed4aa 100644 --- a/glymur/test/test_opj_suite_warn.py +++ b/glymur/test/test_opj_suite_warn.py @@ -54,139 +54,6 @@ class TestSuiteDumpWarnings(unittest.TestCase): def tearDown(self): pass - def test_NR_broken_jp2_dump(self): - jfile = opj_data_file('input/nonregression/broken.jp2') - with self.assertWarnsRegex(UserWarning, 'incorrect box length'): - # colr box has bad length. - jp2 = Jp2k(jfile) - - ids = [box.box_id for box in jp2.box] - self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) - - ids = [box.box_id for box in jp2.box[2].box] - self.assertEqual(ids, ['ihdr', 'colr']) - - # Signature box. Check for corruption. - self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10)) - - # File type box. - self.assertEqual(jp2.box[1].brand, 'jp2 ') - self.assertEqual(jp2.box[1].minor_version, 0) - self.assertEqual(jp2.box[1].compatibility_list[0], 'jp2 ') - - # Jp2 Header - # Image header - self.assertEqual(jp2.box[2].box[0].height, 152) - self.assertEqual(jp2.box[2].box[0].width, 203) - self.assertEqual(jp2.box[2].box[0].num_components, 3) - 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].colorspace_unknown, False) - self.assertEqual(jp2.box[2].box[0].ip_provided, False) - - # Jp2 Header - # Colour specification - self.assertEqual(jp2.box[2].box[1].method, - glymur.core.ENUMERATED_COLORSPACE) - self.assertEqual(jp2.box[2].box[1].precedence, 0) - self.assertEqual(jp2.box[2].box[1].approximation, 0) # not allowed? - self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB) - - c = jp2.box[3].main_header - - ids = [x.marker_id for x in c.segment] - expected = ['SOC', 'SIZ', 'CME', 'COD', 'QCD', 'QCC', 'QCC'] - self.assertEqual(ids, expected) - - # SIZ: Image and tile size - # Profile: - self.assertEqual(c.segment[1].rsiz, 0) - # Reference grid size - self.assertEqual(c.segment[1].xsiz, 203) - self.assertEqual(c.segment[1].ysiz, 152) - # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) - # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), (203, 152)) - # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) - # bitdepth - self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) - # signed - self.assertEqual(c.segment[1].signed, (False, False, False)) - # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), - [(1, 1)] * 3) - - # COM: comment - # Registration - self.assertEqual(c.segment[2].rcme, glymur.core.RCME_ISO_8859_1) - # Comment value - self.assertEqual(c.segment[2].ccme.decode('latin-1'), - "Creator: JasPer Version 1.701.0") - - # COD: Coding style default - self.assertFalse(c.segment[3].scod & 2) # no sop - self.assertFalse(c.segment[3].scod & 4) # no eph - self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[3].layers, 1) # layers = 1 - self.assertEqual(c.segment[3].spcod[3], 1) # mct - self.assertEqual(c.segment[3].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[3].code_block_size), - (64, 64)) # cblk - # Selective arithmetic coding bypass - self.assertFalse(c.segment[3].spcod[7] & 0x01) - # Reset context probabilities - self.assertFalse(c.segment[3].spcod[7] & 0x02) - # Termination on each coding pass - self.assertFalse(c.segment[3].spcod[7] & 0x04) - # Vertically causal context - self.assertFalse(c.segment[3].spcod[7] & 0x08) - # Predictable termination - self.assertFalse(c.segment[3].spcod[7] & 0x0010) - # Segmentation symbols - self.assertFalse(c.segment[3].spcod[7] & 0x0020) - self.assertEqual(c.segment[3].spcod[8], - glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[3].spcod), 9) - - # QCD: Quantization default - self.assertEqual(c.segment[4].sqcd & 0x1f, 0) - self.assertEqual(c.segment[4].guard_bits, 2) - self.assertEqual(c.segment[4].mantissa, [0] * 16) - self.assertEqual(c.segment[4].exponent, - [8] + [9, 9, 10] * 5) - - # QCC: Quantization component - # associated component - self.assertEqual(c.segment[5].cqcc, 1) - self.assertEqual(c.segment[5].guard_bits, 2) - # quantization type - self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[5].mantissa, [0] * 16) - self.assertEqual(c.segment[5].exponent, - [8] + [9, 9, 10] * 5) - - # QCC: Quantization component - # associated component - self.assertEqual(c.segment[6].cqcc, 2) - self.assertEqual(c.segment[6].guard_bits, 2) - # quantization type - self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[6].mantissa, [0] * 16) - self.assertEqual(c.segment[6].exponent, - [8] + [9, 9, 10] * 5) - - def test_NR_broken2_jp2_dump(self): - # Invalid marker ID on codestream. - jfile = opj_data_file('input/nonregression/broken2.jp2') - msg = 'Invalid marker id encountered at byte' - with self.assertWarnsRegex(UserWarning, msg): - jp2 = Jp2k(jfile) - - self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC') - @unittest.skipIf(sys.maxsize < 2**32, 'Do not run on 32-bit platforms') def test_NR_broken3_jp2_dump(self): """ diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index efd1ccf..10e3e54 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -11,6 +11,7 @@ # pylint: disable=R0904 import os +import re import struct import sys import tempfile @@ -70,6 +71,8 @@ class TestPrinting(unittest.TestCase): self.assertTrue(True) + @unittest.skipIf(sys.hexversion < 0x03030000, + "assertWarn methods introduced in 3.x") def test_unknown_superbox(self): """Verify that we can handle an unknown superbox.""" with tempfile.NamedTemporaryFile(suffix='.jpx') as tfile: @@ -86,10 +89,10 @@ class TestPrinting(unittest.TestCase): tfile.write(write_buffer) tfile.flush() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + regex = re.compile(r'''Unrecognized\sbox\s\(b'grp\s'\)\s + encountered.''', re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): jpx = Jp2k(tfile.name) - self.assertTrue(len(w), 1) glymur.set_printoptions(short=True) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -725,8 +728,6 @@ class TestPrintingOpjDataRoot(unittest.TestCase): # Reset printoptions for every test. glymur.set_printoptions(short=False, xml=True, codestream=True) - warnings.resetwarnings() - def tearDown(self): pass @@ -744,33 +745,43 @@ class TestPrintingOpjDataRoot(unittest.TestCase): """An invalid colorspace shouldn't cause an error.""" filename = opj_data_file('input/nonregression/edf_c2_1103421.jp2') with warnings.catch_warnings(): + # Bad compatibility list item and bad colorspace warnings. Just + # suppress the warnings. warnings.simplefilter("ignore") jp2 = Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(jp2) + @unittest.skipIf(sys.hexversion < 0x03030000, + "assertWarn methods introduced in 3.x") 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") + regex = re.compile(r'''Invalid\sprofile:\s\(Rsiz=\d+\)\.''', re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): j = Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j) + @unittest.skipIf(sys.hexversion < 0x03030000, + "assertWarn methods introduced in 3.x") 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') - with warnings.catch_warnings(): - warnings.simplefilter("ignore") + regex = re.compile(r'''Invalid\swavelet\stransform\sin\sCOD\ssegment:\s + \d+\.''', re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): j = Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j) + @unittest.skipIf(sys.hexversion < 0x03030000, + "assertWarn methods introduced in 3.x") def test_invalid_progression_order(self): """Should still be able to print even if prog order is invalid.""" jfile = opj_data_file('input/nonregression/2977.pdf.asan.67.2198.jp2') with warnings.catch_warnings(): + # Multiple warnings, actually. warnings.simplefilter("ignore") jp2 = Jp2k(jfile) codestream = jp2.get_codestream() @@ -1058,10 +1069,7 @@ class TestPrintingOpjDataRoot(unittest.TestCase): def test_uuid(self): """verify printing of UUID box""" filename = opj_data_file('input/nonregression/text_GBR.jp2') - with warnings.catch_warnings(): - # brand is 'jp2 ', but has any icc profile. - warnings.simplefilter("ignore") - jp2 = Jp2k(filename) + jp2 = Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(jp2.box[4]) From ddf17a9d18e56d862e72738bbe5a2386507ac211 Mon Sep 17 00:00:00 2001 From: jevans Date: Thu, 21 Aug 2014 19:29:08 -0400 Subject: [PATCH 4/6] Removed all tests from test_opj_suite_warn. Now located in test_glymur_warnings and test_opj_suite_dump. --- glymur/test/test_glymur_warnings.py | 95 ++++++++++- glymur/test/test_opj_suite_dump.py | 153 +++++++++++++++++ glymur/test/test_opj_suite_warn.py | 254 ---------------------------- 3 files changed, 242 insertions(+), 260 deletions(-) delete mode 100644 glymur/test/test_opj_suite_warn.py diff --git a/glymur/test/test_glymur_warnings.py b/glymur/test/test_glymur_warnings.py index 1f65cc8..6d5c1e3 100644 --- a/glymur/test/test_glymur_warnings.py +++ b/glymur/test/test_glymur_warnings.py @@ -28,6 +28,70 @@ from .fixtures import opj_data_file, OPJ_DATA_ROOT class TestWarnings(unittest.TestCase): """Test suite for warnings issued by glymur.""" + def test_NR_DEC_issue188_beach_64bitsbox_jp2_41_decode(self): + """ + Has an 'XML ' box instead of 'xml '. Yes that is pedantic, but it + really does deserve a warning. + """ + relpath = 'input/nonregression/issue188_beach_64bitsbox.jp2' + jfile = opj_data_file(relpath) + regex = re.compile(r"""Unrecognized\sbox\s\(b'XML\s'\)\sencountered.""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + + + def test_NR_gdal_fuzzer_unchecked_numresolutions_dump(self): + """ + Has an invalid number of resolutions. + """ + lst = ['input', 'nonregression', + 'gdal_fuzzer_unchecked_numresolutions.jp2'] + jfile = opj_data_file('/'.join(lst)) + regex = re.compile(r"""Invalid\snumber\sof\sresolutions\s + \(\d+\)\.""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + + @unittest.skipIf(re.match("1.5|2.0.0", glymur.version.openjpeg_version), + "Test not passing on 1.5.x, not introduced until 2.x") + def test_NR_gdal_fuzzer_check_number_of_tiles(self): + """ + Has an impossible tiling setup. + """ + lst = ['input', 'nonregression', + 'gdal_fuzzer_check_number_of_tiles.jp2'] + jfile = opj_data_file('/'.join(lst)) + regex = re.compile(r"""Invalid\snumber\sof\stiles\s + \(\d+\)\.""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + + def test_NR_gdal_fuzzer_check_comp_dx_dy_jp2_dump(self): + """ + Invalid subsampling value. + """ + lst = ['input', 'nonregression', 'gdal_fuzzer_check_comp_dx_dy.jp2'] + jfile = opj_data_file('/'.join(lst)) + regex = re.compile(r"""Invalid\ssubsampling\svalue\sfor\scomponent\s + \d+:\s+ + dx=\d+,\s*dy=\d+""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + + def test_NR_gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc_patch_jp2(self): + lst = ['input', 'nonregression', + 'gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc.patch.jp2'] + jfile = opj_data_file('/'.join(lst)) + regex = re.compile(r"""Invalid\scomponent\snumber\s\(\d+\),\s + number\sof\scomponents\sis\sonly\s\d+""", + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + def test_NR_broken_jp2_dump(self): """ The colr box has a ridiculously incorrect box length. @@ -47,20 +111,43 @@ class TestWarnings(unittest.TestCase): regex = re.compile(r'''Invalid\smarker\sid\sencountered\sat\sbyte\s \d+\sin\scodestream:\s*"0x[a-fA-F0-9]{4}"''', re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + + def test_NR_broken4_jp2_dump(self): + """ + Has an invalid marker in the main header + """ + jfile = opj_data_file('input/nonregression/broken4.jp2') + regex = r'Invalid marker id encountered at byte \d+ in codestream' with self.assertWarnsRegex(UserWarning, regex): jp2 = Jp2k(jfile) + @unittest.skipIf(sys.maxsize < 2**32, 'Do not run on 32-bit platforms') + def test_NR_broken3_jp2_dump(self): + """ + Has an impossibly large box length. + + The file in question here has a colr box with an erroneous box + length of over 1GB. Don't run it on 32-bit platforms. + """ + jfile = opj_data_file('input/nonregression/broken3.jp2') + regex = re.compile(r'''b'colr'\sbox\shas\sincorrect\sbox\slength\s + \(\d+\)''', re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(jfile) + def test_bad_rsiz(self): """Should warn if RSIZ is bad. Issue196""" filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2') with self.assertWarnsRegex(UserWarning, 'Invalid profile'): - j = Jp2k(filename) + Jp2k(filename) def test_bad_wavelet_transform(self): """Should warn if wavelet transform is bad. Issue195""" filename = opj_data_file('input/nonregression/edf_c2_10025.jp2') with self.assertWarnsRegex(UserWarning, 'Invalid wavelet transform'): - j = Jp2k(filename) + Jp2k(filename) def test_invalid_progression_order(self): """Should still be able to parse even if prog order is invalid.""" @@ -99,10 +186,6 @@ class TestWarnings(unittest.TestCase): with self.assertWarnsRegex(UserWarning, 'Unrecognized marker'): codestream = Jp2k(tfile.name).get_codestream() - self.assertEqual(codestream.segment[2].marker_id, '0xff79') - self.assertEqual(codestream.segment[2].length, 3) - self.assertEqual(codestream.segment[2].data, b'\x00') - if __name__ == "__main__": unittest.main() diff --git a/glymur/test/test_opj_suite_dump.py b/glymur/test/test_opj_suite_dump.py index 138f72b..8a831ca 100644 --- a/glymur/test/test_opj_suite_dump.py +++ b/glymur/test/test_opj_suite_dump.py @@ -52,6 +52,159 @@ class TestSuiteDump(unittest.TestCase): def tearDown(self): pass + def test_NR_DEC_issue188_beach_64bitsbox_jp2_41_decode(self): + """ + Has an 'XML ' box instead of 'xml '. Just verify we can read it. + """ + relpath = 'input/nonregression/issue188_beach_64bitsbox.jp2' + jfile = opj_data_file(relpath) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + j = Jp2k(jfile) + d = j.read() + self.assertTrue(True) + + + def test_NR_broken4_jp2_dump(self): + jfile = opj_data_file('input/nonregression/broken4.jp2') + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + jp2 = Jp2k(jfile) + + self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC') + + @unittest.skipIf(sys.maxsize < 2**32, 'Do not run on 32-bit platforms') + def test_NR_broken3_jp2_dump(self): + """ + NR_broken3_jp2_dump + + The file in question here has a colr box with an erroneous box + length of over 1GB. Don't run it on 32-bit platforms. + """ + jfile = opj_data_file('input/nonregression/broken3.jp2') + with warnings.catch_warnings(): + # Bad box length. + warnings.simplefilter("ignore") + jp2 = Jp2k(jfile) + + ids = [box.box_id for box in jp2.box] + self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) + + ids = [box.box_id for box in jp2.box[2].box] + self.assertEqual(ids, ['ihdr', 'colr']) + + # Signature box. Check for corruption. + self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10)) + + # File type box. + self.assertEqual(jp2.box[1].brand, 'jp2 ') + self.assertEqual(jp2.box[1].minor_version, 0) + self.assertEqual(jp2.box[1].compatibility_list[0], 'jp2 ') + + # Jp2 Header + # Image header + self.assertEqual(jp2.box[2].box[0].height, 152) + self.assertEqual(jp2.box[2].box[0].width, 203) + self.assertEqual(jp2.box[2].box[0].num_components, 3) + 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].colorspace_unknown, False) + self.assertEqual(jp2.box[2].box[0].ip_provided, False) + + # Jp2 Header + # Colour specification + self.assertEqual(jp2.box[2].box[1].method, + glymur.core.ENUMERATED_COLORSPACE) + self.assertEqual(jp2.box[2].box[1].precedence, 0) + self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2 + self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB) + + c = jp2.box[3].main_header + + ids = [x.marker_id for x in c.segment] + expected = ['SOC', 'SIZ', 'CME', 'COD', 'QCD', 'QCC', 'QCC'] + self.assertEqual(ids, expected) + + # SIZ: Image and tile size + # Profile: + self.assertEqual(c.segment[1].rsiz, 0) + # Reference grid size + self.assertEqual(c.segment[1].xsiz, 203) + self.assertEqual(c.segment[1].ysiz, 152) + # Reference grid offset + self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + # Tile size + self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), (203, 152)) + # Tile offset + self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) + # bitdepth + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) + # signed + self.assertEqual(c.segment[1].signed, (False, False, False)) + # subsampling + self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + [(1, 1)] * 3) + + # COM: comment + # Registration + self.assertEqual(c.segment[2].rcme, glymur.core.RCME_ISO_8859_1) + # Comment value + self.assertEqual(c.segment[2].ccme.decode('latin-1'), + "Creator: JasPer Vers)on 1.701.0") + + # COD: Coding style default + self.assertFalse(c.segment[3].scod & 2) # no sop + self.assertFalse(c.segment[3].scod & 4) # no eph + self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP) + self.assertEqual(c.segment[3].layers, 1) # layers = 1 + self.assertEqual(c.segment[3].spcod[3], 1) # mct + self.assertEqual(c.segment[3].spcod[4], 5) # level + self.assertEqual(tuple(c.segment[3].code_block_size), + (64, 64)) # cblk + # Selective arithmetic coding bypass + self.assertFalse(c.segment[3].spcod[7] & 0x01) + # Reset context probabilities + self.assertFalse(c.segment[3].spcod[7] & 0x02) + # Termination on each coding pass + self.assertFalse(c.segment[3].spcod[7] & 0x04) + # Vertically causal context + self.assertFalse(c.segment[3].spcod[7] & 0x08) + # Predictable termination + self.assertFalse(c.segment[3].spcod[7] & 0x0010) + # Segmentation symbols + self.assertFalse(c.segment[3].spcod[7] & 0x0020) + self.assertEqual(c.segment[3].spcod[8], + glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) + self.assertEqual(len(c.segment[3].spcod), 9) + + # QCD: Quantization default + self.assertEqual(c.segment[4].sqcd & 0x1f, 0) + self.assertEqual(c.segment[4].guard_bits, 2) + self.assertEqual(c.segment[4].mantissa, [0] * 16) + self.assertEqual(c.segment[4].exponent, + [8] + [9, 9, 10] * 5) + + # QCC: Quantization component + # associated component + self.assertEqual(c.segment[5].cqcc, 1) + self.assertEqual(c.segment[5].guard_bits, 2) + # quantization type + self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none + self.assertEqual(c.segment[5].mantissa, [0] * 16) + self.assertEqual(c.segment[5].exponent, + [8] + [9, 9, 10] * 5) + + # QCC: Quantization component + # associated component + self.assertEqual(c.segment[6].cqcc, 2) + self.assertEqual(c.segment[6].guard_bits, 2) + # quantization type + self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none + self.assertEqual(c.segment[6].mantissa, [0] * 16) + self.assertEqual(c.segment[6].exponent, + [8] + [9, 9, 10] * 5) + def test_NR_broken2_jp2_dump(self): """ Invalid marker ID in the codestream. diff --git a/glymur/test/test_opj_suite_warn.py b/glymur/test/test_opj_suite_warn.py deleted file mode 100644 index d5ed4aa..0000000 --- a/glymur/test/test_opj_suite_warn.py +++ /dev/null @@ -1,254 +0,0 @@ -""" -The tests defined here roughly correspond to what is in the OpenJPEG test -suite. -""" - -# Some test names correspond with openjpeg tests. Long names are ok in this -# case. -# pylint: disable=C0103 - -# All of these tests correspond to tests in openjpeg, so no docstring is really -# needed. -# pylint: disable=C0111 - -# This module is very long, cannot be helped. -# pylint: disable=C0302 - -# unittest fools pylint with "too many public methods" -# pylint: disable=R0904 - -# Some tests use numpy test infrastructure, which means the tests never -# reference "self", so pylint claims it should be a function. No, no, no. -# pylint: disable=R0201 - -# Many tests are pretty long and that can't be helped. -# pylint: disable=R0915 - -# asserWarns introduced in python 3.2 (python2.7/pylint issue) -# pylint: disable=E1101 - -import re -import sys -import unittest - -import warnings - -import numpy as np - -from glymur import Jp2k -import glymur - -from .fixtures import OPJ_DATA_ROOT -from .fixtures import mse, peak_tolerance, read_pgx, opj_data_file - - -@unittest.skipIf(sys.hexversion < 0x03030000, - "assertWarn methods introduced in 3.x") -@unittest.skipIf(OPJ_DATA_ROOT is None, - "OPJ_DATA_ROOT environment variable not set") -class TestSuiteDumpWarnings(unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass - - @unittest.skipIf(sys.maxsize < 2**32, 'Do not run on 32-bit platforms') - def test_NR_broken3_jp2_dump(self): - """ - NR_broken3_jp2_dump - - The file in question here has a colr box with an erroneous box - length of over 1GB. Don't run it on 32-bit platforms. - """ - jfile = opj_data_file('input/nonregression/broken3.jp2') - msg = r'box has incorrect box length \(\d+\)' - with self.assertWarnsRegex(UserWarning, msg): - jp2 = Jp2k(jfile) - - ids = [box.box_id for box in jp2.box] - self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) - - ids = [box.box_id for box in jp2.box[2].box] - self.assertEqual(ids, ['ihdr', 'colr']) - - # Signature box. Check for corruption. - self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10)) - - # File type box. - self.assertEqual(jp2.box[1].brand, 'jp2 ') - self.assertEqual(jp2.box[1].minor_version, 0) - self.assertEqual(jp2.box[1].compatibility_list[0], 'jp2 ') - - # Jp2 Header - # Image header - self.assertEqual(jp2.box[2].box[0].height, 152) - self.assertEqual(jp2.box[2].box[0].width, 203) - self.assertEqual(jp2.box[2].box[0].num_components, 3) - 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].colorspace_unknown, False) - self.assertEqual(jp2.box[2].box[0].ip_provided, False) - - # Jp2 Header - # Colour specification - self.assertEqual(jp2.box[2].box[1].method, - glymur.core.ENUMERATED_COLORSPACE) - self.assertEqual(jp2.box[2].box[1].precedence, 0) - self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2 - self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB) - - c = jp2.box[3].main_header - - ids = [x.marker_id for x in c.segment] - expected = ['SOC', 'SIZ', 'CME', 'COD', 'QCD', 'QCC', 'QCC'] - self.assertEqual(ids, expected) - - # SIZ: Image and tile size - # Profile: - self.assertEqual(c.segment[1].rsiz, 0) - # Reference grid size - self.assertEqual(c.segment[1].xsiz, 203) - self.assertEqual(c.segment[1].ysiz, 152) - # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) - # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), (203, 152)) - # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) - # bitdepth - self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) - # signed - self.assertEqual(c.segment[1].signed, (False, False, False)) - # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), - [(1, 1)] * 3) - - # COM: comment - # Registration - self.assertEqual(c.segment[2].rcme, glymur.core.RCME_ISO_8859_1) - # Comment value - self.assertEqual(c.segment[2].ccme.decode('latin-1'), - "Creator: JasPer Vers)on 1.701.0") - - # COD: Coding style default - self.assertFalse(c.segment[3].scod & 2) # no sop - self.assertFalse(c.segment[3].scod & 4) # no eph - self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[3].layers, 1) # layers = 1 - self.assertEqual(c.segment[3].spcod[3], 1) # mct - self.assertEqual(c.segment[3].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[3].code_block_size), - (64, 64)) # cblk - # Selective arithmetic coding bypass - self.assertFalse(c.segment[3].spcod[7] & 0x01) - # Reset context probabilities - self.assertFalse(c.segment[3].spcod[7] & 0x02) - # Termination on each coding pass - self.assertFalse(c.segment[3].spcod[7] & 0x04) - # Vertically causal context - self.assertFalse(c.segment[3].spcod[7] & 0x08) - # Predictable termination - self.assertFalse(c.segment[3].spcod[7] & 0x0010) - # Segmentation symbols - self.assertFalse(c.segment[3].spcod[7] & 0x0020) - self.assertEqual(c.segment[3].spcod[8], - glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[3].spcod), 9) - - # QCD: Quantization default - self.assertEqual(c.segment[4].sqcd & 0x1f, 0) - self.assertEqual(c.segment[4].guard_bits, 2) - self.assertEqual(c.segment[4].mantissa, [0] * 16) - self.assertEqual(c.segment[4].exponent, - [8] + [9, 9, 10] * 5) - - # QCC: Quantization component - # associated component - self.assertEqual(c.segment[5].cqcc, 1) - self.assertEqual(c.segment[5].guard_bits, 2) - # quantization type - self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[5].mantissa, [0] * 16) - self.assertEqual(c.segment[5].exponent, - [8] + [9, 9, 10] * 5) - - # QCC: Quantization component - # associated component - self.assertEqual(c.segment[6].cqcc, 2) - self.assertEqual(c.segment[6].guard_bits, 2) - # quantization type - self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[6].mantissa, [0] * 16) - self.assertEqual(c.segment[6].exponent, - [8] + [9, 9, 10] * 5) - - def test_NR_broken4_jp2_dump(self): - # Has an invalid marker in the main header - jfile = opj_data_file('input/nonregression/broken4.jp2') - regex = r'Invalid marker id encountered at byte \d+ in codestream' - with self.assertWarnsRegex(UserWarning, regex): - jp2 = Jp2k(jfile) - - self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC') - - def test_NR_gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc_patch_jp2(self): - lst = ['input', 'nonregression', - 'gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc.patch.jp2'] - jfile = opj_data_file('/'.join(lst)) - regex = re.compile(r"""Invalid\scomponent\snumber\s\(\d+\),\s - number\sof\scomponents\sis\sonly\s\d+""", - re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): - Jp2k(jfile) - - def test_NR_gdal_fuzzer_check_comp_dx_dy_jp2_dump(self): - lst = ['input', 'nonregression', 'gdal_fuzzer_check_comp_dx_dy.jp2'] - jfile = opj_data_file('/'.join(lst)) - regex = re.compile(r"""Invalid\ssubsampling\svalue\sfor\scomponent\s - \d+:\s+ - dx=\d+,\s*dy=\d+""", - re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): - Jp2k(jfile) - - def test_NR_gdal_fuzzer_check_number_of_tiles(self): - # Has an impossible tiling setup. - lst = ['input', 'nonregression', - 'gdal_fuzzer_check_number_of_tiles.jp2'] - jfile = opj_data_file('/'.join(lst)) - regex = re.compile(r"""Invalid\snumber\sof\stiles\s - \(\d+\)\.""", - re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): - Jp2k(jfile) - - def test_NR_gdal_fuzzer_unchecked_numresolutions_dump(self): - # Has an invalid number of resolutions. - lst = ['input', 'nonregression', - 'gdal_fuzzer_unchecked_numresolutions.jp2'] - jfile = opj_data_file('/'.join(lst)) - regex = re.compile(r"""Invalid\snumber\sof\sresolutions\s - \(\d+\)\.""", - re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): - Jp2k(jfile) - - @unittest.skipIf(re.match("1.5|2.0.0", glymur.version.openjpeg_version), - "Test not passing on 1.5.x, not introduced until 2.x") - def test_NR_DEC_issue188_beach_64bitsbox_jp2_41_decode(self): - # Has an 'XML ' box instead of 'xml '. Yes that is pedantic, but it - # really does deserve a warning. - relpath = 'input/nonregression/issue188_beach_64bitsbox.jp2' - jfile = opj_data_file(relpath) - regex = re.compile(r"""Unrecognized\sbox\s\(b'XML\s'\)\sencountered.""", - re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): - j = Jp2k(jfile) - d = j.read() - - -if __name__ == "__main__": - unittest.main() From d00f84b6ebc657eb295551b13e7764353b8ca436 Mon Sep 17 00:00:00 2001 From: jevans Date: Thu, 21 Aug 2014 19:48:26 -0400 Subject: [PATCH 5/6] moved test_exceeded_box_length into test_glymur_warnings --- glymur/test/test_glymur_warnings.py | 19 +++++++++++++++++++ glymur/test/test_opj_suite_neg.py | 13 +------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/glymur/test/test_glymur_warnings.py b/glymur/test/test_glymur_warnings.py index 6d5c1e3..7c3c422 100644 --- a/glymur/test/test_glymur_warnings.py +++ b/glymur/test/test_glymur_warnings.py @@ -28,6 +28,25 @@ from .fixtures import opj_data_file, OPJ_DATA_ROOT class TestWarnings(unittest.TestCase): """Test suite for warnings issued by glymur.""" + def test_exceeded_box_length(self): + """ + should warn if reading past end of a box + + Verify that a warning is issued if we read past the end of a box + This file has a palette (pclr) box whose length is impossibly + short. + """ + infile = os.path.join(OPJ_DATA_ROOT, + 'input/nonregression/mem-b2ace68c-1381.jp2') + regex = re.compile(r'''Encountered\san\sunrecoverable\sValueError\s + while\sparsing\sa\spclr\sbox\sat\sbyte\soffset\s + \d+\.\s+The\soriginal\serror\smessage\swas\s + "total\ssize\sof\snew\sarray\smust\sbe\s + unchanged"''', + re.VERBOSE) + with self.assertWarnsRegex(UserWarning, regex): + Jp2k(infile) + def test_NR_DEC_issue188_beach_64bitsbox_jp2_41_decode(self): """ Has an 'XML ' box instead of 'xml '. Yes that is pedantic, but it diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index 5a475a2..0020803 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -83,7 +83,7 @@ class TestSuiteNegative(unittest.TestCase): relpath = 'input/nonregression/illegalcolortransform.j2k' jfile = opj_data_file(relpath) jp2k = Jp2k(jfile) - with warnings.catch_warnings(record=True) as w: + with warnings.catch_warnings(): warnings.simplefilter('ignore') codestream = jp2k.get_codestream(header_only=False) @@ -119,17 +119,6 @@ class TestSuiteNegative(unittest.TestCase): with self.assertRaises(IOError): j.write(data, cbsize=(2, 2048)) - def test_exceeded_box(self): - """should warn if reading past end of a box""" - # Verify that a warning is issued if we read past the end of a box - # This file has a palette (pclr) box whose length is impossibly - # short. - infile = os.path.join(OPJ_DATA_ROOT, - 'input/nonregression/mem-b2ace68c-1381.jp2') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('ignore') - Jp2k(infile) - @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_precinct_size_not_p2(self): """precinct sizes should be powers of two.""" From 18aaa983f79336c0123256b86e4722ecd70c20b9 Mon Sep 17 00:00:00 2001 From: jevans Date: Mon, 25 Aug 2014 20:00:08 -0400 Subject: [PATCH 6/6] Refactored warnings, no warnings/failures on mac. --- glymur/test/test_printing.py | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index 10e3e54..b893317 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -71,15 +71,13 @@ class TestPrinting(unittest.TestCase): self.assertTrue(True) - @unittest.skipIf(sys.hexversion < 0x03030000, - "assertWarn methods introduced in 3.x") def test_unknown_superbox(self): """Verify that we can handle an unknown superbox.""" with tempfile.NamedTemporaryFile(suffix='.jpx') as tfile: with open(self.jpxfile, 'rb') as ifile: tfile.write(ifile.read()) - # Add the header for an unknwon superbox. + # Add the header for an unknown superbox. write_buffer = struct.pack('>I4s', 20, 'grp '.encode()) tfile.write(write_buffer) @@ -89,9 +87,9 @@ class TestPrinting(unittest.TestCase): tfile.write(write_buffer) tfile.flush() - regex = re.compile(r'''Unrecognized\sbox\s\(b'grp\s'\)\s - encountered.''', re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): + with warnings.catch_warnings(): + # Suppress the warning about the unrecognized box. + warnings.simplefilter("ignore") jpx = Jp2k(tfile.name) glymur.set_printoptions(short=True) @@ -752,31 +750,24 @@ class TestPrintingOpjDataRoot(unittest.TestCase): with patch('sys.stdout', new=StringIO()) as fake_out: print(jp2) - @unittest.skipIf(sys.hexversion < 0x03030000, - "assertWarn methods introduced in 3.x") 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') - regex = re.compile(r'''Invalid\sprofile:\s\(Rsiz=\d+\)\.''', re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") j = Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j) - @unittest.skipIf(sys.hexversion < 0x03030000, - "assertWarn methods introduced in 3.x") 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') - regex = re.compile(r'''Invalid\swavelet\stransform\sin\sCOD\ssegment:\s - \d+\.''', re.VERBOSE) - with self.assertWarnsRegex(UserWarning, regex): - j = Jp2k(filename) - with patch('sys.stdout', new=StringIO()) as fake_out: - print(j) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + jp2 = Jp2k(filename) + with patch('sys.stdout', new=StringIO()) as fake_out: + print(jp2) - @unittest.skipIf(sys.hexversion < 0x03030000, - "assertWarn methods introduced in 3.x") def test_invalid_progression_order(self): """Should still be able to print even if prog order is invalid.""" jfile = opj_data_file('input/nonregression/2977.pdf.asan.67.2198.jp2')