diff --git a/src/PIL/QoiImagePlugin.py b/src/PIL/QoiImagePlugin.py index e9fef37a9..f8aa720c1 100644 --- a/src/PIL/QoiImagePlugin.py +++ b/src/PIL/QoiImagePlugin.py @@ -11,7 +11,6 @@ import os from . import Image, ImageFile from ._binary import i32be as i32 -from ._binary import o8 def _accept(prefix): @@ -49,7 +48,7 @@ class QoiDecoder(ImageFile.PyDecoder): def decode(self, buffer): self._previously_seen_pixels = {} self._previous_pixel = None - self._add_to_previous_pixels(b"".join(o8(i) for i in (0, 0, 0, 255))) + self._add_to_previous_pixels(bytearray((0, 0, 0, 255))) data = bytearray() bands = Image.getmodebands(self.mode) @@ -57,34 +56,40 @@ class QoiDecoder(ImageFile.PyDecoder): while len(data) < dest_length: byte = self.fd.read(1)[0] if byte == 0b11111110: # QOI_OP_RGB - value = self.fd.read(3) + self._previous_pixel[3:] + value = bytearray(self.fd.read(3)) + self._previous_pixel[3:] elif byte == 0b11111111: # QOI_OP_RGBA value = self.fd.read(4) else: op = byte >> 6 if op == 0: # QOI_OP_INDEX op_index = byte & 0b00111111 - value = self._previously_seen_pixels.get(op_index, (0, 0, 0, 0)) - elif op == 1: # QOI_OP_DIFF - value = ( - (self._previous_pixel[0] + ((byte & 0b00110000) >> 4) - 2) - % 256, - (self._previous_pixel[1] + ((byte & 0b00001100) >> 2) - 2) - % 256, - (self._previous_pixel[2] + (byte & 0b00000011) - 2) % 256, + value = self._previously_seen_pixels.get( + op_index, bytearray((0, 0, 0, 0)) + ) + elif op == 1: # QOI_OP_DIFF + value = bytearray( + ( + (self._previous_pixel[0] + ((byte & 0b00110000) >> 4) - 2) + % 256, + (self._previous_pixel[1] + ((byte & 0b00001100) >> 2) - 2) + % 256, + (self._previous_pixel[2] + (byte & 0b00000011) - 2) % 256, + self._previous_pixel[3], + ) ) - value += (self._previous_pixel[3],) elif op == 2: # QOI_OP_LUMA second_byte = self.fd.read(1)[0] diff_green = (byte & 0b00111111) - 32 diff_red = ((second_byte & 0b11110000) >> 4) - 8 diff_blue = (second_byte & 0b00001111) - 8 - value = tuple( - (self._previous_pixel[i] + diff_green + diff) % 256 - for i, diff in enumerate((diff_red, 0, diff_blue)) + value = bytearray( + tuple( + (self._previous_pixel[i] + diff_green + diff) % 256 + for i, diff in enumerate((diff_red, 0, diff_blue)) + ) ) - value += (self._previous_pixel[3],) + value += self._previous_pixel[3:] elif op == 3: # QOI_OP_RUN run_length = (byte & 0b00111111) + 1 value = self._previous_pixel @@ -92,7 +97,6 @@ class QoiDecoder(ImageFile.PyDecoder): value = value[:3] data += value * run_length continue - value = b"".join(o8(i) for i in value) self._add_to_previous_pixels(value) if bands == 3: