Start QOI decoding with a zero-initialized array of previously seen pixels by radarhere · Pull Request #9008 · python-pillow/Pillow
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.