From 30219d01bf7058b81b6c8cb3998ecfafb57bc149 Mon Sep 17 00:00:00 2001 From: jevans Date: Mon, 8 Sep 2014 20:10:21 -0400 Subject: [PATCH] Basic functionality and UTs are in. --- glymur/jp2k.py | 45 +++++++++++++++++++++++++ glymur/test/test_jp2k.py | 72 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 4ebd678..8463eb5 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -759,6 +759,51 @@ class Jp2k(Jp2kBox): return boxes + def __getitem__(self, *pargs): + """ + """ + if isinstance(pargs[0], slice): + # Should have a slice object where start = stop = step = None + slc = pargs[0] + if slc.start is None and slc.stop is None and slc.step is None: + return self.read() + else: + raise IndexError("Illegal syntax.") + + if isinstance(pargs[0], tuple): + ridx = pargs[0][0] + cidx = pargs[0][1] + + if ((ridx.start is not None) or + (ridx.stop is not None) or + (cidx.start is not None) or + (cidx.stop is not None)): + msg = "Only strides are supported when slicing a Jp2k object." + raise IndexError(msg) + + if ridx.step is None and cidx.step is None: + step = 1 + elif ridx.step != cidx.step: + msg = "Row and column strides must be the same." + raise IndexError(msg) + else: + step = ridx.step + + if np.log2(step) != np.floor(np.log2(step)): + msg = "Row and column strides must be powers of 2." + raise IndexError(msg) + + data = self.read(rlevel=np.int(np.log2(step))) + if len(pargs[0]) == 2: + return data + + # Ok, 3 arguments in pargs. + if isinstance(pargs[0][2], slice): + return data[:,:,pargs[0][2]] + elif isinstance(pargs[0][2], int): + return data[:,:,pargs[0][2]] + + def read(self, **kwargs): """Read a JPEG 2000 image. diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 63492a5..9058bbf 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -63,6 +63,78 @@ class TestJp2k(unittest.TestCase): def tearDown(self): pass + def test_slice_protocol_negative(self): + """ + """ + j = Jp2k(self.j2kfile) + + with self.assertRaises(IndexError): + # Strides in x/y directions cannot differ. + d = j[::2, ::3] + + with self.assertRaises(IndexError): + # Strides in x/y direction must be powers of 2. + d = j[::3, ::3] + + # start and stop are not supported when slicing on Jp2k object + with self.assertRaises(IndexError): + d = j[2::2, 2::2] + with self.assertRaises(IndexError): + d = j[:8:2, :8:2] + with self.assertRaises(IndexError): + d = j[2:8:2, 2:8:2] + + def test_slice_protocol_3d(self): + """ + """ + j = Jp2k(self.j2kfile) + all = j.read() + + d = j[:,:,0] + np.testing.assert_array_equal(all[:,:,0], d) + + d = j[:,:,1] + np.testing.assert_array_equal(all[:,:,1], d) + + d = j[:,:,2] + np.testing.assert_array_equal(all[:,:,2], d) + + d = j[:,:,1:3] + np.testing.assert_array_equal(all[:,:,1:3], d) + + d = j[::2, ::2, 1:3] + all = j.read(rlevel=1) + np.testing.assert_array_equal(all[:,:,1:3], d) + + def test_slice_protocol_2d(self): + """ + + """ + j = Jp2k(self.j2kfile) + + d = j[:] + self.assertEqual(d.shape, (800, 480, 3)) + + # Stride of one. + d = j[::1, ::1] + self.assertEqual(d.shape, (800, 480, 3)) + + # Stride of 2. + d = j[::2, ::2] + self.assertEqual(d.shape, (400, 240, 3)) + + d = j[::4, ::4] + self.assertEqual(d.shape, (200, 120, 3)) + + d = j[::8, ::8] + self.assertEqual(d.shape, (100, 60, 3)) + + d = j[::16, ::16] + self.assertEqual(d.shape, (50, 30, 3)) + + d = j[::32, ::32] + self.assertEqual(d.shape, (25, 15, 3)) + @unittest.skipIf(os.name == "nt", "Unexplained failure on windows") def test_irreversible(self): """Irreversible"""