Skip to content

Conversation

radarhere
Copy link
Member

This originated in discussion at #9007

When starting to decode a QOI image, https://qoiformat.org/qoi-specification.pdf states that

The decoder and encoder start with {r: 0, g: 0, b: 0, a: 255} as the previous pixel value.

def _add_to_previous_pixels(self, value: bytes | bytearray) -> None:
self._previous_pixel = value
r, g, b, a = value
hash_value = (r * 3 + g * 5 + b * 7 + a * 11) % 64
self._previously_seen_pixels[hash_value] = value
def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]:
assert self.fd is not None
self._previously_seen_pixels = {}
self._add_to_previous_pixels(bytearray((0, 0, 0, 255)))

However, the part of the specification describing _previously_seen_pixels states that

A running array[64] (zero-initialized) of previously seen pixel values is maintained by the encoder and decoder.

While I don't think these two statements from specification fit together in the most natural way, the code that currently exists is not 'initialized' at zero exactly - we're starting out with the previous pixel value of (0, 0, 0, 255). This PR stops that.

@radarhere radarhere changed the title Start QOI decoding with an empty array of previously seen pixel values Start QOI decoding with a zero-initialized array of previously seen pixels Jun 10, 2025
@radarhere radarhere merged commit 7f7c27f into python-pillow:main Jun 11, 2025
55 checks passed
@radarhere radarhere deleted the qoi branch June 11, 2025 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants