and self._cached_colorspace == colorspace
and self._cached_input_pixel == input_pixel.pixel
):
- output_color = self._cached_output_color
+ output_color.pixel = self._cached_output_color
return
rgb888_pixel = input_pixel
8 // self._core.colorspace.depth
)
- buffer = memoryview(bytearray([0] * (buffer_size * 4)))
- mask = memoryview(bytearray([0] * mask_length))
+ buffer = memoryview(bytearray([0] * (buffer_size * 4))).cast("I")
+ mask = memoryview(bytearray([0] * (mask_length * 4))).cast("I")
self._core.fill_area(subrectangle, mask, buffer)
# Can't acquire display bus; skip the rest of the data.
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"
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:
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
raise ValueError("Unable to read color palette data")
for i in range(number_of_colors):
- palette[i] = palette_data[i]
+ 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
self._colors = []
for _ in range(color_count):
- self._colors.append(self._make_color(0))
+ self._colors.append(ColorStruct())
@staticmethod
- def _make_color(value, transparent=False):
- color = ColorStruct(transparent=transparent)
-
+ def _color_to_int(value):
if isinstance(value, (tuple, list, bytes, bytearray)):
value = (value[0] & 0xFF) << 16 | (value[1] & 0xFF) << 8 | value[2] & 0xFF
elif isinstance(value, int):
raise ValueError("Color must be between 0x000000 and 0xFFFFFF")
else:
raise TypeError("Color buffer must be a buffer, tuple, list, or int")
- color.rgb888 = value
-
- return color
+ return value
def __len__(self) -> int:
"""Returns the number of colors in a Palette"""
(to represent an RGB value). Value can be an int, bytes (3 bytes (RGB) or
4 bytes (RGB + pad byte)), bytearray, or a tuple or list of 3 integers.
"""
- if self._colors[index].rgb888 == value:
+ self._set_color(index, self._color_to_int(value))
+
+ def _set_color(self, palette_index: int, color: int):
+ if self._colors[palette_index].rgb888 == color:
return
- self._colors[index] = self._make_color(value)
- self._colors[index].cached_colorspace = None
+ self._colors[palette_index].rgb888 = color
+ self._colors[palette_index].cached_colorspace = None
self._needs_refresh = True
def __getitem__(self, index: int) -> Optional[int]:
cached_colorspace_grayscale: bool = False
transparent: bool = False
- def rgba(self) -> tuple[int, int, int, int]:
- """Return the color as a tuple of red, green, blue, alpha"""
- return (
- self.rgb888 >> 16,
- (self.rgb888 >> 8) & 0xFF,
- self.rgb888 & 0xFF,
- 0 if self.transparent else 0xFF,
- )
-
null_transform = TransformStruct() # Use defaults
if not output_pixel.opaque:
full_coverage = False
else:
- mask[offset // 8] |= 1 << (offset % 8)
- # print("Mask", mask)
+ mask[offset // 32] |= 1 << (offset % 32)
if colorspace.depth == 16:
struct.pack_into(
"H",
- buffer,
+ buffer.cast("B"),
offset * 2,
output_pixel.pixel,
)
elif colorspace.depth == 32:
struct.pack_into(
"I",
- buffer,
+ buffer.cast("B"),
offset * 4,
output_pixel.pixel,
)