<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
<font face="Verdana"><br>
I recently downloaded the Python Imaging Library (PIL 1.1.5), and I
have been trying to use it to convert several hundred XPM files into
GIFs (I also tried converting into PNGs which may be useful in the
future).&nbsp; During this process, I ran into various problems which appear
to be caused by bugs.<br>
<br>
Most of the difficulties were related to XPMs -- not being able to load
XPM files which other applications were quite happy with.&nbsp; But there
were also a couple of minor issues with transparency in GIF and PNG
formats. <br>
<br>
Attached is a diff file containing the changes I had to make to the
code to fix these problems.&nbsp; This fixes things for the vast majority of
the XPM files I have.&nbsp; There are still some XPMs that can't be loaded
(those which use more than one character per pixel for example), but
these are far less common.<br>
<br>
<br>
Because I am not a regular contributer to this project I thought I
should include more information than just the diffs, so here is a list
of the bugs I found and what I changed as a result: <br>
<br>
<br>
</font><br>
<font face="Verdana"><b>Bug:</b> PIL could not open some XPM files
because it failed to cope with some features of XPM syntax.</font><br>
<br>
<font face="Verdana"><b>Fix:&nbsp;</b> Various changes in XpmImagePlugin.py:</font><br>
<br>
<ul>
  <li><font face="Verdana">Changed the RE used to match the image
header to one that copes with leading spaces and multiple spaces
between words.</font></li>
</ul>
<ul>
  <li><font face="Verdana">In XpmImageFile._open(), when reading the
image palette:</font></li>
</ul>
<blockquote>
  <ul>
    <li><font face="Verdana">Ignore lines which are commented-out.</font></li>
    <li><font face="Verdana">Strip leading and trailing whitespace
before processing.</font></li>
    <li><font face="Verdana">Remove case sensitivity when looking for
"None".</font></li>
    <li><font face="Verdana">Use ImageColor.getrgb() to interpret color
values.</font></li>
    <li><font face="Verdana">Look ahead to detect colour names
consisting of multiple words</font></li>
  </ul>
</blockquote>
<ul>
  <li><font face="Verdana">In XpmImageFile.load_read() (when reading
the pixels) ignore lines which are commented-out.</font></li>
</ul>
<br>
<br>
<br>
<br>
<font face="Verdana"><b>Bug: </b>PIL could not open some XPM files,
because the color names were not recognized.</font><br>
<br>
<font face="Verdana"><b>Fix: </b>various changes to ImageColor.py:</font><br>
<br>
<ul>
  <li><font face="Verdana">Changed the colormap to the standard list of
X11 colours (as found on any Unix or Linux system).</font></li>
</ul>
<blockquote><font face="Verdana"><b>Note</b>: before this change, the
colormap apparently contained colours taken from CSS3 -- the comment
reads 'X11 colour table (from "CSS3 module: Color working draft")'.&nbsp;
However some of the standard X11 colours clashed with existing colours
in the map.&nbsp; In the end, I removed all the CSS3 colours and just
included the X11 colours.&nbsp; The comment does say "X11 colour table"
after all.</font></blockquote>
<ul>
  <li><font face="Verdana">getrgb(): Remove spaces from the color name
in order to find a match.&nbsp; X11 has variations of some color names, such
as "light blue" and "LightBlue".&nbsp;&nbsp; But the version with spaces was not
recognized.</font></li>
</ul>
<ul>
  <li><font face="Verdana">getrgb(): Recognize colours specified as a
48-bit RGB string (e.g. #FFFF0000AAAA).&nbsp; These are sometimes
encountered in XPMs.&nbsp; The 3 bytes of extra precision are ignored, and
the returned RGB value is a standard 24-bit RGB tuple.</font></li>
</ul>
<font face="Verdana"><br>
<br>
<br>
<b>Bug:</b> PIL loaded all XPM files incorrectly, shifting the entire
image several pixels to the right (truncating it on the right, and
adding a a band of incorrect pixels on the left).<br>
<br>
This is caused by trying to use memory mapping to read the file, which
prevents the proper XPM decoder from being used.&nbsp; Memory mapping does
not work because of the structure of XPM files -- the file includes
characters (such as the opening and closing quotes on each line) which
do not correspond to pixel values.<br>
<br>
<b>Fix:</b> Changed load() in ImageFile.py to explicitly exclude XPM
files from the memory mapping. <br>
</font><br>
<font face="Verdana">There may be a more elegent way to do this,
perhaps by changing the value of ImageFile.tile for XPMs.&nbsp; But I tried
the obvious thing -- changing the "raw" designation to something else,
and that seemed to break things even more.&nbsp;&nbsp; Perhaps someone more
familiar with this code could do better.</font><br>
<font face="Verdana"><br>
<br>
<br>
<b>Bug:</b> Could not write GIFs with transparency.&nbsp; The pixels which
should have been transparent were not.<br>
<br>
<b>Fix:</b> Changed _save() in GifImagePlugin.py.&nbsp;&nbsp; The code was
looking in the wrong dictionary for the transparency value.<br>
<br>
<br>
<b><br>
Bug:</b> Could not write PNGs with transparency.&nbsp; The pixels which
should have been transparent were not.<br>
<br>
<b>Fix:</b> Changed _save() in PngImagePlugin.py.&nbsp; The code was looking
in the wrong dictionary for the transparency value.<br>
<br>
<br>
-- <br>
Tom Heathcote</font><br>
<pre class="moz-signature" cols="72">-- 
Tom Heathcote              Petris Technology
<a class="moz-txt-link-abbreviated"
 href="mailto:tom.heathcote@petris.com">tom.heathcote@petris.com</a>   154 Brent Street
Tel +44 20 8202 2433       London  NW4 2DR
Fax +44 20 8202 2287       England
</pre>
</body>
</html>