diff --git a/CHANGES.txt b/CHANGES.txt index a65c20a..894a103 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,8 @@ -Feb 01, 2014 - Added read support for JPX free, number list, data reference, +Feb 03, 2014 - Added read support for JPX free, number list, data reference, fragment table, and fragment list boxes. Palette box now a 2D numpy array instead of a list of 1D arrays. JP2 super box constructors now take - optional box list argument. + optional box list argument. Fixed bug where JPX files with more than one + codestream but advertising jp2 compatibility were not being read. Jan 28, 2014 - v0.5.10 Fixed bad warning when reader requirements box mask length is unsupported. diff --git a/glymur/jp2k.py b/glymur/jp2k.py index a9927da..3fd9d21 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -1027,16 +1027,20 @@ class Jp2k(Jp2kBox): Raises ------ IOError - If the file is JPX with more than one codestream. + If the file is JPX with more than one codestream and no JP2 + compatibility is advertised. """ with open(self.filename, 'rb') as fptr: if self._codec_format == opj2.CODEC_J2K: codestream = Codestream(fptr, self.length, header_only=header_only) else: + ftyp = self.box[1] box = [x for x in self.box if x.box_id == 'jp2c'] - if len(box) != 1: - msg = "JP2 files must have a single codestream." + if len(box) > 1 and 'jp2 ' not in ftyp.compatibility_list: + msg = "If more than one codestream exists, JP2 " + msg += "compatibiltity must be advertised by the FileType " + msg += "box." raise RuntimeError(msg) fptr.seek(box[0].offset) read_buffer = fptr.read(8) diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 15da73d..9ebe774 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -63,6 +63,7 @@ class TestJp2k(unittest.TestCase): def setUp(self): self.jp2file = glymur.data.nemo() self.j2kfile = glymur.data.goodstuff() + self.jpxfile = glymur.data.jpxfile() def tearDown(self): pass @@ -374,6 +375,15 @@ class TestJp2k(unittest.TestCase): attr_value = elt.attrib['{0}CreatorTool'.format(ns1)] self.assertEqual(attr_value, 'glymur') + def test_jpx_mult_codestreams_jp2_brand(self): + """Read JPX codestream when jp2-compatible.""" + # The file in question has multiple codestreams. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + jpx = Jp2k(self.jpxfile) + data = jpx.read() + self.assertEqual(data.shape, (1024, 1024, 3)) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_unrecognized_exif_tag(self): """An unrecognized exif tag should be handled gracefully."""