From be0163f418470250e4977c0204181490c77ac65d Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 30 May 2013 15:44:32 -0400 Subject: [PATCH] Requiring precinct size to be a multiple of two. --- glymur/jp2k.py | 16 ++++++++++++---- glymur/test/test_opj_suite_neg.py | 13 ++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 6eb23fd..5c7e361 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -8,6 +8,7 @@ if sys.hexversion >= 0x03030000: else: from contextlib2 import ExitStack import ctypes +import math import os import struct import warnings @@ -181,7 +182,8 @@ class Jp2k(Jp2kBox): psnr : list, optional Different PSNR for successive layers. psizes : list, optional - List of precinct sizes. + List of precinct sizes. Each precinct size tuple is defined in + (height x width). sop : bool, optional If true, write SOP marker before each packet. subsam : tuple, optional @@ -266,9 +268,15 @@ class Jp2k(Jp2kBox): cparams.cp_fixed_quality = 1 if psizes is not None: - for j, precinct in enumerate(psizes): - cparams.prcw_init[j] = precinct[0] - cparams.prch_init[j] = precinct[1] + for j, (prch, prcw) in enumerate(psizes): + 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." + raise IOError(msg.format(prch, prcw)) + + cparams.prcw_init[j] = prcw + cparams.prch_init[j] = prch cparams.csty |= 0x01 cparams.res_spec = len(psizes) diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index 8296861..f33b981 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -9,6 +9,7 @@ import unittest import warnings import numpy as np +import pkg_resources from ..lib import openjp2 as opj2 @@ -62,7 +63,8 @@ def read_image(infile): class TestSuiteNegative(unittest.TestCase): def setUp(self): - pass + self.jp2file = pkg_resources.resource_filename(glymur.__name__, + "data/nemo.jp2") def tearDown(self): pass @@ -150,5 +152,14 @@ class TestSuiteNegative(unittest.TestCase): with self.assertWarns(UserWarning) as cw: j = Jp2k(infile) + def test_precinct_size_not_multiple_of_two(self): + # Seems like precinct size should be a multiple 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, psizes=[(13, 13)]) + if __name__ == "__main__": unittest.main()