We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Some pcx images are displayed incorrectly
Hi everyone!
I'm trying to use pcx images extracted from an old game (Might and Magic VI, the game has 2D UI over the 3D environment. This 2D UI is composed by various internal formats and pcx files.)

The problem is that one of these pcx is displayed incorrecly by pillow, while being displayed correctly by EyeOfGnome (gdk-pixbuf) image viewer.
Another pcx is displayed correctly by pillow!

What do I mean by incorrectly? The bad image has a kind of "red shift" of pixels colors. the left border is a bit red. It' like a "3D-ified" image, it's a bit blurry and the whole is a bit darker.

I opened the pcx files with an hex editor and the main difference I spotted in the pcx-header is that the wrong one has the "48 byte palette" field completely empty. while the other one has some data in it. But it shoudn't be a problem because other viewers display it correctly.

I simply use this code
img = Image.open(pcxfilename)
img.show()

this archive contains the pcx files https://db.tt/td291VTh

gdk-pixbuf decoding of pcx is a bit more complex than the pillow one:
gdk-pixbuf/io-pcx.c VS libImaging/PcxDecode.c

thanks for any help!

![border](https://f.cloud.github.com/assets/130094/2161053/c8ed7598-94c1-11e3-8607-1f2ad1f208c1.png)

Some pcx images are displayed incorrectly
Hi everyone!
I'm trying to use pcx images extracted from an old game (Might and Magic VI, the game has 2D UI over the 3D environment. This 2D UI is composed by various internal formats and pcx files.)

The problem is that one of these pcx is displayed incorrecly by pillow, while being displayed correctly by EyeOfGnome (gdk-pixbuf) image viewer.
Another pcx is displayed correctly by pillow!

What do I mean by incorrectly? The bad image has a kind of "red shift" of pixels colors. the left border is a bit red. It' like a "3D-ified" image, it's a bit blurry and the whole is a bit darker.

I opened the pcx files with an hex editor and the main difference I spotted in the pcx-header is that the wrong one has the "48 byte palette" field completely empty. while the other one has some data in it. But it shoudn't be a problem because other viewers display it correctly.

I simply use this code
img = Image.open(pcxfilename)
img.show()

this archive contains the pcx files https://db.tt/td291VTh

gdk-pixbuf decoding of pcx is a bit more complex than the pillow one:
gdk-pixbuf/io-pcx.c VS libImaging/PcxDecode.c

thanks for any help!

![border](https://f.cloud.github.com/assets/130094/2161053/c8ed7598-94c1-11e3-8607-1f2ad1f208c1.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `PIL/PcxImagePlugin.py`
Content:
```
1 #
2 # The Python Imaging Library.
3 # $Id$
4 #
5 # PCX file handling
6 #
7 # This format was originally used by ZSoft's popular PaintBrush
8 # program for the IBM PC.  It is also supported by many MS-DOS and
9 # Windows applications, including the Windows PaintBrush program in
10 # Windows 3.
11 #
12 # history:
13 # 1995-09-01 fl   Created
14 # 1996-05-20 fl   Fixed RGB support
15 # 1997-01-03 fl   Fixed 2-bit and 4-bit support
16 # 1999-02-03 fl   Fixed 8-bit support (broken in 1.0b1)
17 # 1999-02-07 fl   Added write support
18 # 2002-06-09 fl   Made 2-bit and 4-bit support a bit more robust
19 # 2002-07-30 fl   Seek from to current position, not beginning of file
20 # 2003-06-03 fl   Extract DPI settings (info["dpi"])
21 #
22 # Copyright (c) 1997-2003 by Secret Labs AB.
23 # Copyright (c) 1995-2003 by Fredrik Lundh.
24 #
25 # See the README file for information on usage and redistribution.
26 #
27 
28 __version__ = "0.6"
29 
30 from PIL import Image, ImageFile, ImagePalette, _binary
31 
32 i8 = _binary.i8
33 i16 = _binary.i16le
34 o8 = _binary.o8
35 
36 def _accept(prefix):
37     return i8(prefix[0]) == 10 and i8(prefix[1]) in [0, 2, 3, 5]
38 
39 ##
40 # Image plugin for Paintbrush images.
41 
42 class PcxImageFile(ImageFile.ImageFile):
43 
44     format = "PCX"
45     format_description = "Paintbrush"
46 
47     def _open(self):
48 
49         # header
50         s = self.fp.read(128)
51         if not _accept(s):
52             raise SyntaxError("not a PCX file")
53 
54         # image
55         bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1
56         if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:
57             raise SyntaxError("bad PCX image size")
58 
59         # format
60         version = i8(s[1])
61         bits = i8(s[3])
62         planes = i8(s[65])
63         stride = i16(s,66)
64 
65         self.info["dpi"] = i16(s,12), i16(s,14)
66 
67         if bits == 1 and planes == 1:
68             mode = rawmode = "1"
69 
70         elif bits == 1 and planes in (2, 4):
71             mode = "P"
72             rawmode = "P;%dL" % planes
73             self.palette = ImagePalette.raw("RGB", s[16:64])
74 
75         elif version == 5 and bits == 8 and planes == 1:
76             mode = rawmode = "L"
77             # FIXME: hey, this doesn't work with the incremental loader !!!
78             self.fp.seek(-769, 2)
79             s = self.fp.read(769)
80             if len(s) == 769 and i8(s[0]) == 12:
81                 # check if the palette is linear greyscale
82                 for i in range(256):
83                     if s[i*3+1:i*3+4] != o8(i)*3:
84                         mode = rawmode = "P"
85                         break
86                 if mode == "P":
87                     self.palette = ImagePalette.raw("RGB", s[1:])
88             self.fp.seek(128)
89 
90         elif version == 5 and bits == 8 and planes == 3:
91             mode = "RGB"
92             rawmode = "RGB;L"
93 
94         else:
95             raise IOError("unknown PCX mode")
96 
97         self.mode = mode
98         self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]
99 
100         bbox = (0, 0) + self.size
101 
102         self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))]
103 
104 # --------------------------------------------------------------------
105 # save PCX files
106 
107 SAVE = {
108     # mode: (version, bits, planes, raw mode)
109     "1": (2, 1, 1, "1"),
110     "L": (5, 8, 1, "L"),
111     "P": (5, 8, 1, "P"),
112     "RGB": (5, 8, 3, "RGB;L"),
113 }
114 
115 o16 = _binary.o16le
116 
117 def _save(im, fp, filename, check=0):
118 
119     try:
120         version, bits, planes, rawmode = SAVE[im.mode]
121     except KeyError:
122         raise ValueError("Cannot save %s images as PCX" % im.mode)
123 
124     if check:
125         return check
126 
127     # bytes per plane
128     stride = (im.size[0] * bits + 7) // 8
129 
130     # under windows, we could determine the current screen size with
131     # "Image.core.display_mode()[1]", but I think that's overkill...
132 
133     screen = im.size
134 
135     dpi = 100, 100
136 
137     # PCX header
138     fp.write(
139         o8(10) + o8(version) + o8(1) + o8(bits) + o16(0) +
140         o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +
141         o16(dpi[1]) + b"\0"*24 + b"\xFF"*24 + b"\0" + o8(planes) +
142         o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +
143         b"\0"*54
144         )
145 
146     assert fp.tell() == 128
147 
148     ImageFile._save(im, fp, [("pcx", (0,0)+im.size, 0,
149                               (rawmode, bits*planes))])
150 
151     if im.mode == "P":
152         # colour palette
153         fp.write(o8(12))
154         fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes
155     elif im.mode == "L":
156         # greyscale palette
157         fp.write(o8(12))
158         for i in range(256):
159             fp.write(o8(i)*3)
160 
161 # --------------------------------------------------------------------
162 # registry
163 
164 Image.register_open("PCX", PcxImageFile, _accept)
165 Image.register_save("PCX", _save)
166 
167 Image.register_extension("PCX", ".pcx")
168
```
--- 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/PIL/PcxImagePlugin.py b/PIL/PcxImagePlugin.py
--- a/PIL/PcxImagePlugin.py
+++ b/PIL/PcxImagePlugin.py
@@ -55,12 +55,18 @@
         bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1
         if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:
             raise SyntaxError("bad PCX image size")
+        if Image.DEBUG:
+            print ("BBox: %s %s %s %s" % bbox)
+
 
         # format
         version = i8(s[1])
         bits = i8(s[3])
         planes = i8(s[65])
         stride = i16(s,66)
+        if Image.DEBUG:
+            print ("PCX version %s, bits %s, planes %s, stride %s" %
+                   (version, bits, planes, stride))
 
         self.info["dpi"] = i16(s,12), i16(s,14)
 
@@ -98,7 +104,9 @@
         self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]
 
         bbox = (0, 0) + self.size
-
+        if Image.DEBUG:
+            print ("size: %sx%s" % self.size)
+            
         self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))]
 
 # --------------------------------------------------------------------
@@ -126,6 +134,16 @@
 
     # bytes per plane
     stride = (im.size[0] * bits + 7) // 8
+    # stride should be even
+    stride = stride + (stride % 2)
+    # Stride needs to be kept in sync with the PcxEncode.c version.
+    # Ideally it should be passed in in the state, but the bytes value
+    # gets overwritten. 
+
+
+    if Image.DEBUG:
+        print ("PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d" % (
+            im.size[0], bits, stride))
 
     # under windows, we could determine the current screen size with
     # "Image.core.display_mode()[1]", but I think that's overkill...

{"golden_diff": "diff --git a/PIL/PcxImagePlugin.py b/PIL/PcxImagePlugin.py\n--- a/PIL/PcxImagePlugin.py\n+++ b/PIL/PcxImagePlugin.py\n@@ -55,12 +55,18 @@\n         bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1\n         if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:\n             raise SyntaxError(\"bad PCX image size\")\n+        if Image.DEBUG:\n+            print (\"BBox: %s %s %s %s\" % bbox)\n+\n \n         # format\n         version = i8(s[1])\n         bits = i8(s[3])\n         planes = i8(s[65])\n         stride = i16(s,66)\n+        if Image.DEBUG:\n+            print (\"PCX version %s, bits %s, planes %s, stride %s\" %\n+                   (version, bits, planes, stride))\n \n         self.info[\"dpi\"] = i16(s,12), i16(s,14)\n \n@@ -98,7 +104,9 @@\n         self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]\n \n         bbox = (0, 0) + self.size\n-\n+        if Image.DEBUG:\n+            print (\"size: %sx%s\" % self.size)\n+            \n         self.tile = [(\"pcx\", bbox, self.fp.tell(), (rawmode, planes * stride))]\n \n # --------------------------------------------------------------------\n@@ -126,6 +134,16 @@\n \n     # bytes per plane\n     stride = (im.size[0] * bits + 7) // 8\n+    # stride should be even\n+    stride = stride + (stride % 2)\n+    # Stride needs to be kept in sync with the PcxEncode.c version.\n+    # Ideally it should be passed in in the state, but the bytes value\n+    # gets overwritten. \n+\n+\n+    if Image.DEBUG:\n+        print (\"PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d\" % (\n+            im.size[0], bits, stride))\n \n     # under windows, we could determine the current screen size with\n     # \"Image.core.display_mode()[1]\", but I think that's overkill...\n", "issue": "Some pcx images are displayed incorrectly\nHi everyone!\nI'm trying to use pcx images extracted from an old game (Might and Magic VI, the game has 2D UI over the 3D environment. This 2D UI is composed by various internal formats and pcx files.)\n\nThe problem is that one of these pcx is displayed incorrecly by pillow, while being displayed correctly by EyeOfGnome (gdk-pixbuf) image viewer.\nAnother pcx is displayed correctly by pillow!\n\nWhat do I mean by incorrectly? The bad image has a kind of \"red shift\" of pixels colors. the left border is a bit red. It' like a \"3D-ified\" image, it's a bit blurry and the whole is a bit darker.\n\nI opened the pcx files with an hex editor and the main difference I spotted in the pcx-header is that the wrong one has the \"48 byte palette\" field completely empty. while the other one has some data in it. But it shoudn't be a problem because other viewers display it correctly.\n\nI simply use this code\nimg = Image.open(pcxfilename)\nimg.show()\n\nthis archive contains the pcx files https://db.tt/td291VTh\n\ngdk-pixbuf decoding of pcx is a bit more complex than the pillow one:\ngdk-pixbuf/io-pcx.c VS libImaging/PcxDecode.c\n\nthanks for any help!\n\n![border](https://f.cloud.github.com/assets/130094/2161053/c8ed7598-94c1-11e3-8607-1f2ad1f208c1.png)\n\nSome pcx images are displayed incorrectly\nHi everyone!\nI'm trying to use pcx images extracted from an old game (Might and Magic VI, the game has 2D UI over the 3D environment. This 2D UI is composed by various internal formats and pcx files.)\n\nThe problem is that one of these pcx is displayed incorrecly by pillow, while being displayed correctly by EyeOfGnome (gdk-pixbuf) image viewer.\nAnother pcx is displayed correctly by pillow!\n\nWhat do I mean by incorrectly? The bad image has a kind of \"red shift\" of pixels colors. the left border is a bit red. It' like a \"3D-ified\" image, it's a bit blurry and the whole is a bit darker.\n\nI opened the pcx files with an hex editor and the main difference I spotted in the pcx-header is that the wrong one has the \"48 byte palette\" field completely empty. while the other one has some data in it. But it shoudn't be a problem because other viewers display it correctly.\n\nI simply use this code\nimg = Image.open(pcxfilename)\nimg.show()\n\nthis archive contains the pcx files https://db.tt/td291VTh\n\ngdk-pixbuf decoding of pcx is a bit more complex than the pillow one:\ngdk-pixbuf/io-pcx.c VS libImaging/PcxDecode.c\n\nthanks for any help!\n\n![border](https://f.cloud.github.com/assets/130094/2161053/c8ed7598-94c1-11e3-8607-1f2ad1f208c1.png)\n\n", "before_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# PCX file handling\n#\n# This format was originally used by ZSoft's popular PaintBrush\n# program for the IBM PC.  It is also supported by many MS-DOS and\n# Windows applications, including the Windows PaintBrush program in\n# Windows 3.\n#\n# history:\n# 1995-09-01 fl   Created\n# 1996-05-20 fl   Fixed RGB support\n# 1997-01-03 fl   Fixed 2-bit and 4-bit support\n# 1999-02-03 fl   Fixed 8-bit support (broken in 1.0b1)\n# 1999-02-07 fl   Added write support\n# 2002-06-09 fl   Made 2-bit and 4-bit support a bit more robust\n# 2002-07-30 fl   Seek from to current position, not beginning of file\n# 2003-06-03 fl   Extract DPI settings (info[\"dpi\"])\n#\n# Copyright (c) 1997-2003 by Secret Labs AB.\n# Copyright (c) 1995-2003 by Fredrik Lundh.\n#\n# See the README file for information on usage and redistribution.\n#\n\n__version__ = \"0.6\"\n\nfrom PIL import Image, ImageFile, ImagePalette, _binary\n\ni8 = _binary.i8\ni16 = _binary.i16le\no8 = _binary.o8\n\ndef _accept(prefix):\n    return i8(prefix[0]) == 10 and i8(prefix[1]) in [0, 2, 3, 5]\n\n##\n# Image plugin for Paintbrush images.\n\nclass PcxImageFile(ImageFile.ImageFile):\n\n    format = \"PCX\"\n    format_description = \"Paintbrush\"\n\n    def _open(self):\n\n        # header\n        s = self.fp.read(128)\n        if not _accept(s):\n            raise SyntaxError(\"not a PCX file\")\n\n        # image\n        bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1\n        if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:\n            raise SyntaxError(\"bad PCX image size\")\n\n        # format\n        version = i8(s[1])\n        bits = i8(s[3])\n        planes = i8(s[65])\n        stride = i16(s,66)\n\n        self.info[\"dpi\"] = i16(s,12), i16(s,14)\n\n        if bits == 1 and planes == 1:\n            mode = rawmode = \"1\"\n\n        elif bits == 1 and planes in (2, 4):\n            mode = \"P\"\n            rawmode = \"P;%dL\" % planes\n            self.palette = ImagePalette.raw(\"RGB\", s[16:64])\n\n        elif version == 5 and bits == 8 and planes == 1:\n            mode = rawmode = \"L\"\n            # FIXME: hey, this doesn't work with the incremental loader !!!\n            self.fp.seek(-769, 2)\n            s = self.fp.read(769)\n            if len(s) == 769 and i8(s[0]) == 12:\n                # check if the palette is linear greyscale\n                for i in range(256):\n                    if s[i*3+1:i*3+4] != o8(i)*3:\n                        mode = rawmode = \"P\"\n                        break\n                if mode == \"P\":\n                    self.palette = ImagePalette.raw(\"RGB\", s[1:])\n            self.fp.seek(128)\n\n        elif version == 5 and bits == 8 and planes == 3:\n            mode = \"RGB\"\n            rawmode = \"RGB;L\"\n\n        else:\n            raise IOError(\"unknown PCX mode\")\n\n        self.mode = mode\n        self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]\n\n        bbox = (0, 0) + self.size\n\n        self.tile = [(\"pcx\", bbox, self.fp.tell(), (rawmode, planes * stride))]\n\n# --------------------------------------------------------------------\n# save PCX files\n\nSAVE = {\n    # mode: (version, bits, planes, raw mode)\n    \"1\": (2, 1, 1, \"1\"),\n    \"L\": (5, 8, 1, \"L\"),\n    \"P\": (5, 8, 1, \"P\"),\n    \"RGB\": (5, 8, 3, \"RGB;L\"),\n}\n\no16 = _binary.o16le\n\ndef _save(im, fp, filename, check=0):\n\n    try:\n        version, bits, planes, rawmode = SAVE[im.mode]\n    except KeyError:\n        raise ValueError(\"Cannot save %s images as PCX\" % im.mode)\n\n    if check:\n        return check\n\n    # bytes per plane\n    stride = (im.size[0] * bits + 7) // 8\n\n    # under windows, we could determine the current screen size with\n    # \"Image.core.display_mode()[1]\", but I think that's overkill...\n\n    screen = im.size\n\n    dpi = 100, 100\n\n    # PCX header\n    fp.write(\n        o8(10) + o8(version) + o8(1) + o8(bits) + o16(0) +\n        o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +\n        o16(dpi[1]) + b\"\\0\"*24 + b\"\\xFF\"*24 + b\"\\0\" + o8(planes) +\n        o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +\n        b\"\\0\"*54\n        )\n\n    assert fp.tell() == 128\n\n    ImageFile._save(im, fp, [(\"pcx\", (0,0)+im.size, 0,\n                              (rawmode, bits*planes))])\n\n    if im.mode == \"P\":\n        # colour palette\n        fp.write(o8(12))\n        fp.write(im.im.getpalette(\"RGB\", \"RGB\")) # 768 bytes\n    elif im.mode == \"L\":\n        # greyscale palette\n        fp.write(o8(12))\n        for i in range(256):\n            fp.write(o8(i)*3)\n\n# --------------------------------------------------------------------\n# registry\n\nImage.register_open(\"PCX\", PcxImageFile, _accept)\nImage.register_save(\"PCX\", _save)\n\nImage.register_extension(\"PCX\", \".pcx\")\n", "path": "PIL/PcxImagePlugin.py"}], "after_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# PCX file handling\n#\n# This format was originally used by ZSoft's popular PaintBrush\n# program for the IBM PC.  It is also supported by many MS-DOS and\n# Windows applications, including the Windows PaintBrush program in\n# Windows 3.\n#\n# history:\n# 1995-09-01 fl   Created\n# 1996-05-20 fl   Fixed RGB support\n# 1997-01-03 fl   Fixed 2-bit and 4-bit support\n# 1999-02-03 fl   Fixed 8-bit support (broken in 1.0b1)\n# 1999-02-07 fl   Added write support\n# 2002-06-09 fl   Made 2-bit and 4-bit support a bit more robust\n# 2002-07-30 fl   Seek from to current position, not beginning of file\n# 2003-06-03 fl   Extract DPI settings (info[\"dpi\"])\n#\n# Copyright (c) 1997-2003 by Secret Labs AB.\n# Copyright (c) 1995-2003 by Fredrik Lundh.\n#\n# See the README file for information on usage and redistribution.\n#\n\n__version__ = \"0.6\"\n\nfrom PIL import Image, ImageFile, ImagePalette, _binary\n\ni8 = _binary.i8\ni16 = _binary.i16le\no8 = _binary.o8\n\ndef _accept(prefix):\n    return i8(prefix[0]) == 10 and i8(prefix[1]) in [0, 2, 3, 5]\n\n##\n# Image plugin for Paintbrush images.\n\nclass PcxImageFile(ImageFile.ImageFile):\n\n    format = \"PCX\"\n    format_description = \"Paintbrush\"\n\n    def _open(self):\n\n        # header\n        s = self.fp.read(128)\n        if not _accept(s):\n            raise SyntaxError(\"not a PCX file\")\n\n        # image\n        bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1\n        if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:\n            raise SyntaxError(\"bad PCX image size\")\n        if Image.DEBUG:\n            print (\"BBox: %s %s %s %s\" % bbox)\n\n\n        # format\n        version = i8(s[1])\n        bits = i8(s[3])\n        planes = i8(s[65])\n        stride = i16(s,66)\n        if Image.DEBUG:\n            print (\"PCX version %s, bits %s, planes %s, stride %s\" %\n                   (version, bits, planes, stride))\n\n        self.info[\"dpi\"] = i16(s,12), i16(s,14)\n\n        if bits == 1 and planes == 1:\n            mode = rawmode = \"1\"\n\n        elif bits == 1 and planes in (2, 4):\n            mode = \"P\"\n            rawmode = \"P;%dL\" % planes\n            self.palette = ImagePalette.raw(\"RGB\", s[16:64])\n\n        elif version == 5 and bits == 8 and planes == 1:\n            mode = rawmode = \"L\"\n            # FIXME: hey, this doesn't work with the incremental loader !!!\n            self.fp.seek(-769, 2)\n            s = self.fp.read(769)\n            if len(s) == 769 and i8(s[0]) == 12:\n                # check if the palette is linear greyscale\n                for i in range(256):\n                    if s[i*3+1:i*3+4] != o8(i)*3:\n                        mode = rawmode = \"P\"\n                        break\n                if mode == \"P\":\n                    self.palette = ImagePalette.raw(\"RGB\", s[1:])\n            self.fp.seek(128)\n\n        elif version == 5 and bits == 8 and planes == 3:\n            mode = \"RGB\"\n            rawmode = \"RGB;L\"\n\n        else:\n            raise IOError(\"unknown PCX mode\")\n\n        self.mode = mode\n        self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]\n\n        bbox = (0, 0) + self.size\n        if Image.DEBUG:\n            print (\"size: %sx%s\" % self.size)\n            \n        self.tile = [(\"pcx\", bbox, self.fp.tell(), (rawmode, planes * stride))]\n\n# --------------------------------------------------------------------\n# save PCX files\n\nSAVE = {\n    # mode: (version, bits, planes, raw mode)\n    \"1\": (2, 1, 1, \"1\"),\n    \"L\": (5, 8, 1, \"L\"),\n    \"P\": (5, 8, 1, \"P\"),\n    \"RGB\": (5, 8, 3, \"RGB;L\"),\n}\n\no16 = _binary.o16le\n\ndef _save(im, fp, filename, check=0):\n\n    try:\n        version, bits, planes, rawmode = SAVE[im.mode]\n    except KeyError:\n        raise ValueError(\"Cannot save %s images as PCX\" % im.mode)\n\n    if check:\n        return check\n\n    # bytes per plane\n    stride = (im.size[0] * bits + 7) // 8\n    # stride should be even\n    stride = stride + (stride % 2)\n    # Stride needs to be kept in sync with the PcxEncode.c version.\n    # Ideally it should be passed in in the state, but the bytes value\n    # gets overwritten. \n\n\n    if Image.DEBUG:\n        print (\"PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d\" % (\n            im.size[0], bits, stride))\n\n    # under windows, we could determine the current screen size with\n    # \"Image.core.display_mode()[1]\", but I think that's overkill...\n\n    screen = im.size\n\n    dpi = 100, 100\n\n    # PCX header\n    fp.write(\n        o8(10) + o8(version) + o8(1) + o8(bits) + o16(0) +\n        o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +\n        o16(dpi[1]) + b\"\\0\"*24 + b\"\\xFF\"*24 + b\"\\0\" + o8(planes) +\n        o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +\n        b\"\\0\"*54\n        )\n\n    assert fp.tell() == 128\n\n    ImageFile._save(im, fp, [(\"pcx\", (0,0)+im.size, 0,\n                              (rawmode, bits*planes))])\n\n    if im.mode == \"P\":\n        # colour palette\n        fp.write(o8(12))\n        fp.write(im.im.getpalette(\"RGB\", \"RGB\")) # 768 bytes\n    elif im.mode == \"L\":\n        # greyscale palette\n        fp.write(o8(12))\n        for i in range(256):\n            fp.write(o8(i)*3)\n\n# --------------------------------------------------------------------\n# registry\n\nImage.register_open(\"PCX\", PcxImageFile, _accept)\nImage.register_save(\"PCX\", _save)\n\nImage.register_extension(\"PCX\", \".pcx\")\n", "path": "PIL/PcxImagePlugin.py"}]}