We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
PSD Plugin does not register a MIME type
The [`PSDImagePlugin`](https://github.com/python-pillow/Pillow/blob/master/src/PIL/PsdImagePlugin.py) does not register a MIME type as I'd expect it to. The correct MIME for PSD images, according to IANA, is ["image/vnd.adobe.photoshop"](https://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop).

Is there a reason this isn't registered?
PSD Plugin does not register a MIME type
The [`PSDImagePlugin`](https://github.com/python-pillow/Pillow/blob/master/src/PIL/PsdImagePlugin.py) does not register a MIME type as I'd expect it to. The correct MIME for PSD images, according to IANA, is ["image/vnd.adobe.photoshop"](https://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop).

Is there a reason this isn't registered?

--- 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/PsdImagePlugin.py`
Content:
```
1 #
2 # The Python Imaging Library
3 # $Id$
4 #
5 # Adobe PSD 2.5/3.0 file handling
6 #
7 # History:
8 # 1995-09-01 fl   Created
9 # 1997-01-03 fl   Read most PSD images
10 # 1997-01-18 fl   Fixed P and CMYK support
11 # 2001-10-21 fl   Added seek/tell support (for layers)
12 #
13 # Copyright (c) 1997-2001 by Secret Labs AB.
14 # Copyright (c) 1995-2001 by Fredrik Lundh
15 #
16 # See the README file for information on usage and redistribution.
17 #
18 
19 import io
20 
21 from . import Image, ImageFile, ImagePalette
22 from ._binary import i8, i16be as i16, i32be as i32
23 
24 MODES = {
25     # (photoshop mode, bits) -> (pil mode, required channels)
26     (0, 1): ("1", 1),
27     (0, 8): ("L", 1),
28     (1, 8): ("L", 1),
29     (2, 8): ("P", 1),
30     (3, 8): ("RGB", 3),
31     (4, 8): ("CMYK", 4),
32     (7, 8): ("L", 1),  # FIXME: multilayer
33     (8, 8): ("L", 1),  # duotone
34     (9, 8): ("LAB", 3),
35 }
36 
37 
38 # --------------------------------------------------------------------.
39 # read PSD images
40 
41 
42 def _accept(prefix):
43     return prefix[:4] == b"8BPS"
44 
45 
46 ##
47 # Image plugin for Photoshop images.
48 
49 
50 class PsdImageFile(ImageFile.ImageFile):
51 
52     format = "PSD"
53     format_description = "Adobe Photoshop"
54     _close_exclusive_fp_after_loading = False
55 
56     def _open(self):
57 
58         read = self.fp.read
59 
60         #
61         # header
62 
63         s = read(26)
64         if not _accept(s) or i16(s[4:]) != 1:
65             raise SyntaxError("not a PSD file")
66 
67         psd_bits = i16(s[22:])
68         psd_channels = i16(s[12:])
69         psd_mode = i16(s[24:])
70 
71         mode, channels = MODES[(psd_mode, psd_bits)]
72 
73         if channels > psd_channels:
74             raise OSError("not enough channels")
75 
76         self.mode = mode
77         self._size = i32(s[18:]), i32(s[14:])
78 
79         #
80         # color mode data
81 
82         size = i32(read(4))
83         if size:
84             data = read(size)
85             if mode == "P" and size == 768:
86                 self.palette = ImagePalette.raw("RGB;L", data)
87 
88         #
89         # image resources
90 
91         self.resources = []
92 
93         size = i32(read(4))
94         if size:
95             # load resources
96             end = self.fp.tell() + size
97             while self.fp.tell() < end:
98                 read(4)  # signature
99                 id = i16(read(2))
100                 name = read(i8(read(1)))
101                 if not (len(name) & 1):
102                     read(1)  # padding
103                 data = read(i32(read(4)))
104                 if len(data) & 1:
105                     read(1)  # padding
106                 self.resources.append((id, name, data))
107                 if id == 1039:  # ICC profile
108                     self.info["icc_profile"] = data
109 
110         #
111         # layer and mask information
112 
113         self.layers = []
114 
115         size = i32(read(4))
116         if size:
117             end = self.fp.tell() + size
118             size = i32(read(4))
119             if size:
120                 self.layers = _layerinfo(self.fp)
121             self.fp.seek(end)
122         self.n_frames = len(self.layers)
123         self.is_animated = self.n_frames > 1
124 
125         #
126         # image descriptor
127 
128         self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels)
129 
130         # keep the file open
131         self.__fp = self.fp
132         self.frame = 1
133         self._min_frame = 1
134 
135     def seek(self, layer):
136         if not self._seek_check(layer):
137             return
138 
139         # seek to given layer (1..max)
140         try:
141             name, mode, bbox, tile = self.layers[layer - 1]
142             self.mode = mode
143             self.tile = tile
144             self.frame = layer
145             self.fp = self.__fp
146             return name, bbox
147         except IndexError as e:
148             raise EOFError("no such layer") from e
149 
150     def tell(self):
151         # return layer number (0=image, 1..max=layers)
152         return self.frame
153 
154     def load_prepare(self):
155         # create image memory if necessary
156         if not self.im or self.im.mode != self.mode or self.im.size != self.size:
157             self.im = Image.core.fill(self.mode, self.size, 0)
158         # create palette (optional)
159         if self.mode == "P":
160             Image.Image.load(self)
161 
162     def _close__fp(self):
163         try:
164             if self.__fp != self.fp:
165                 self.__fp.close()
166         except AttributeError:
167             pass
168         finally:
169             self.__fp = None
170 
171 
172 def _layerinfo(file):
173     # read layerinfo block
174     layers = []
175     read = file.read
176     for i in range(abs(i16(read(2)))):
177 
178         # bounding box
179         y0 = i32(read(4))
180         x0 = i32(read(4))
181         y1 = i32(read(4))
182         x1 = i32(read(4))
183 
184         # image info
185         info = []
186         mode = []
187         types = list(range(i16(read(2))))
188         if len(types) > 4:
189             continue
190 
191         for i in types:
192             type = i16(read(2))
193 
194             if type == 65535:
195                 m = "A"
196             else:
197                 m = "RGBA"[type]
198 
199             mode.append(m)
200             size = i32(read(4))
201             info.append((m, size))
202 
203         # figure out the image mode
204         mode.sort()
205         if mode == ["R"]:
206             mode = "L"
207         elif mode == ["B", "G", "R"]:
208             mode = "RGB"
209         elif mode == ["A", "B", "G", "R"]:
210             mode = "RGBA"
211         else:
212             mode = None  # unknown
213 
214         # skip over blend flags and extra information
215         read(12)  # filler
216         name = ""
217         size = i32(read(4))  # length of the extra data field
218         combined = 0
219         if size:
220             data_end = file.tell() + size
221 
222             length = i32(read(4))
223             if length:
224                 file.seek(length - 16, io.SEEK_CUR)
225             combined += length + 4
226 
227             length = i32(read(4))
228             if length:
229                 file.seek(length, io.SEEK_CUR)
230             combined += length + 4
231 
232             length = i8(read(1))
233             if length:
234                 # Don't know the proper encoding,
235                 # Latin-1 should be a good guess
236                 name = read(length).decode("latin-1", "replace")
237             combined += length + 1
238 
239             file.seek(data_end)
240         layers.append((name, mode, (x0, y0, x1, y1)))
241 
242     # get tiles
243     i = 0
244     for name, mode, bbox in layers:
245         tile = []
246         for m in mode:
247             t = _maketile(file, m, bbox, 1)
248             if t:
249                 tile.extend(t)
250         layers[i] = name, mode, bbox, tile
251         i += 1
252 
253     return layers
254 
255 
256 def _maketile(file, mode, bbox, channels):
257 
258     tile = None
259     read = file.read
260 
261     compression = i16(read(2))
262 
263     xsize = bbox[2] - bbox[0]
264     ysize = bbox[3] - bbox[1]
265 
266     offset = file.tell()
267 
268     if compression == 0:
269         #
270         # raw compression
271         tile = []
272         for channel in range(channels):
273             layer = mode[channel]
274             if mode == "CMYK":
275                 layer += ";I"
276             tile.append(("raw", bbox, offset, layer))
277             offset = offset + xsize * ysize
278 
279     elif compression == 1:
280         #
281         # packbits compression
282         i = 0
283         tile = []
284         bytecount = read(channels * ysize * 2)
285         offset = file.tell()
286         for channel in range(channels):
287             layer = mode[channel]
288             if mode == "CMYK":
289                 layer += ";I"
290             tile.append(("packbits", bbox, offset, layer))
291             for y in range(ysize):
292                 offset = offset + i16(bytecount[i : i + 2])
293                 i += 2
294 
295     file.seek(offset)
296 
297     if offset & 1:
298         read(1)  # padding
299 
300     return tile
301 
302 
303 # --------------------------------------------------------------------
304 # registry
305 
306 
307 Image.register_open(PsdImageFile.format, PsdImageFile, _accept)
308 
309 Image.register_extension(PsdImageFile.format, ".psd")
310
```
--- 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/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py
--- a/src/PIL/PsdImagePlugin.py
+++ b/src/PIL/PsdImagePlugin.py
@@ -307,3 +307,5 @@
 Image.register_open(PsdImageFile.format, PsdImageFile, _accept)
 
 Image.register_extension(PsdImageFile.format, ".psd")
+
+Image.register_mime(PsdImageFile.format, "image/vnd.adobe.photoshop")

{"golden_diff": "diff --git a/src/PIL/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py\n--- a/src/PIL/PsdImagePlugin.py\n+++ b/src/PIL/PsdImagePlugin.py\n@@ -307,3 +307,5 @@\n Image.register_open(PsdImageFile.format, PsdImageFile, _accept)\n \n Image.register_extension(PsdImageFile.format, \".psd\")\n+\n+Image.register_mime(PsdImageFile.format, \"image/vnd.adobe.photoshop\")\n", "issue": "PSD Plugin does not register a MIME type\nThe [`PSDImagePlugin`](https://github.com/python-pillow/Pillow/blob/master/src/PIL/PsdImagePlugin.py) does not register a MIME type as I'd expect it to. The correct MIME for PSD images, according to IANA, is [\"image/vnd.adobe.photoshop\"](https://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop).\r\n\r\nIs there a reason this isn't registered?\nPSD Plugin does not register a MIME type\nThe [`PSDImagePlugin`](https://github.com/python-pillow/Pillow/blob/master/src/PIL/PsdImagePlugin.py) does not register a MIME type as I'd expect it to. The correct MIME for PSD images, according to IANA, is [\"image/vnd.adobe.photoshop\"](https://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop).\r\n\r\nIs there a reason this isn't registered?\n", "before_files": [{"content": "#\n# The Python Imaging Library\n# $Id$\n#\n# Adobe PSD 2.5/3.0 file handling\n#\n# History:\n# 1995-09-01 fl   Created\n# 1997-01-03 fl   Read most PSD images\n# 1997-01-18 fl   Fixed P and CMYK support\n# 2001-10-21 fl   Added seek/tell support (for layers)\n#\n# Copyright (c) 1997-2001 by Secret Labs AB.\n# Copyright (c) 1995-2001 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport io\n\nfrom . import Image, ImageFile, ImagePalette\nfrom ._binary import i8, i16be as i16, i32be as i32\n\nMODES = {\n    # (photoshop mode, bits) -> (pil mode, required channels)\n    (0, 1): (\"1\", 1),\n    (0, 8): (\"L\", 1),\n    (1, 8): (\"L\", 1),\n    (2, 8): (\"P\", 1),\n    (3, 8): (\"RGB\", 3),\n    (4, 8): (\"CMYK\", 4),\n    (7, 8): (\"L\", 1),  # FIXME: multilayer\n    (8, 8): (\"L\", 1),  # duotone\n    (9, 8): (\"LAB\", 3),\n}\n\n\n# --------------------------------------------------------------------.\n# read PSD images\n\n\ndef _accept(prefix):\n    return prefix[:4] == b\"8BPS\"\n\n\n##\n# Image plugin for Photoshop images.\n\n\nclass PsdImageFile(ImageFile.ImageFile):\n\n    format = \"PSD\"\n    format_description = \"Adobe Photoshop\"\n    _close_exclusive_fp_after_loading = False\n\n    def _open(self):\n\n        read = self.fp.read\n\n        #\n        # header\n\n        s = read(26)\n        if not _accept(s) or i16(s[4:]) != 1:\n            raise SyntaxError(\"not a PSD file\")\n\n        psd_bits = i16(s[22:])\n        psd_channels = i16(s[12:])\n        psd_mode = i16(s[24:])\n\n        mode, channels = MODES[(psd_mode, psd_bits)]\n\n        if channels > psd_channels:\n            raise OSError(\"not enough channels\")\n\n        self.mode = mode\n        self._size = i32(s[18:]), i32(s[14:])\n\n        #\n        # color mode data\n\n        size = i32(read(4))\n        if size:\n            data = read(size)\n            if mode == \"P\" and size == 768:\n                self.palette = ImagePalette.raw(\"RGB;L\", data)\n\n        #\n        # image resources\n\n        self.resources = []\n\n        size = i32(read(4))\n        if size:\n            # load resources\n            end = self.fp.tell() + size\n            while self.fp.tell() < end:\n                read(4)  # signature\n                id = i16(read(2))\n                name = read(i8(read(1)))\n                if not (len(name) & 1):\n                    read(1)  # padding\n                data = read(i32(read(4)))\n                if len(data) & 1:\n                    read(1)  # padding\n                self.resources.append((id, name, data))\n                if id == 1039:  # ICC profile\n                    self.info[\"icc_profile\"] = data\n\n        #\n        # layer and mask information\n\n        self.layers = []\n\n        size = i32(read(4))\n        if size:\n            end = self.fp.tell() + size\n            size = i32(read(4))\n            if size:\n                self.layers = _layerinfo(self.fp)\n            self.fp.seek(end)\n        self.n_frames = len(self.layers)\n        self.is_animated = self.n_frames > 1\n\n        #\n        # image descriptor\n\n        self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels)\n\n        # keep the file open\n        self.__fp = self.fp\n        self.frame = 1\n        self._min_frame = 1\n\n    def seek(self, layer):\n        if not self._seek_check(layer):\n            return\n\n        # seek to given layer (1..max)\n        try:\n            name, mode, bbox, tile = self.layers[layer - 1]\n            self.mode = mode\n            self.tile = tile\n            self.frame = layer\n            self.fp = self.__fp\n            return name, bbox\n        except IndexError as e:\n            raise EOFError(\"no such layer\") from e\n\n    def tell(self):\n        # return layer number (0=image, 1..max=layers)\n        return self.frame\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.fill(self.mode, self.size, 0)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def _close__fp(self):\n        try:\n            if self.__fp != self.fp:\n                self.__fp.close()\n        except AttributeError:\n            pass\n        finally:\n            self.__fp = None\n\n\ndef _layerinfo(file):\n    # read layerinfo block\n    layers = []\n    read = file.read\n    for i in range(abs(i16(read(2)))):\n\n        # bounding box\n        y0 = i32(read(4))\n        x0 = i32(read(4))\n        y1 = i32(read(4))\n        x1 = i32(read(4))\n\n        # image info\n        info = []\n        mode = []\n        types = list(range(i16(read(2))))\n        if len(types) > 4:\n            continue\n\n        for i in types:\n            type = i16(read(2))\n\n            if type == 65535:\n                m = \"A\"\n            else:\n                m = \"RGBA\"[type]\n\n            mode.append(m)\n            size = i32(read(4))\n            info.append((m, size))\n\n        # figure out the image mode\n        mode.sort()\n        if mode == [\"R\"]:\n            mode = \"L\"\n        elif mode == [\"B\", \"G\", \"R\"]:\n            mode = \"RGB\"\n        elif mode == [\"A\", \"B\", \"G\", \"R\"]:\n            mode = \"RGBA\"\n        else:\n            mode = None  # unknown\n\n        # skip over blend flags and extra information\n        read(12)  # filler\n        name = \"\"\n        size = i32(read(4))  # length of the extra data field\n        combined = 0\n        if size:\n            data_end = file.tell() + size\n\n            length = i32(read(4))\n            if length:\n                file.seek(length - 16, io.SEEK_CUR)\n            combined += length + 4\n\n            length = i32(read(4))\n            if length:\n                file.seek(length, io.SEEK_CUR)\n            combined += length + 4\n\n            length = i8(read(1))\n            if length:\n                # Don't know the proper encoding,\n                # Latin-1 should be a good guess\n                name = read(length).decode(\"latin-1\", \"replace\")\n            combined += length + 1\n\n            file.seek(data_end)\n        layers.append((name, mode, (x0, y0, x1, y1)))\n\n    # get tiles\n    i = 0\n    for name, mode, bbox in layers:\n        tile = []\n        for m in mode:\n            t = _maketile(file, m, bbox, 1)\n            if t:\n                tile.extend(t)\n        layers[i] = name, mode, bbox, tile\n        i += 1\n\n    return layers\n\n\ndef _maketile(file, mode, bbox, channels):\n\n    tile = None\n    read = file.read\n\n    compression = i16(read(2))\n\n    xsize = bbox[2] - bbox[0]\n    ysize = bbox[3] - bbox[1]\n\n    offset = file.tell()\n\n    if compression == 0:\n        #\n        # raw compression\n        tile = []\n        for channel in range(channels):\n            layer = mode[channel]\n            if mode == \"CMYK\":\n                layer += \";I\"\n            tile.append((\"raw\", bbox, offset, layer))\n            offset = offset + xsize * ysize\n\n    elif compression == 1:\n        #\n        # packbits compression\n        i = 0\n        tile = []\n        bytecount = read(channels * ysize * 2)\n        offset = file.tell()\n        for channel in range(channels):\n            layer = mode[channel]\n            if mode == \"CMYK\":\n                layer += \";I\"\n            tile.append((\"packbits\", bbox, offset, layer))\n            for y in range(ysize):\n                offset = offset + i16(bytecount[i : i + 2])\n                i += 2\n\n    file.seek(offset)\n\n    if offset & 1:\n        read(1)  # padding\n\n    return tile\n\n\n# --------------------------------------------------------------------\n# registry\n\n\nImage.register_open(PsdImageFile.format, PsdImageFile, _accept)\n\nImage.register_extension(PsdImageFile.format, \".psd\")\n", "path": "src/PIL/PsdImagePlugin.py"}], "after_files": [{"content": "#\n# The Python Imaging Library\n# $Id$\n#\n# Adobe PSD 2.5/3.0 file handling\n#\n# History:\n# 1995-09-01 fl   Created\n# 1997-01-03 fl   Read most PSD images\n# 1997-01-18 fl   Fixed P and CMYK support\n# 2001-10-21 fl   Added seek/tell support (for layers)\n#\n# Copyright (c) 1997-2001 by Secret Labs AB.\n# Copyright (c) 1995-2001 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport io\n\nfrom . import Image, ImageFile, ImagePalette\nfrom ._binary import i8, i16be as i16, i32be as i32\n\nMODES = {\n    # (photoshop mode, bits) -> (pil mode, required channels)\n    (0, 1): (\"1\", 1),\n    (0, 8): (\"L\", 1),\n    (1, 8): (\"L\", 1),\n    (2, 8): (\"P\", 1),\n    (3, 8): (\"RGB\", 3),\n    (4, 8): (\"CMYK\", 4),\n    (7, 8): (\"L\", 1),  # FIXME: multilayer\n    (8, 8): (\"L\", 1),  # duotone\n    (9, 8): (\"LAB\", 3),\n}\n\n\n# --------------------------------------------------------------------.\n# read PSD images\n\n\ndef _accept(prefix):\n    return prefix[:4] == b\"8BPS\"\n\n\n##\n# Image plugin for Photoshop images.\n\n\nclass PsdImageFile(ImageFile.ImageFile):\n\n    format = \"PSD\"\n    format_description = \"Adobe Photoshop\"\n    _close_exclusive_fp_after_loading = False\n\n    def _open(self):\n\n        read = self.fp.read\n\n        #\n        # header\n\n        s = read(26)\n        if not _accept(s) or i16(s[4:]) != 1:\n            raise SyntaxError(\"not a PSD file\")\n\n        psd_bits = i16(s[22:])\n        psd_channels = i16(s[12:])\n        psd_mode = i16(s[24:])\n\n        mode, channels = MODES[(psd_mode, psd_bits)]\n\n        if channels > psd_channels:\n            raise OSError(\"not enough channels\")\n\n        self.mode = mode\n        self._size = i32(s[18:]), i32(s[14:])\n\n        #\n        # color mode data\n\n        size = i32(read(4))\n        if size:\n            data = read(size)\n            if mode == \"P\" and size == 768:\n                self.palette = ImagePalette.raw(\"RGB;L\", data)\n\n        #\n        # image resources\n\n        self.resources = []\n\n        size = i32(read(4))\n        if size:\n            # load resources\n            end = self.fp.tell() + size\n            while self.fp.tell() < end:\n                read(4)  # signature\n                id = i16(read(2))\n                name = read(i8(read(1)))\n                if not (len(name) & 1):\n                    read(1)  # padding\n                data = read(i32(read(4)))\n                if len(data) & 1:\n                    read(1)  # padding\n                self.resources.append((id, name, data))\n                if id == 1039:  # ICC profile\n                    self.info[\"icc_profile\"] = data\n\n        #\n        # layer and mask information\n\n        self.layers = []\n\n        size = i32(read(4))\n        if size:\n            end = self.fp.tell() + size\n            size = i32(read(4))\n            if size:\n                self.layers = _layerinfo(self.fp)\n            self.fp.seek(end)\n        self.n_frames = len(self.layers)\n        self.is_animated = self.n_frames > 1\n\n        #\n        # image descriptor\n\n        self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels)\n\n        # keep the file open\n        self.__fp = self.fp\n        self.frame = 1\n        self._min_frame = 1\n\n    def seek(self, layer):\n        if not self._seek_check(layer):\n            return\n\n        # seek to given layer (1..max)\n        try:\n            name, mode, bbox, tile = self.layers[layer - 1]\n            self.mode = mode\n            self.tile = tile\n            self.frame = layer\n            self.fp = self.__fp\n            return name, bbox\n        except IndexError as e:\n            raise EOFError(\"no such layer\") from e\n\n    def tell(self):\n        # return layer number (0=image, 1..max=layers)\n        return self.frame\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.fill(self.mode, self.size, 0)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def _close__fp(self):\n        try:\n            if self.__fp != self.fp:\n                self.__fp.close()\n        except AttributeError:\n            pass\n        finally:\n            self.__fp = None\n\n\ndef _layerinfo(file):\n    # read layerinfo block\n    layers = []\n    read = file.read\n    for i in range(abs(i16(read(2)))):\n\n        # bounding box\n        y0 = i32(read(4))\n        x0 = i32(read(4))\n        y1 = i32(read(4))\n        x1 = i32(read(4))\n\n        # image info\n        info = []\n        mode = []\n        types = list(range(i16(read(2))))\n        if len(types) > 4:\n            continue\n\n        for i in types:\n            type = i16(read(2))\n\n            if type == 65535:\n                m = \"A\"\n            else:\n                m = \"RGBA\"[type]\n\n            mode.append(m)\n            size = i32(read(4))\n            info.append((m, size))\n\n        # figure out the image mode\n        mode.sort()\n        if mode == [\"R\"]:\n            mode = \"L\"\n        elif mode == [\"B\", \"G\", \"R\"]:\n            mode = \"RGB\"\n        elif mode == [\"A\", \"B\", \"G\", \"R\"]:\n            mode = \"RGBA\"\n        else:\n            mode = None  # unknown\n\n        # skip over blend flags and extra information\n        read(12)  # filler\n        name = \"\"\n        size = i32(read(4))  # length of the extra data field\n        combined = 0\n        if size:\n            data_end = file.tell() + size\n\n            length = i32(read(4))\n            if length:\n                file.seek(length - 16, io.SEEK_CUR)\n            combined += length + 4\n\n            length = i32(read(4))\n            if length:\n                file.seek(length, io.SEEK_CUR)\n            combined += length + 4\n\n            length = i8(read(1))\n            if length:\n                # Don't know the proper encoding,\n                # Latin-1 should be a good guess\n                name = read(length).decode(\"latin-1\", \"replace\")\n            combined += length + 1\n\n            file.seek(data_end)\n        layers.append((name, mode, (x0, y0, x1, y1)))\n\n    # get tiles\n    i = 0\n    for name, mode, bbox in layers:\n        tile = []\n        for m in mode:\n            t = _maketile(file, m, bbox, 1)\n            if t:\n                tile.extend(t)\n        layers[i] = name, mode, bbox, tile\n        i += 1\n\n    return layers\n\n\ndef _maketile(file, mode, bbox, channels):\n\n    tile = None\n    read = file.read\n\n    compression = i16(read(2))\n\n    xsize = bbox[2] - bbox[0]\n    ysize = bbox[3] - bbox[1]\n\n    offset = file.tell()\n\n    if compression == 0:\n        #\n        # raw compression\n        tile = []\n        for channel in range(channels):\n            layer = mode[channel]\n            if mode == \"CMYK\":\n                layer += \";I\"\n            tile.append((\"raw\", bbox, offset, layer))\n            offset = offset + xsize * ysize\n\n    elif compression == 1:\n        #\n        # packbits compression\n        i = 0\n        tile = []\n        bytecount = read(channels * ysize * 2)\n        offset = file.tell()\n        for channel in range(channels):\n            layer = mode[channel]\n            if mode == \"CMYK\":\n                layer += \";I\"\n            tile.append((\"packbits\", bbox, offset, layer))\n            for y in range(ysize):\n                offset = offset + i16(bytecount[i : i + 2])\n                i += 2\n\n    file.seek(offset)\n\n    if offset & 1:\n        read(1)  # padding\n\n    return tile\n\n\n# --------------------------------------------------------------------\n# registry\n\n\nImage.register_open(PsdImageFile.format, PsdImageFile, _accept)\n\nImage.register_extension(PsdImageFile.format, \".psd\")\n\nImage.register_mime(PsdImageFile.format, \"image/vnd.adobe.photoshop\")\n", "path": "src/PIL/PsdImagePlugin.py"}]}