Merge branch 'devel' into issue104
This commit is contained in:
commit
1b09fd8eaa
2 changed files with 29 additions and 82 deletions
|
|
@ -1193,8 +1193,8 @@ class PaletteBox(Jp2kBox):
|
|||
offset of the box from the start of the file.
|
||||
longname : str
|
||||
more verbose description of the box.
|
||||
palette : list
|
||||
Colormap represented as list of 1D arrays, one per color component.
|
||||
palette : ndarray
|
||||
Colormap array.
|
||||
"""
|
||||
def __init__(self, palette, bits_per_component, signed, length=0,
|
||||
offset=-1):
|
||||
|
|
@ -1207,8 +1207,7 @@ class PaletteBox(Jp2kBox):
|
|||
|
||||
def __str__(self):
|
||||
msg = Jp2kBox.__str__(self)
|
||||
msg += '\n Size: ({0} x {1})'.format(len(self.palette[0]),
|
||||
len(self.palette))
|
||||
msg += '\n Size: ({0} x {1})'.format(*self.palette.shape)
|
||||
return msg
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -1238,68 +1237,29 @@ class PaletteBox(Jp2kBox):
|
|||
bps = [((x & 0x07f) + 1) for x in data]
|
||||
signed = [((x & 0x80) > 1) for x in data]
|
||||
|
||||
fmt = '>'
|
||||
for bits in bps:
|
||||
if bits <= 8:
|
||||
fmt += 'B'
|
||||
elif bits <= 16:
|
||||
fmt += 'H'
|
||||
elif bits <= 32:
|
||||
fmt += 'I'
|
||||
|
||||
# Each palette component is padded out to the next largest byte.
|
||||
# That means a list comprehension does this in one shot.
|
||||
row_nbytes = sum([int(math.ceil(x/8.0)) for x in bps])
|
||||
|
||||
# Form the format string so that we can intelligently unpack the
|
||||
# colormap. We have to do this because it is possible that the
|
||||
# colormap columns could have different datatypes.
|
||||
#
|
||||
# This means that we store the palette as a list of 1D arrays,
|
||||
# which reverses the usual indexing scheme.
|
||||
read_buffer = fptr.read(num_entries * row_nbytes)
|
||||
palette = _buffer2palette(read_buffer, num_entries, num_columns, bps)
|
||||
palette = np.zeros((num_entries, num_columns), dtype=np.int32)
|
||||
for j in range(num_entries):
|
||||
palette[j] = struct.unpack_from(fmt, read_buffer,
|
||||
offset=j * row_nbytes)
|
||||
|
||||
box = PaletteBox(palette, bps, signed, length=length, offset=offset)
|
||||
return box
|
||||
|
||||
|
||||
def _buffer2palette(read_buffer, num_rows, num_cols, bps):
|
||||
"""Construct the palette from the buffer read from file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
read_buffer : iterable
|
||||
Byte array of palette information read from file.
|
||||
num_rows, num_cols : int
|
||||
Size of palette.
|
||||
bps : iterable
|
||||
Bits per sample for each channel.
|
||||
|
||||
Returns
|
||||
-------
|
||||
palette : list of 1D arrays
|
||||
Each 1D array corresponds to a channel.
|
||||
"""
|
||||
row_nbytes = 0
|
||||
palette = []
|
||||
fmt = '>'
|
||||
for j in range(num_cols):
|
||||
if bps[j] <= 8:
|
||||
row_nbytes += 1
|
||||
fmt += 'B'
|
||||
palette.append(np.zeros(num_rows, dtype=np.uint8))
|
||||
elif bps[j] <= 16:
|
||||
row_nbytes += 2
|
||||
fmt += 'H'
|
||||
palette.append(np.zeros(num_rows, dtype=np.uint16))
|
||||
elif bps[j] <= 32:
|
||||
row_nbytes += 4
|
||||
fmt += 'I'
|
||||
palette.append(np.zeros(num_rows, dtype=np.uint32))
|
||||
else:
|
||||
msg = 'Unsupported palette bitdepth (%d).'.format(bps[j])
|
||||
raise IOError(msg)
|
||||
|
||||
for j in range(num_rows):
|
||||
row_buffer = read_buffer[(row_nbytes * j):(row_nbytes * (j + 1))]
|
||||
row = struct.unpack(fmt, row_buffer)
|
||||
for k in range(num_cols):
|
||||
palette[k][j] = row[k]
|
||||
|
||||
return palette
|
||||
|
||||
# Map rreq codes to display text.
|
||||
_READER_REQUIREMENTS_DISPLAY = {
|
||||
0: 'File not completely understood',
|
||||
|
|
|
|||
|
|
@ -3797,19 +3797,16 @@ class TestSuiteDump(unittest.TestCase):
|
|||
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
|
||||
|
||||
# Palette box.
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette), 3)
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette[0]), 256)
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette[1]), 256)
|
||||
self.assertEqual(len(jp2.box[2].box[1].palette[2]), 256)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0][0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[1][0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[2][0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0][128], 73)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[1][128], 92)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[2][128], 53)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0][-1], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[1][-1], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[2][-1], 245)
|
||||
self.assertEqual(jp2.box[2].box[1].palette.shape, (256, 3))
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0, 0], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0, 1], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[0, 2], 0)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[128, 0], 73)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[128, 1], 92)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[128, 2], 53)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[255, 0], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[255, 1], 245)
|
||||
np.testing.assert_array_equal(jp2.box[2].box[1].palette[255, 2], 245)
|
||||
|
||||
# Component mapping box
|
||||
self.assertEqual(jp2.box[2].box[2].component_index, (0, 0, 0))
|
||||
|
|
@ -5699,10 +5696,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
|
||||
# Jp2 Header
|
||||
# Palette box.
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette), 3)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[0]), 256)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[1]), 256)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[2]), 256)
|
||||
self.assertEqual(jp2.box[3].box[2].palette.shape, (256, 3))
|
||||
|
||||
# Jp2 Header
|
||||
# Component mapping box
|
||||
|
|
@ -6127,11 +6121,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
|
||||
# Jp2 Header
|
||||
# Palette box.
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette), 4)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[0]), 1)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[1]), 1)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[2]), 1)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[3]), 1)
|
||||
self.assertEqual(jp2.box[3].box[2].palette.shape, (1, 4))
|
||||
|
||||
# Jp2 Header
|
||||
# Component mapping box
|
||||
|
|
@ -6242,10 +6232,7 @@ class TestSuiteDump(unittest.TestCase):
|
|||
# Jp2 Header
|
||||
# Palette box.
|
||||
# 3 columns with 16 entries.
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette), 3)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[0]), 16)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[1]), 16)
|
||||
self.assertEqual(len(jp2.box[3].box[2].palette[2]), 16)
|
||||
self.assertEqual(jp2.box[3].box[2].palette.shape, (16, 3))
|
||||
|
||||
# Jp2 Header
|
||||
# Component mapping box
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue