diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 8d5272b..a42e291 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -233,6 +233,11 @@ class Jp2k(Jp2kBox): msg = "Code block area cannot exceed 4096. " msg += "Code block height and width must be larger than 4." raise RuntimeError(msg) + if ((math.log(h, 2) != math.floor(math.log(h, 2)) or + math.log(w, 2) != math.floor(math.log(w, 2)))): + msg = "Bad code block size ({0}, {1}), " + msg += "must be powers of 2." + raise IOError(msg.format(h, w)) cparams.cblockw_init = w cparams.cblockh_init = h @@ -269,10 +274,16 @@ class Jp2k(Jp2kBox): if psizes is not None: for j, (prch, prcw) in enumerate(psizes): + if j == 0 and cbsize is not None: + cblkh, cblkw = cbsize + if cblkh * 2 > prch or cblkw * 2 > prcw: + msg = "Highest Resolution precinct size must be at " + msg += "least twice that of the code block dimensions." + raise IOError(msg) if ((math.log(prch, 2) != math.floor(math.log(prch, 2)) or math.log(prcw, 2) != math.floor(math.log(prcw, 2)))): - msg = "Bad precinct size ({0}, {1}), " - msg += "must be multiple of 2." + msg = "Bad precinct sizes ({0}, {1}), " + msg += "must be powers of 2." raise IOError(msg.format(prch, prcw)) cparams.prcw_init[j] = prcw diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index f33b981..0862c42 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -153,7 +153,7 @@ class TestSuiteNegative(unittest.TestCase): j = Jp2k(infile) def test_precinct_size_not_multiple_of_two(self): - # Seems like precinct size should be a multiple of two. + # Seems like precinct sizes should be powers of two. ifile = Jp2k(self.jp2file) data = ifile.read(reduce=3) with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -161,5 +161,26 @@ class TestSuiteNegative(unittest.TestCase): with self.assertRaises(IOError) as ce: ofile.write(data, psizes=[(13, 13)]) + def test_codeblock_size_not_multiple_of_two(self): + # Seems like code block sizes should be powers of two. + ifile = Jp2k(self.jp2file) + data = ifile.read(reduce=3) + with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: + ofile = Jp2k(tfile.name, 'wb') + with self.assertRaises(IOError) as ce: + ofile.write(data, cbsize=(13, 12)) + + def test_codeblock_size_with_precinct_size(self): + # Seems like code block sizes should never exceed half that of + # precinct size. + ifile = Jp2k(self.jp2file) + data = ifile.read(reduce=3) + with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: + ofile = Jp2k(tfile.name, 'wb') + with self.assertRaises(IOError) as ce: + ofile.write(data, + cbsize=(64, 64), + psizes=[(64, 64)]) + if __name__ == "__main__": unittest.main()