From 7f6081113563cc48b2b8dcab6a76c04e9f708d8b Mon Sep 17 00:00:00 2001 From: jevans Date: Sat, 13 Sep 2014 09:31:11 -0400 Subject: [PATCH] More progress. All UTs passing on Mac/3.4.1/2.1.0 __getitem__ method needs a refactor. Need to test on JPX file with multiple images. --- glymur/jp2k.py | 49 ++++++++++++++++++++++++++++++++++------ glymur/test/test_jp2k.py | 35 ++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 6919555..68348ca 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -763,6 +763,15 @@ class Jp2k(Jp2kBox): """ Slicing protocol. """ + codestream = self.get_codestream(header_only=True) + if isinstance(pargs, int): + # Not a very good use of this protocol, but technically legal. + row = pargs + area = (row, 0, row + 1, codestream.segment[1].xsiz) + + # Take out the singleton row dimension. + return self.read(area=area).squeeze() + if isinstance(pargs, slice): # Case of jp2[:] # @@ -781,24 +790,50 @@ class Jp2k(Jp2kBox): else: bands = pargs[2] - if ((rows.step is None) and (cols.step is None)): - # Slicing with full resolution. - # This can be improved to take advantage of tiling. - return self.read()[rows, cols, bands] + if rows.step is None: + rows_step = 1 + else: + rows_step = rows.step - if rows.step != cols.step: + if cols.step is None: + cols_step = 1 + else: + cols_step = cols.step + + if rows_step != cols_step: msg = "Row and column strides must be the same." raise IndexError(msg) # Ok, reduce layer step is the same in both xy directions, so just take # one of them. - step = rows.step + step = rows_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 rows.start is None: + rows_start = 0 + else: + rows_start = rows.start + + if rows.stop is None: + rows_stop = codestream.segment[1].ysiz + else: + rows_stop = rows.stop + + if cols.start is None: + cols_start = 0 + else: + cols_start = cols.start + + if cols.stop is None: + cols_stop = codestream.segment[1].xsiz + else: + cols_stop = cols.stop + + area = (rows_start, cols_start, rows_stop, cols_stop) + data = self.read(area=area, rlevel=np.int(np.log2(step))) if len(pargs) == 2: return data diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 50b153a..e03181d 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -70,6 +70,11 @@ class TestSliceProtocol(unittest.TestCase): # Strides in x/y directions cannot differ. self.j2k[::2, ::3] + def test_resolution_strides_cannot_differ(self): + with self.assertRaises(IndexError): + # Strides in x/y directions cannot differ. + self.j2k[::2, ::3] + def test_resolution_strides_must_be_powers_of_two(self): with self.assertRaises(IndexError): self.j2k[::3, ::3] @@ -90,6 +95,11 @@ class TestSliceProtocol(unittest.TestCase): all = self.j2k.read(rlevel=1) np.testing.assert_array_equal(all[:,:,1:3], d) + def test_retrieve_single_row(self): + actual = self.jp2[0] + expected = self.jp2_data[0] + np.testing.assert_array_equal(actual, expected) + def test_full_resolution_slicing_by_quarters_upper_left(self): actual = self.jp2[:728, :1296] expected = self.jp2_data[:728, :1296] @@ -110,6 +120,11 @@ class TestSliceProtocol(unittest.TestCase): expected = self.jp2_data[728:, 1296:] np.testing.assert_array_equal(actual, expected) + def test_full_resolution_slicing_by_quarters_center(self): + actual = self.jp2[364:1092, 648:1942] + expected = self.jp2_data[364:1092, 648:1942] + np.testing.assert_array_equal(actual, expected) + def test_full_resolution_slicing_by_halves_left(self): actual = self.jp2[:, :1296] expected = self.jp2_data[:, :1296] @@ -130,6 +145,26 @@ class TestSliceProtocol(unittest.TestCase): expected = self.jp2_data[728:, :] np.testing.assert_array_equal(actual, expected) + def test_region_rlevel1(self): + actual = self.jp2[0:201:2, 0:201:2] + expected = self.jp2.read(area=(0, 0, 201, 201), rlevel=1) + np.testing.assert_array_equal(actual, expected) + + def test_region_rlevel1_slice_start_is_none(self): + actual = self.jp2[:201:2, :201:2] + expected = self.jp2.read(area=(0, 0, 201, 201), rlevel=1) + np.testing.assert_array_equal(actual, expected) + + def test_region_rlevel1_slice_stop_is_none(self): + actual = self.jp2[201::2, 201::2] + expected = self.jp2.read(area=(201, 201, 1456, 2592), rlevel=1) + np.testing.assert_array_equal(actual, expected) + + def test_region_rlevel1(self): + actual = self.jp2[0:202:2, 0:202:2] + expected = self.jp2.read(area=(0, 0, 202, 202), rlevel=1) + np.testing.assert_array_equal(actual, expected) + def test_slice_protocol_2d_reduce_resolution(self): d = self.j2k[:] self.assertEqual(d.shape, (800, 480, 3))