X-Git-Url: https://git.ayoreis.com/hackapet/Adafruit_Blinka_Displayio.git/blobdiff_plain/213fe1e32c96fa57a3f45805433c011542385d95..HEAD:/displayio/_ondiskbitmap.py diff --git a/displayio/_ondiskbitmap.py b/displayio/_ondiskbitmap.py index f9e9e8b..00ea765 100644 --- a/displayio/_ondiskbitmap.py +++ b/displayio/_ondiskbitmap.py @@ -19,26 +19,15 @@ displayio for Blinka """ 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 """ @@ -46,9 +35,6 @@ class OnDiskBitmap: load times. These load times may result in frame tearing where only part of the image is visible. - It's easiest to use on a board with a built in display such as the `Hallowing M0 Express - `_. - .. code-block:: Python import board @@ -59,7 +45,7 @@ class OnDiskBitmap: board.DISPLAY.auto_brightness = False board.DISPLAY.brightness = 0 splash = displayio.Group() - board.DISPLAY.show(splash) + board.DISPLAY.root_group = splash odb = displayio.OnDiskBitmap(\'/sample.bmp\') face = displayio.TileGrid(odb, pixel_shader=odb.pixel_shader) @@ -102,31 +88,35 @@ class OnDiskBitmap: 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 @@ -136,7 +126,7 @@ class OnDiskBitmap: 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 @@ -144,16 +134,20 @@ class OnDiskBitmap: 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( + i, palette_data[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: " @@ -214,22 +208,6 @@ class OnDiskBitmap: 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 @@ -272,7 +250,6 @@ class OnDiskBitmap: 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