__keyitem__ parameter now assumed to be either integer or slice. No
longer erroring out when mixing resolution reduction with horiz/vert slicing, but neither is it tested.
This commit is contained in:
parent
79a0b7edb8
commit
f7b7b9a0df
2 changed files with 34 additions and 54 deletions
|
|
@ -759,60 +759,51 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
return boxes
|
return boxes
|
||||||
|
|
||||||
def __getitem__(self, *pargs):
|
def __getitem__(self, pargs):
|
||||||
"""
|
"""
|
||||||
Slicing protocol.
|
Slicing protocol.
|
||||||
"""
|
"""
|
||||||
if isinstance(pargs[0], slice):
|
if isinstance(pargs, slice):
|
||||||
|
# Case of jp2[:]
|
||||||
|
#
|
||||||
# Should have a slice object where start = stop = step = None
|
# Should have a slice object where start = stop = step = None
|
||||||
slc = pargs[0]
|
slc = pargs
|
||||||
if slc.start is None and slc.stop is None and slc.step is None:
|
if slc.start is None and slc.stop is None and slc.step is None:
|
||||||
return self.read()
|
return self.read()
|
||||||
else:
|
else:
|
||||||
raise IndexError("Illegal syntax.")
|
raise IndexError("Illegal syntax.")
|
||||||
|
|
||||||
if not isinstance(pargs[0], tuple):
|
# Assuming pargs is a tuple from now on.
|
||||||
msg = "Unexpected situation, slicing invoked, but not passed "
|
rows = pargs[0]
|
||||||
msg += "a slice or tuple."
|
cols = pargs[1]
|
||||||
raise RuntimeError(msg)
|
if len(pargs) == 2:
|
||||||
|
bands = slice(None, None, None)
|
||||||
|
else:
|
||||||
|
bands = pargs[2]
|
||||||
|
|
||||||
# Assuming tuple from now on.
|
if ((rows.step is None) and (cols.step is None)):
|
||||||
ridx = pargs[0][0]
|
|
||||||
cidx = pargs[0][1]
|
|
||||||
bidx = pargs[0][2]
|
|
||||||
|
|
||||||
if ((ridx.step is None) and (cidx.step is None)):
|
|
||||||
# Slicing with full resolution.
|
# Slicing with full resolution.
|
||||||
return self.read()[ridx, cidx, bidx]
|
# This can be improved to take advantage of tiling.
|
||||||
|
return self.read()[rows, cols, bands]
|
||||||
|
|
||||||
if ((ridx.start is not None) or
|
if rows.step != cols.step:
|
||||||
(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."
|
msg = "Row and column strides must be the same."
|
||||||
raise IndexError(msg)
|
raise IndexError(msg)
|
||||||
else:
|
|
||||||
step = ridx.step
|
# Ok, reduce layer step is the same in both xy directions, so just take
|
||||||
|
# one of them.
|
||||||
|
step = rows.step
|
||||||
|
|
||||||
if np.log2(step) != np.floor(np.log2(step)):
|
if np.log2(step) != np.floor(np.log2(step)):
|
||||||
msg = "Row and column strides must be powers of 2."
|
msg = "Row and column strides must be powers of 2."
|
||||||
raise IndexError(msg)
|
raise IndexError(msg)
|
||||||
|
|
||||||
data = self.read(rlevel=np.int(np.log2(step)))
|
data = self.read(rlevel=np.int(np.log2(step)))
|
||||||
if len(pargs[0]) == 2:
|
if len(pargs) == 2:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# Ok, 3 arguments in pargs.
|
# Ok, 3 arguments in pargs.
|
||||||
if isinstance(pargs[0][2], slice):
|
return data[:, :, bands]
|
||||||
return data[:,:,pargs[0][2]]
|
|
||||||
elif isinstance(pargs[0][2], int):
|
|
||||||
return data[:,:,pargs[0][2]]
|
|
||||||
|
|
||||||
|
|
||||||
def read(self, **kwargs):
|
def read(self, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -74,24 +74,11 @@ class TestSliceProtocol(unittest.TestCase):
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
self.j2k[::3, ::3]
|
self.j2k[::3, ::3]
|
||||||
|
|
||||||
def test_start_and_resolution_stride_not_allowed_at_same_time(self):
|
|
||||||
with self.assertRaises(IndexError):
|
|
||||||
self.j2k[2::2, 2::2]
|
|
||||||
|
|
||||||
def test_stop_and_resolution_stride_not_allowed_at_same_time(self):
|
|
||||||
with self.assertRaises(IndexError):
|
|
||||||
self.j2k[:8:2, :8:2]
|
|
||||||
|
|
||||||
def test_integer_index_in_3d(self):
|
def test_integer_index_in_3d(self):
|
||||||
|
|
||||||
d = self.j2k[:,:,0]
|
for j in [0, 1, 2]:
|
||||||
np.testing.assert_array_equal(self.j2k_data[:,:,0], d)
|
band = self.j2k[:, :, j]
|
||||||
|
np.testing.assert_array_equal(self.j2k_data[:, :, j], band)
|
||||||
d = self.j2k[:,:,1]
|
|
||||||
np.testing.assert_array_equal(self.j2k_data[:,:,1], d)
|
|
||||||
|
|
||||||
d = self.j2k[:,:,2]
|
|
||||||
np.testing.assert_array_equal(self.j2k_data[:,:,2], d)
|
|
||||||
|
|
||||||
def test_slice_in_third_dimension(self):
|
def test_slice_in_third_dimension(self):
|
||||||
actual = self.j2k[:,:,1:3]
|
actual = self.j2k[:,:,1:3]
|
||||||
|
|
@ -103,13 +90,15 @@ class TestSliceProtocol(unittest.TestCase):
|
||||||
all = self.j2k.read(rlevel=1)
|
all = self.j2k.read(rlevel=1)
|
||||||
np.testing.assert_array_equal(all[:,:,1:3], d)
|
np.testing.assert_array_equal(all[:,:,1:3], d)
|
||||||
|
|
||||||
def test_full_resolution_slicing_by_quarters(self):
|
def test_full_resolution_slicing_by_quarters_upper_left(self):
|
||||||
# upper left
|
actual = self.jp2[:728, :1296]
|
||||||
np.testing.assert_array_equal(self.jp2_data[:728, :1296],
|
expected = self.jp2_data[:728, :1296]
|
||||||
self.jp2[:728, :1296])
|
np.testing.assert_array_equal(actual, expected)
|
||||||
# lower left
|
|
||||||
np.testing.assert_array_equal(self.jp2_data[728:, :1296],
|
def test_full_resolution_slicing_by_quarters_lower_left(self):
|
||||||
self.jp2[728:, :1296])
|
actual = self.jp2[728:, :1296]
|
||||||
|
expected = self.jp2_data[728:, :1296]
|
||||||
|
np.testing.assert_array_equal(actual, expected)
|
||||||
|
|
||||||
def test_full_resolution_slicing_by_quarters_upper_right(self):
|
def test_full_resolution_slicing_by_quarters_upper_right(self):
|
||||||
actual = self.jp2[:728, 1296:]
|
actual = self.jp2[:728, 1296:]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue