From 2d01875e7c9be1b2a550f143c542bd931fa7c821 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 9 Mar 2023 13:34:44 +1100 Subject: [PATCH] Added QOI reading --- Tests/images/hopper.qoi | Bin 0 -> 35651 bytes Tests/images/pil123rgba.qoi | Bin 0 -> 42827 bytes Tests/test_file_qoi.py | 28 +++++++ docs/handbook/image-file-formats.rst | 7 ++ docs/releasenotes/9.5.0.rst | 5 ++ src/PIL/QoiImagePlugin.py | 106 +++++++++++++++++++++++++++ src/PIL/__init__.py | 1 + 7 files changed, 147 insertions(+) create mode 100644 Tests/images/hopper.qoi create mode 100644 Tests/images/pil123rgba.qoi create mode 100644 Tests/test_file_qoi.py create mode 100644 src/PIL/QoiImagePlugin.py diff --git a/Tests/images/hopper.qoi b/Tests/images/hopper.qoi new file mode 100644 index 0000000000000000000000000000000000000000..6b255aba13babbe06be9be4b78dc62f47e5b4284 GIT binary patch literal 35651 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 W(eS-{pT)cf{D1iO8@w0)+5QiX6ZyIT literal 0 HcmV?d00001 diff --git a/Tests/test_file_qoi.py b/Tests/test_file_qoi.py new file mode 100644 index 000000000..d5c2f3926 --- /dev/null +++ b/Tests/test_file_qoi.py @@ -0,0 +1,28 @@ +import pytest + +from PIL import Image, QoiImagePlugin + +from .helper import assert_image_equal_tofile, assert_image_similar_tofile + + +class TestFileQOI: + def test_sanity(self): + with Image.open("Tests/images/hopper.qoi") as im: + assert im.mode == "RGB" + assert im.size == (128, 128) + assert im.format == "QOI" + + assert_image_equal_tofile(im, "Tests/images/hopper.png") + + with Image.open("Tests/images/pil123rgba.qoi") as im: + assert im.mode == "RGBA" + assert im.size == (162, 150) + assert im.format == "QOI" + + assert_image_similar_tofile(im, "Tests/images/pil123rgba.png", 0.03) + + def test_invalid_file(self): + invalid_file = "Tests/images/flower.jpg" + + with pytest.raises(SyntaxError): + QoiImagePlugin.QoiImageFile(invalid_file) diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 02224af34..27a624545 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -1544,6 +1544,13 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum .. versionadded:: 5.3.0 +QOI +^^^ + +.. versionadded:: 9.5.0 + +Pillow identifies and reads QOI images. + XV Thumbnails ^^^^^^^^^^^^^ diff --git a/docs/releasenotes/9.5.0.rst b/docs/releasenotes/9.5.0.rst index df2ec53fa..ebefc3df7 100644 --- a/docs/releasenotes/9.5.0.rst +++ b/docs/releasenotes/9.5.0.rst @@ -28,6 +28,11 @@ TODO API Additions ============= +QOI file format +^^^^^^^^^^^^^^^ + +Pillow can now read QOI images. + Added ``dpi`` argument when saving PDFs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/PIL/QoiImagePlugin.py b/src/PIL/QoiImagePlugin.py new file mode 100644 index 000000000..09aa1a1a4 --- /dev/null +++ b/src/PIL/QoiImagePlugin.py @@ -0,0 +1,106 @@ +# +# The Python Imaging Library. +# $Id$ +# +# QOI support for PIL +# +# See the README file for information on usage and redistribution. +# + +import os + +from . import Image, ImageFile +from ._binary import i32be as i32 +from ._binary import o8 + + +def _accept(prefix): + return prefix[:4] == b"qoif" + + +class QoiImageFile(ImageFile.ImageFile): + format = "QOI" + format_description = "Quite OK Image" + + def _open(self): + if not _accept(self.fp.read(4)): + msg = "not a QOI file" + raise SyntaxError(msg) + + self._size = tuple(i32(self.fp.read(4)) for i in range(2)) + + channels = self.fp.read(1)[0] + self.mode = "RGB" if channels == 3 else "RGBA" + + self.fp.seek(1, os.SEEK_CUR) # colorspace + self.tile = [("qoi", (0, 0) + self._size, self.fp.tell(), None)] + + +class QoiDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def _add_to_previous_pixels(self, value): + 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): + self._previously_seen_pixels = {} + self._previous_pixel = None + self._add_to_previous_pixels(b"".join(o8(i) for i in (0, 0, 0, 255))) + + data = bytearray() + bands = Image.getmodebands(self.mode) + while len(data) < self.state.xsize * self.state.ysize * bands: + byte = self.fd.read(1)[0] + if byte == 0b11111110: # QOI_OP_RGB + value = self.fd.read(3) + o8(255) + 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._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 += (self._previous_pixel[3],) + elif op == 3: # QOI_OP_RUN + run_length = (byte & 0b00111111) + 1 + value = self._previous_pixel + if bands == 3: + 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: + value = value[:3] + data += value + self.set_as_raw(bytes(data)) + return -1, 0 + + +Image.register_open(QoiImageFile.format, QoiImageFile, _accept) +Image.register_decoder("qoi", QoiDecoder) +Image.register_extension(QoiImageFile.format, ".qoi") diff --git a/src/PIL/__init__.py b/src/PIL/__init__.py index 0e6f82092..32d2381f3 100644 --- a/src/PIL/__init__.py +++ b/src/PIL/__init__.py @@ -59,6 +59,7 @@ _plugins = [ "PngImagePlugin", "PpmImagePlugin", "PsdImagePlugin", + "QoiImagePlugin", "SgiImagePlugin", "SpiderImagePlugin", "SunImagePlugin",