"""
from typing import Union, BinaryIO
+from ._helpers import read_word
from ._colorconverter import ColorConverter
+from ._colorspace import Colorspace
from ._palette import Palette
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git"
-def _read_uint32(buffer: bytes, idx: int) -> int:
- return (
- buffer[idx]
- | buffer[idx + 1] << 8
- | buffer[idx + 2] << 16
- | buffer[idx + 3] << 24
- )
-
-
-def _read_word(header: bytes, idx: int) -> int:
- return _read_uint32(header, idx * 2)
-
-
class OnDiskBitmap:
# pylint: disable=too-many-instance-attributes
"""
try:
self._file = file
file.seek(0)
- bmp_header = file.read(138)
+ bmp_header = memoryview(file.read(138)).cast(
+ "H"
+ ) # cast as unsigned 16-bit int
- if len(bmp_header) != 138 or bmp_header[0:2] != b"BM":
+ if len(bmp_header.tobytes()) != 138 or bmp_header.tobytes()[0:2] != b"BM":
raise ValueError("Invalid BMP file")
- self._data_offset = _read_word(bmp_header, 5)
+ self._data_offset = read_word(bmp_header, 5)
- header_size = _read_word(bmp_header, 7)
- bits_per_pixel = bmp_header[14 * 2] | bmp_header[14 * 2 + 1] << 8
- compression = _read_word(bmp_header, 15)
- number_of_colors = _read_word(bmp_header, 23)
+ header_size = read_word(bmp_header, 7)
+ bits_per_pixel = bmp_header[14]
+ compression = read_word(bmp_header, 15)
+ number_of_colors = read_word(bmp_header, 23)
indexed = bits_per_pixel <= 8
self._bitfield_compressed = compression == 3
self._bits_per_pixel = bits_per_pixel
- self._width = _read_word(bmp_header, 9)
- self._height = _read_word(bmp_header, 11)
+ self._width = read_word(bmp_header, 9)
+ self._height = read_word(bmp_header, 11)
- self._colorconverter = ColorConverter()
+ self._pixel_shader_base = ColorConverter(
+ input_colorspace=Colorspace.RGB888, dither=False
+ )
if bits_per_pixel == 16:
if header_size >= 56 or self._bitfield_compressed:
- self._r_bitmask = _read_word(bmp_header, 27)
- self._g_bitmask = _read_word(bmp_header, 29)
- self._b_bitmask = _read_word(bmp_header, 31)
+ self._r_bitmask = read_word(bmp_header, 27)
+ self._g_bitmask = read_word(bmp_header, 29)
+ self._b_bitmask = read_word(bmp_header, 31)
else:
# No compression or short header mean 5:5:5
self._r_bitmask = 0x7C00
if number_of_colors == 0:
number_of_colors = 1 << bits_per_pixel
- palette = Palette(number_of_colors)
+ palette = Palette(number_of_colors, dither=False)
if number_of_colors > 1:
palette_size = number_of_colors * 4
file.seek(palette_offset)
- palette_data = file.read(palette_size)
- if len(palette_data) != palette_size:
+ palette_data = memoryview(file.read(palette_size)).cast(
+ "I"
+ ) # cast as unsigned 32-bit int
+ if len(palette_data.tobytes()) != palette_size:
raise ValueError("Unable to read color palette data")
for i in range(number_of_colors):
- palette[i] = _read_uint32(palette_data, i * 4)
+ palette._set_color(
+ palette_data[i], i
+ ) # pylint: disable=protected-access
else:
- palette[0] = 0x000000
- palette[1] = 0xFFFFFF
- self._palette = palette
+ palette._set_color(0x000000, 0) # pylint: disable=protected-access
+ palette._set_color(0xFFFFFF, 1) # pylint: disable=protected-access
+ self._pixel_shader_base = palette
elif header_size not in (12, 40, 108, 124):
raise ValueError(
"Only Windows format, uncompressed BMP supported: "
return self._pixel_shader_base
- @property
- def _colorconverter(self) -> ColorConverter:
- return self._pixel_shader_base
-
- @_colorconverter.setter
- def _colorconverter(self, colorconverter: ColorConverter) -> None:
- self._pixel_shader_base = colorconverter
-
- @property
- def _palette(self) -> Palette:
- return self._pixel_shader_base
-
- @_palette.setter
- def _palette(self, palette: Palette) -> None:
- self._pixel_shader_base = palette
-
def _get_pixel(self, x: int, y: int) -> int:
if not (0 <= x < self.width and 0 <= y < self.height):
return 0
return red << 19 | green << 10 | blue << 3
if bytes_per_pixel == 4 and self._bitfield_compressed:
return pixel_data[0] | pixel_data[1] << 8 | pixel_data[2] << 16
-
pixel = pixel_data[0] | pixel_data[1] << 8 | pixel_data[2] << 16
if bytes_per_pixel == 4:
pixel |= pixel_data[3] << 24