Repository: python-pillow/Pillow

Issue:
Changed int conversion in ImagePalette to ord for Python 2
Error reported in #1592



Discussion:
I'm not convinced that this is the right approach yet. 

There's got to be something screwy with the palette, because if it was just an bytes/int conversion issue, then we'd likely have run across this before. The code's been in there since the conversion to py3. 

What's the character that's throwing it off? How is it encoded in the palette?

The palette string is -

```
b'\x00\x01\x002313424635746857968979:8:;9;=:<>;=?<>@=?@>@A?AB@ACACEBDFCEGDFHEGIFHIGIJHJKIJLJLNKMOLNPMOQNPROQSPRTQSTRTUSUVTVWUVXUWYVY[XZ\\Y[]Z\\^[]_\\^`]_a^`b_ac`bdacebdecefdfgeghfhighjgikhjlikmjlnkmolnpmoqnqsprtqsurtvsuwtvxuwyvxzwy{xz|y{}z|~{}\x7f|~\x80}\x7f\x81~x\x8a:\x80\x82\x7f\x81\x83\x80z\x8c<\x82\x84\x81\x83\x85\x82\x84\x86\x83}\x8f?\x85\x87\x84\x86\x88\x85\x87\x89\x86\x88\x8a\x87\x89\x8b\x88\x83\x94D\x8a\x8c\x89\x8b\x8d\x8a\x8c\x8e\x8b\x8d\x8f\x8c\x8e\x90\x8d\x8f\x91\x8e\x90\x92\x8f\x91\x93\x90\x92\x94\x91\x93\x95\x92\x94\x96\x93\x95\x97\x94\x96\x98\x95\x97\x99\x96\x98\x9a\x97\x9a\x9b\x98\x9b\x9d\x99\x9c\x9e\x9b\x9d\x9f\x9c\x9e\xa0\x9d\x9f\xa1\x9e\xa0\xa2\x9f\x9c\xaaf\xa1\xa3\xa0\xa2\xa4\xa1\xa3\xa5\xa2\xa4\xa6\xa3\xa5\xa7\xa4\xa6\xa8\xa5\xa7\xa9\xa6\xa8\xaa\xa7\xa9\xab\xa8\xaa\xac\xa9\xab\xad\xaa\xa5\xbb<\xac\xae\xab\xa6\xbc=\xad\xaf\xac\xa7\xbd>\xae\xb0\xad\xa8\xbe?\xb0\xb2\xae\xb1\xb3\xaf\xb2\xb4\xb1\xb3\xb5\xb2\xb4\xb6\xb3\xb5\xb7\xb4\xb6\xb8\xb5\xb7\xb9\xb6\xb8\xba\xb7\xb9\xbb\xb8\xb0\xc8W\xba\xbc\xb9\xbb\xbd\xba\xb1\xcdD\xbc\xbe\xbb\xb2\xceE\xbd\xbf\xbc\xb4\xcfF\xbe\xc1\xbd\xb5\xd0G\xb3\xd0O\xc0\xc2\xbe\xb5\xd1P\xc1\xc3\xbf\xb6\xd2Q\xc2\xc4\xc1\xb7\xd3R\xbc\xd2R\xc3\xc5\xc2\xbe\xd3S\xc4\xc6\xc3\xbc\xd3[\xc5\xc7\xc4\xbd\xd4\\\xc6\xc8\xc5\xbe\xd5]\xc7\xc9\xc6\xbe\xd6e\xc8\xca\xc7\xc9\xcb\xc8\xbf\xd8f\xca\xcc\xc9\xc0\xd9g\xbf\xd9n\xc9\xd1\xa6\xc6\xd8o\xc0\xdao\xcb\xce\xca\xcd\xcf\xcb\xc7\xdap\xc5\xdav\xce\xd0\xcc\xcf\xd1\xce\xd0\xd2\xcf\xc9\xddz\xc7\xdd\x80\xd1\xd3\xd0\xc8\xde\x81\xd2\xd4\xd1\xc9\xdf\x82\xcf\xde\x82\xd3\xd5\xd2\xd0\xdf\x83\xd4\xd6\xd3\xd5\xd7\xd4\xd1\xdf\x98\xd6\xd8\xd5\xd8\xda\xd6\xd1\xe4\x94\xd9\xdb\xd7\xd8\xe3\x96\xd2\xe5\x95\xda\xdc\xd9\xd7\xe4\x9d\xdb\xdd\xda\xdc\xde\xdb\xd8\xe6\x9e\xdd\xdf\xdc\xd9\xe7\x9f\xde\xe0\xdd\xd8\xe8\xa6\xdf\xe1\xde\xd9\xe9\xa7\xe0\xe2\xdf\xda\xea\xa8\xde\xe9\xaf\xe1\xe4\xe0\xe3\xe5\xe1\xe4\xe6\xe3\xe5\xe7\xe4\xe6\xe8\xe5\xe7\xe9\xe6\xe8\xea\xe7\xe7\xef\xc3\xe9\xeb\xe8\xe8\xf0\xc4\xea\xec\xe9\xeb\xee\xea\xed\xef\xeb\xee\xf0\xed\xef\xf1\xee\xf0\xf2\xef\xf1\xf3\xf0\xf2\xf4\xf1\xf3\xf5\xf2\xf4\xf7\xf3\xf6\xf8\xf4\xf7\xf9\xf6\xf8\xfa\xf7\xf9\xfb\xf8\xfa\xfc\xf9\xfb\xfd\xfa\xfc\xff\xfb\xfe\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
```

It looks to me like the '\x00' character is being rendered as '' in Python 2, but converted by int by Python 3.

So, any palette that contains black (#000000) should error out in python 2.x with PIL from 2012 through current master.  


Resolving patch:
diff --git a/PIL/ImagePalette.py b/PIL/ImagePalette.py
--- a/PIL/ImagePalette.py
+++ b/PIL/ImagePalette.py
@@ -38,7 +38,7 @@ class ImagePalette(object):
     def __init__(self, mode="RGB", palette=None, size=0):
         self.mode = mode
         self.rawmode = None  # if set, palette contains raw data
-        self.palette = palette or list(range(256))*len(self.mode)
+        self.palette = palette or bytearray(range(256))*len(self.mode)
         self.colors = {}
         self.dirty = None
         if ((size == 0 and len(self.mode)*256 != len(self.palette)) or
@@ -98,7 +98,7 @@ def getcolor(self, color):
             except KeyError:
                 # allocate new color slot
                 if isinstance(self.palette, bytes):
-                    self.palette = [int(x) for x in self.palette]
+                    self.palette = bytearray(self.palette)
                 index = len(self.colors)
                 if index >= 256:
                     raise ValueError("cannot allocate more than 256 colors")


Test patch:
diff --git a/Tests/images/chi.gif b/Tests/images/chi.gif
new file mode 100644
Binary files /dev/null and b/Tests/images/chi.gif differ
diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py
--- a/Tests/test_imagedraw.py
+++ b/Tests/test_imagedraw.py
@@ -52,6 +52,13 @@ def test_removed_methods(self):
         self.assertRaises(Exception, lambda: draw.setink(0))
         self.assertRaises(Exception, lambda: draw.setfill(0))
 
+    def test_valueerror(self):
+        im = Image.open("Tests/images/chi.gif")
+
+        draw = ImageDraw.Draw(im)
+        draw.line(((0, 0)), fill=(0, 0, 0))
+        del draw
+
     def test_mode_mismatch(self):
         im = hopper("RGB").copy()