We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
PyQt6 Support
Hi everyone!. I'm updating my app to PyQt6 and found a problem.

ImageQt.ImageQt class raises an error when try to use with QPainter:

```pycon
>>> page_image = ImageQt.ImageQt(page)
>>> painter = QtGui.QPainter()
>>> painter.begin(page_image)
TypeError: begin(self, QPaintDevice): argument 1 has unexpected type 'ImageQt'
```

Regards

Python 3.8.6
Ubuntu 20.04
PyQt6 6.0.1
Pillow 8.1.0

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/PIL/ImageQt.py`
Content:
```
1 #
2 # The Python Imaging Library.
3 # $Id$
4 #
5 # a simple Qt image interface.
6 #
7 # history:
8 # 2006-06-03 fl: created
9 # 2006-06-04 fl: inherit from QImage instead of wrapping it
10 # 2006-06-05 fl: removed toimage helper; move string support to ImageQt
11 # 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com)
12 #
13 # Copyright (c) 2006 by Secret Labs AB
14 # Copyright (c) 2006 by Fredrik Lundh
15 #
16 # See the README file for information on usage and redistribution.
17 #
18 
19 import sys
20 from io import BytesIO
21 
22 from . import Image
23 from ._util import isPath
24 
25 qt_versions = [
26     ["side6", "PySide6"],
27     ["5", "PyQt5"],
28     ["side2", "PySide2"],
29 ]
30 
31 # If a version has already been imported, attempt it first
32 qt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)
33 for qt_version, qt_module in qt_versions:
34     try:
35         if qt_module == "PySide6":
36             from PySide6.QtCore import QBuffer, QIODevice
37             from PySide6.QtGui import QImage, QPixmap, qRgba
38         elif qt_module == "PyQt5":
39             from PyQt5.QtCore import QBuffer, QIODevice
40             from PyQt5.QtGui import QImage, QPixmap, qRgba
41         elif qt_module == "PySide2":
42             from PySide2.QtCore import QBuffer, QIODevice
43             from PySide2.QtGui import QImage, QPixmap, qRgba
44     except (ImportError, RuntimeError):
45         continue
46     qt_is_installed = True
47     break
48 else:
49     qt_is_installed = False
50     qt_version = None
51 
52 
53 def rgb(r, g, b, a=255):
54     """(Internal) Turns an RGB color into a Qt compatible color integer."""
55     # use qRgb to pack the colors, and then turn the resulting long
56     # into a negative integer with the same bitpattern.
57     return qRgba(r, g, b, a) & 0xFFFFFFFF
58 
59 
60 def fromqimage(im):
61     """
62     :param im: A PIL Image object, or a file name
63     (given either as Python string or a PyQt string object)
64     """
65     buffer = QBuffer()
66     buffer.open(QIODevice.ReadWrite)
67     # preserve alpha channel with png
68     # otherwise ppm is more friendly with Image.open
69     if im.hasAlphaChannel():
70         im.save(buffer, "png")
71     else:
72         im.save(buffer, "ppm")
73 
74     b = BytesIO()
75     b.write(buffer.data())
76     buffer.close()
77     b.seek(0)
78 
79     return Image.open(b)
80 
81 
82 def fromqpixmap(im):
83     return fromqimage(im)
84     # buffer = QBuffer()
85     # buffer.open(QIODevice.ReadWrite)
86     # # im.save(buffer)
87     # # What if png doesn't support some image features like animation?
88     # im.save(buffer, 'ppm')
89     # bytes_io = BytesIO()
90     # bytes_io.write(buffer.data())
91     # buffer.close()
92     # bytes_io.seek(0)
93     # return Image.open(bytes_io)
94 
95 
96 def align8to32(bytes, width, mode):
97     """
98     converts each scanline of data from 8 bit to 32 bit aligned
99     """
100 
101     bits_per_pixel = {"1": 1, "L": 8, "P": 8}[mode]
102 
103     # calculate bytes per line and the extra padding if needed
104     bits_per_line = bits_per_pixel * width
105     full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)
106     bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)
107 
108     extra_padding = -bytes_per_line % 4
109 
110     # already 32 bit aligned by luck
111     if not extra_padding:
112         return bytes
113 
114     new_data = []
115     for i in range(len(bytes) // bytes_per_line):
116         new_data.append(
117             bytes[i * bytes_per_line : (i + 1) * bytes_per_line]
118             + b"\x00" * extra_padding
119         )
120 
121     return b"".join(new_data)
122 
123 
124 def _toqclass_helper(im):
125     data = None
126     colortable = None
127 
128     # handle filename, if given instead of image name
129     if hasattr(im, "toUtf8"):
130         # FIXME - is this really the best way to do this?
131         im = str(im.toUtf8(), "utf-8")
132     if isPath(im):
133         im = Image.open(im)
134 
135     if im.mode == "1":
136         format = QImage.Format_Mono
137     elif im.mode == "L":
138         format = QImage.Format_Indexed8
139         colortable = []
140         for i in range(256):
141             colortable.append(rgb(i, i, i))
142     elif im.mode == "P":
143         format = QImage.Format_Indexed8
144         colortable = []
145         palette = im.getpalette()
146         for i in range(0, len(palette), 3):
147             colortable.append(rgb(*palette[i : i + 3]))
148     elif im.mode == "RGB":
149         data = im.tobytes("raw", "BGRX")
150         format = QImage.Format_RGB32
151     elif im.mode == "RGBA":
152         data = im.tobytes("raw", "BGRA")
153         format = QImage.Format_ARGB32
154     else:
155         raise ValueError(f"unsupported image mode {repr(im.mode)}")
156 
157     __data = data or align8to32(im.tobytes(), im.size[0], im.mode)
158     return {"data": __data, "im": im, "format": format, "colortable": colortable}
159 
160 
161 if qt_is_installed:
162 
163     class ImageQt(QImage):
164         def __init__(self, im):
165             """
166             An PIL image wrapper for Qt.  This is a subclass of PyQt's QImage
167             class.
168 
169             :param im: A PIL Image object, or a file name (given either as
170                 Python string or a PyQt string object).
171             """
172             im_data = _toqclass_helper(im)
173             # must keep a reference, or Qt will crash!
174             # All QImage constructors that take data operate on an existing
175             # buffer, so this buffer has to hang on for the life of the image.
176             # Fixes https://github.com/python-pillow/Pillow/issues/1370
177             self.__data = im_data["data"]
178             super().__init__(
179                 self.__data,
180                 im_data["im"].size[0],
181                 im_data["im"].size[1],
182                 im_data["format"],
183             )
184             if im_data["colortable"]:
185                 self.setColorTable(im_data["colortable"])
186 
187 
188 def toqimage(im):
189     return ImageQt(im)
190 
191 
192 def toqpixmap(im):
193     # # This doesn't work. For now using a dumb approach.
194     # im_data = _toqclass_helper(im)
195     # result = QPixmap(im_data['im'].size[0], im_data['im'].size[1])
196     # result.loadFromData(im_data['data'])
197     # Fix some strange bug that causes
198     if im.mode == "RGB":
199         im = im.convert("RGBA")
200 
201     qimage = toqimage(im)
202     return QPixmap.fromImage(qimage)
203
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py
--- a/src/PIL/ImageQt.py
+++ b/src/PIL/ImageQt.py
@@ -23,6 +23,7 @@
 from ._util import isPath
 
 qt_versions = [
+    ["6", "PyQt6"],
     ["side6", "PySide6"],
     ["5", "PyQt5"],
     ["side2", "PySide2"],
@@ -32,7 +33,10 @@
 qt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)
 for qt_version, qt_module in qt_versions:
     try:
-        if qt_module == "PySide6":
+        if qt_module == "PyQt6":
+            from PyQt6.QtCore import QBuffer, QIODevice
+            from PyQt6.QtGui import QImage, QPixmap, qRgba
+        elif qt_module == "PySide6":
             from PySide6.QtCore import QBuffer, QIODevice
             from PySide6.QtGui import QImage, QPixmap, qRgba
         elif qt_module == "PyQt5":
@@ -63,7 +67,8 @@
     (given either as Python string or a PyQt string object)
     """
     buffer = QBuffer()
-    buffer.open(QIODevice.ReadWrite)
+    qt_openmode = QIODevice.OpenMode if qt_version == "6" else QIODevice
+    buffer.open(qt_openmode.ReadWrite)
     # preserve alpha channel with png
     # otherwise ppm is more friendly with Image.open
     if im.hasAlphaChannel():
@@ -132,25 +137,26 @@
     if isPath(im):
         im = Image.open(im)
 
+    qt_format = QImage.Format if qt_version == "6" else QImage
     if im.mode == "1":
-        format = QImage.Format_Mono
+        format = qt_format.Format_Mono
     elif im.mode == "L":
-        format = QImage.Format_Indexed8
+        format = qt_format.Format_Indexed8
         colortable = []
         for i in range(256):
             colortable.append(rgb(i, i, i))
     elif im.mode == "P":
-        format = QImage.Format_Indexed8
+        format = qt_format.Format_Indexed8
         colortable = []
         palette = im.getpalette()
         for i in range(0, len(palette), 3):
             colortable.append(rgb(*palette[i : i + 3]))
     elif im.mode == "RGB":
         data = im.tobytes("raw", "BGRX")
-        format = QImage.Format_RGB32
+        format = qt_format.Format_RGB32
     elif im.mode == "RGBA":
         data = im.tobytes("raw", "BGRA")
-        format = QImage.Format_ARGB32
+        format = qt_format.Format_ARGB32
     else:
         raise ValueError(f"unsupported image mode {repr(im.mode)}")

{"golden_diff": "diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py\n--- a/src/PIL/ImageQt.py\n+++ b/src/PIL/ImageQt.py\n@@ -23,6 +23,7 @@\n from ._util import isPath\n \n qt_versions = [\n+    [\"6\", \"PyQt6\"],\n     [\"side6\", \"PySide6\"],\n     [\"5\", \"PyQt5\"],\n     [\"side2\", \"PySide2\"],\n@@ -32,7 +33,10 @@\n qt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)\n for qt_version, qt_module in qt_versions:\n     try:\n-        if qt_module == \"PySide6\":\n+        if qt_module == \"PyQt6\":\n+            from PyQt6.QtCore import QBuffer, QIODevice\n+            from PyQt6.QtGui import QImage, QPixmap, qRgba\n+        elif qt_module == \"PySide6\":\n             from PySide6.QtCore import QBuffer, QIODevice\n             from PySide6.QtGui import QImage, QPixmap, qRgba\n         elif qt_module == \"PyQt5\":\n@@ -63,7 +67,8 @@\n     (given either as Python string or a PyQt string object)\n     \"\"\"\n     buffer = QBuffer()\n-    buffer.open(QIODevice.ReadWrite)\n+    qt_openmode = QIODevice.OpenMode if qt_version == \"6\" else QIODevice\n+    buffer.open(qt_openmode.ReadWrite)\n     # preserve alpha channel with png\n     # otherwise ppm is more friendly with Image.open\n     if im.hasAlphaChannel():\n@@ -132,25 +137,26 @@\n     if isPath(im):\n         im = Image.open(im)\n \n+    qt_format = QImage.Format if qt_version == \"6\" else QImage\n     if im.mode == \"1\":\n-        format = QImage.Format_Mono\n+        format = qt_format.Format_Mono\n     elif im.mode == \"L\":\n-        format = QImage.Format_Indexed8\n+        format = qt_format.Format_Indexed8\n         colortable = []\n         for i in range(256):\n             colortable.append(rgb(i, i, i))\n     elif im.mode == \"P\":\n-        format = QImage.Format_Indexed8\n+        format = qt_format.Format_Indexed8\n         colortable = []\n         palette = im.getpalette()\n         for i in range(0, len(palette), 3):\n             colortable.append(rgb(*palette[i : i + 3]))\n     elif im.mode == \"RGB\":\n         data = im.tobytes(\"raw\", \"BGRX\")\n-        format = QImage.Format_RGB32\n+        format = qt_format.Format_RGB32\n     elif im.mode == \"RGBA\":\n         data = im.tobytes(\"raw\", \"BGRA\")\n-        format = QImage.Format_ARGB32\n+        format = qt_format.Format_ARGB32\n     else:\n         raise ValueError(f\"unsupported image mode {repr(im.mode)}\")\n", "issue": "PyQt6 Support\nHi everyone!. I'm updating my app to PyQt6 and found a problem.\r\n\r\nImageQt.ImageQt class raises an error when try to use with QPainter:\r\n\r\n```pycon\r\n>>> page_image = ImageQt.ImageQt(page)\r\n>>> painter = QtGui.QPainter()\r\n>>> painter.begin(page_image)\r\nTypeError: begin(self, QPaintDevice): argument 1 has unexpected type 'ImageQt'\r\n```\r\n\r\nRegards\r\n\r\nPython 3.8.6\r\nUbuntu 20.04\r\nPyQt6 6.0.1\r\nPillow 8.1.0\n", "before_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# a simple Qt image interface.\n#\n# history:\n# 2006-06-03 fl: created\n# 2006-06-04 fl: inherit from QImage instead of wrapping it\n# 2006-06-05 fl: removed toimage helper; move string support to ImageQt\n# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com)\n#\n# Copyright (c) 2006 by Secret Labs AB\n# Copyright (c) 2006 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport sys\nfrom io import BytesIO\n\nfrom . import Image\nfrom ._util import isPath\n\nqt_versions = [\n    [\"side6\", \"PySide6\"],\n    [\"5\", \"PyQt5\"],\n    [\"side2\", \"PySide2\"],\n]\n\n# If a version has already been imported, attempt it first\nqt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)\nfor qt_version, qt_module in qt_versions:\n    try:\n        if qt_module == \"PySide6\":\n            from PySide6.QtCore import QBuffer, QIODevice\n            from PySide6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PyQt5\":\n            from PyQt5.QtCore import QBuffer, QIODevice\n            from PyQt5.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide2\":\n            from PySide2.QtCore import QBuffer, QIODevice\n            from PySide2.QtGui import QImage, QPixmap, qRgba\n    except (ImportError, RuntimeError):\n        continue\n    qt_is_installed = True\n    break\nelse:\n    qt_is_installed = False\n    qt_version = None\n\n\ndef rgb(r, g, b, a=255):\n    \"\"\"(Internal) Turns an RGB color into a Qt compatible color integer.\"\"\"\n    # use qRgb to pack the colors, and then turn the resulting long\n    # into a negative integer with the same bitpattern.\n    return qRgba(r, g, b, a) & 0xFFFFFFFF\n\n\ndef fromqimage(im):\n    \"\"\"\n    :param im: A PIL Image object, or a file name\n    (given either as Python string or a PyQt string object)\n    \"\"\"\n    buffer = QBuffer()\n    buffer.open(QIODevice.ReadWrite)\n    # preserve alpha channel with png\n    # otherwise ppm is more friendly with Image.open\n    if im.hasAlphaChannel():\n        im.save(buffer, \"png\")\n    else:\n        im.save(buffer, \"ppm\")\n\n    b = BytesIO()\n    b.write(buffer.data())\n    buffer.close()\n    b.seek(0)\n\n    return Image.open(b)\n\n\ndef fromqpixmap(im):\n    return fromqimage(im)\n    # buffer = QBuffer()\n    # buffer.open(QIODevice.ReadWrite)\n    # # im.save(buffer)\n    # # What if png doesn't support some image features like animation?\n    # im.save(buffer, 'ppm')\n    # bytes_io = BytesIO()\n    # bytes_io.write(buffer.data())\n    # buffer.close()\n    # bytes_io.seek(0)\n    # return Image.open(bytes_io)\n\n\ndef align8to32(bytes, width, mode):\n    \"\"\"\n    converts each scanline of data from 8 bit to 32 bit aligned\n    \"\"\"\n\n    bits_per_pixel = {\"1\": 1, \"L\": 8, \"P\": 8}[mode]\n\n    # calculate bytes per line and the extra padding if needed\n    bits_per_line = bits_per_pixel * width\n    full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)\n    bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)\n\n    extra_padding = -bytes_per_line % 4\n\n    # already 32 bit aligned by luck\n    if not extra_padding:\n        return bytes\n\n    new_data = []\n    for i in range(len(bytes) // bytes_per_line):\n        new_data.append(\n            bytes[i * bytes_per_line : (i + 1) * bytes_per_line]\n            + b\"\\x00\" * extra_padding\n        )\n\n    return b\"\".join(new_data)\n\n\ndef _toqclass_helper(im):\n    data = None\n    colortable = None\n\n    # handle filename, if given instead of image name\n    if hasattr(im, \"toUtf8\"):\n        # FIXME - is this really the best way to do this?\n        im = str(im.toUtf8(), \"utf-8\")\n    if isPath(im):\n        im = Image.open(im)\n\n    if im.mode == \"1\":\n        format = QImage.Format_Mono\n    elif im.mode == \"L\":\n        format = QImage.Format_Indexed8\n        colortable = []\n        for i in range(256):\n            colortable.append(rgb(i, i, i))\n    elif im.mode == \"P\":\n        format = QImage.Format_Indexed8\n        colortable = []\n        palette = im.getpalette()\n        for i in range(0, len(palette), 3):\n            colortable.append(rgb(*palette[i : i + 3]))\n    elif im.mode == \"RGB\":\n        data = im.tobytes(\"raw\", \"BGRX\")\n        format = QImage.Format_RGB32\n    elif im.mode == \"RGBA\":\n        data = im.tobytes(\"raw\", \"BGRA\")\n        format = QImage.Format_ARGB32\n    else:\n        raise ValueError(f\"unsupported image mode {repr(im.mode)}\")\n\n    __data = data or align8to32(im.tobytes(), im.size[0], im.mode)\n    return {\"data\": __data, \"im\": im, \"format\": format, \"colortable\": colortable}\n\n\nif qt_is_installed:\n\n    class ImageQt(QImage):\n        def __init__(self, im):\n            \"\"\"\n            An PIL image wrapper for Qt.  This is a subclass of PyQt's QImage\n            class.\n\n            :param im: A PIL Image object, or a file name (given either as\n                Python string or a PyQt string object).\n            \"\"\"\n            im_data = _toqclass_helper(im)\n            # must keep a reference, or Qt will crash!\n            # All QImage constructors that take data operate on an existing\n            # buffer, so this buffer has to hang on for the life of the image.\n            # Fixes https://github.com/python-pillow/Pillow/issues/1370\n            self.__data = im_data[\"data\"]\n            super().__init__(\n                self.__data,\n                im_data[\"im\"].size[0],\n                im_data[\"im\"].size[1],\n                im_data[\"format\"],\n            )\n            if im_data[\"colortable\"]:\n                self.setColorTable(im_data[\"colortable\"])\n\n\ndef toqimage(im):\n    return ImageQt(im)\n\n\ndef toqpixmap(im):\n    # # This doesn't work. For now using a dumb approach.\n    # im_data = _toqclass_helper(im)\n    # result = QPixmap(im_data['im'].size[0], im_data['im'].size[1])\n    # result.loadFromData(im_data['data'])\n    # Fix some strange bug that causes\n    if im.mode == \"RGB\":\n        im = im.convert(\"RGBA\")\n\n    qimage = toqimage(im)\n    return QPixmap.fromImage(qimage)\n", "path": "src/PIL/ImageQt.py"}], "after_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# a simple Qt image interface.\n#\n# history:\n# 2006-06-03 fl: created\n# 2006-06-04 fl: inherit from QImage instead of wrapping it\n# 2006-06-05 fl: removed toimage helper; move string support to ImageQt\n# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com)\n#\n# Copyright (c) 2006 by Secret Labs AB\n# Copyright (c) 2006 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport sys\nfrom io import BytesIO\n\nfrom . import Image\nfrom ._util import isPath\n\nqt_versions = [\n    [\"6\", \"PyQt6\"],\n    [\"side6\", \"PySide6\"],\n    [\"5\", \"PyQt5\"],\n    [\"side2\", \"PySide2\"],\n]\n\n# If a version has already been imported, attempt it first\nqt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)\nfor qt_version, qt_module in qt_versions:\n    try:\n        if qt_module == \"PyQt6\":\n            from PyQt6.QtCore import QBuffer, QIODevice\n            from PyQt6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide6\":\n            from PySide6.QtCore import QBuffer, QIODevice\n            from PySide6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PyQt5\":\n            from PyQt5.QtCore import QBuffer, QIODevice\n            from PyQt5.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide2\":\n            from PySide2.QtCore import QBuffer, QIODevice\n            from PySide2.QtGui import QImage, QPixmap, qRgba\n    except (ImportError, RuntimeError):\n        continue\n    qt_is_installed = True\n    break\nelse:\n    qt_is_installed = False\n    qt_version = None\n\n\ndef rgb(r, g, b, a=255):\n    \"\"\"(Internal) Turns an RGB color into a Qt compatible color integer.\"\"\"\n    # use qRgb to pack the colors, and then turn the resulting long\n    # into a negative integer with the same bitpattern.\n    return qRgba(r, g, b, a) & 0xFFFFFFFF\n\n\ndef fromqimage(im):\n    \"\"\"\n    :param im: A PIL Image object, or a file name\n    (given either as Python string or a PyQt string object)\n    \"\"\"\n    buffer = QBuffer()\n    qt_openmode = QIODevice.OpenMode if qt_version == \"6\" else QIODevice\n    buffer.open(qt_openmode.ReadWrite)\n    # preserve alpha channel with png\n    # otherwise ppm is more friendly with Image.open\n    if im.hasAlphaChannel():\n        im.save(buffer, \"png\")\n    else:\n        im.save(buffer, \"ppm\")\n\n    b = BytesIO()\n    b.write(buffer.data())\n    buffer.close()\n    b.seek(0)\n\n    return Image.open(b)\n\n\ndef fromqpixmap(im):\n    return fromqimage(im)\n    # buffer = QBuffer()\n    # buffer.open(QIODevice.ReadWrite)\n    # # im.save(buffer)\n    # # What if png doesn't support some image features like animation?\n    # im.save(buffer, 'ppm')\n    # bytes_io = BytesIO()\n    # bytes_io.write(buffer.data())\n    # buffer.close()\n    # bytes_io.seek(0)\n    # return Image.open(bytes_io)\n\n\ndef align8to32(bytes, width, mode):\n    \"\"\"\n    converts each scanline of data from 8 bit to 32 bit aligned\n    \"\"\"\n\n    bits_per_pixel = {\"1\": 1, \"L\": 8, \"P\": 8}[mode]\n\n    # calculate bytes per line and the extra padding if needed\n    bits_per_line = bits_per_pixel * width\n    full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)\n    bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)\n\n    extra_padding = -bytes_per_line % 4\n\n    # already 32 bit aligned by luck\n    if not extra_padding:\n        return bytes\n\n    new_data = []\n    for i in range(len(bytes) // bytes_per_line):\n        new_data.append(\n            bytes[i * bytes_per_line : (i + 1) * bytes_per_line]\n            + b\"\\x00\" * extra_padding\n        )\n\n    return b\"\".join(new_data)\n\n\ndef _toqclass_helper(im):\n    data = None\n    colortable = None\n\n    # handle filename, if given instead of image name\n    if hasattr(im, \"toUtf8\"):\n        # FIXME - is this really the best way to do this?\n        im = str(im.toUtf8(), \"utf-8\")\n    if isPath(im):\n        im = Image.open(im)\n\n    qt_format = QImage.Format if qt_version == \"6\" else QImage\n    if im.mode == \"1\":\n        format = qt_format.Format_Mono\n    elif im.mode == \"L\":\n        format = qt_format.Format_Indexed8\n        colortable = []\n        for i in range(256):\n            colortable.append(rgb(i, i, i))\n    elif im.mode == \"P\":\n        format = qt_format.Format_Indexed8\n        colortable = []\n        palette = im.getpalette()\n        for i in range(0, len(palette), 3):\n            colortable.append(rgb(*palette[i : i + 3]))\n    elif im.mode == \"RGB\":\n        data = im.tobytes(\"raw\", \"BGRX\")\n        format = qt_format.Format_RGB32\n    elif im.mode == \"RGBA\":\n        data = im.tobytes(\"raw\", \"BGRA\")\n        format = qt_format.Format_ARGB32\n    else:\n        raise ValueError(f\"unsupported image mode {repr(im.mode)}\")\n\n    __data = data or align8to32(im.tobytes(), im.size[0], im.mode)\n    return {\"data\": __data, \"im\": im, \"format\": format, \"colortable\": colortable}\n\n\nif qt_is_installed:\n\n    class ImageQt(QImage):\n        def __init__(self, im):\n            \"\"\"\n            An PIL image wrapper for Qt.  This is a subclass of PyQt's QImage\n            class.\n\n            :param im: A PIL Image object, or a file name (given either as\n                Python string or a PyQt string object).\n            \"\"\"\n            im_data = _toqclass_helper(im)\n            # must keep a reference, or Qt will crash!\n            # All QImage constructors that take data operate on an existing\n            # buffer, so this buffer has to hang on for the life of the image.\n            # Fixes https://github.com/python-pillow/Pillow/issues/1370\n            self.__data = im_data[\"data\"]\n            super().__init__(\n                self.__data,\n                im_data[\"im\"].size[0],\n                im_data[\"im\"].size[1],\n                im_data[\"format\"],\n            )\n            if im_data[\"colortable\"]:\n                self.setColorTable(im_data[\"colortable\"])\n\n\ndef toqimage(im):\n    return ImageQt(im)\n\n\ndef toqpixmap(im):\n    # # This doesn't work. For now using a dumb approach.\n    # im_data = _toqclass_helper(im)\n    # result = QPixmap(im_data['im'].size[0], im_data['im'].size[1])\n    # result.loadFromData(im_data['data'])\n    # Fix some strange bug that causes\n    if im.mode == \"RGB\":\n        im = im.convert(\"RGBA\")\n\n    qimage = toqimage(im)\n    return QPixmap.fromImage(qimage)\n", "path": "src/PIL/ImageQt.py"}]}