If palette columns are the same width, read it in one step. #210

Should be more efficient, hopefully.
This commit is contained in:
John Evans 2014-04-02 10:35:24 -04:00
commit 8e6dc486da

View file

@ -1933,27 +1933,43 @@ class PaletteBox(Jp2kBox):
# Need to determine bps and signed or not # Need to determine bps and signed or not
read_buffer = fptr.read(num_columns) read_buffer = fptr.read(num_columns)
data = struct.unpack('>' + 'B' * num_columns, read_buffer) bps_signed = struct.unpack('>' + 'B' * num_columns, read_buffer)
bps = [((x & 0x7f) + 1) for x in data] bps = [((x & 0x7f) + 1) for x in bps_signed]
signed = [((x & 0x80) > 1) for x in data] signed = [((x & 0x80) > 1) for x in bps_signed]
fmt = '>' if any(b != bps_signed[0] for b in bps_signed):
for bits in bps: # Ok the palette has the same datatype for all columns. We should
if bits <= 8: # be able to efficiently read it.
fmt += 'B' if bps <= 8:
elif bits <= 16: dtype = np.uint8
fmt += 'H' elif bps <= 16:
elif bits <= 32: dtype = np.uint16
fmt += 'I' elif bps <= 32:
dtype = np.uint32
read_buffer = fptr.read(num_entries * np.sum(bps) / 8)
palette = np.frombuffer(read_buffer, dtype)
palette.reshape((num_entries, num_columns))
# Each palette component is padded out to the next largest byte. else:
# That means a list comprehension does this in one shot. # General case where the columns may not be the same width.
row_nbytes = sum([int(math.ceil(x/8.0)) for x in bps]) fmt = '>'
for bits in bps:
if bits <= 8:
fmt += 'B'
elif bits <= 16:
fmt += 'H'
elif bits <= 32:
fmt += 'I'
read_buffer = fptr.read(num_entries * row_nbytes) # Each palette component is padded out to the next largest byte.
palette = np.zeros((num_entries, num_columns), dtype=np.int32) # That means a list comprehension does this in one shot.
for j in range(num_entries): row_nbytes = sum([int(math.ceil(x/8.0)) for x in bps])
palette[j] = struct.unpack_from(fmt, read_buffer,
read_buffer = fptr.read(num_entries * row_nbytes)
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) offset=j * row_nbytes)
return cls(palette, bps, signed, length=length, offset=offset) return cls(palette, bps, signed, length=length, offset=offset)