[Image-SIG] Fixes to PIL for handling XPM files.

Tom Heathcote tom.heathcote at petris.com
Tue Oct 24 17:07:24 CEST 2006


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).  
During this process, I ran into various problems which appear to be 
caused by bugs.

Most of the difficulties were related to XPMs -- not being able to load 
XPM files which other applications were quite happy with.  But there 
were also a couple of minor issues with transparency in GIF and PNG 
formats.

Attached is a diff file containing the changes I had to make to the code 
to fix these problems.  This fixes things for the vast majority of the 
XPM files I have.  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.


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:



*Bug:* PIL could not open some XPM files because it failed to cope with 
some features of XPM syntax.

*Fix: * Various changes in XpmImagePlugin.py:

    * Changed the RE used to match the image header to one that copes
      with leading spaces and multiple spaces between words.

    * In XpmImageFile._open(), when reading the image palette:

        * Ignore lines which are commented-out.
        * Strip leading and trailing whitespace before processing.
        * Remove case sensitivity when looking for "None".
        * Use ImageColor.getrgb() to interpret color values.
        * Look ahead to detect colour names consisting of multiple words

    * In XpmImageFile.load_read() (when reading the pixels) ignore lines
      which are commented-out.





*Bug: *PIL could not open some XPM files, because the color names were 
not recognized.

*Fix: *various changes to ImageColor.py:

    * Changed the colormap to the standard list of X11 colours (as found
      on any Unix or Linux system).

    *Note*: before this change, the colormap apparently contained
    colours taken from CSS3 -- the comment reads 'X11 colour table (from
    "CSS3 module: Color working draft")'.  However some of the standard
    X11 colours clashed with existing colours in the map.  In the end, I
    removed all the CSS3 colours and just included the X11 colours.  The
    comment does say "X11 colour table" after all.

    * getrgb(): Remove spaces from the color name in order to find a
      match.  X11 has variations of some color names, such as "light
      blue" and "LightBlue".   But the version with spaces was not
      recognized.

    * getrgb(): Recognize colours specified as a 48-bit RGB string (e.g.
      #FFFF0000AAAA).  These are sometimes encountered in XPMs.  The 3
      bytes of extra precision are ignored, and the returned RGB value
      is a standard 24-bit RGB tuple.




*Bug:* 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).

This is caused by trying to use memory mapping to read the file, which 
prevents the proper XPM decoder from being used.  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.

*Fix:* Changed load() in ImageFile.py to explicitly exclude XPM files 
from the memory mapping.

There may be a more elegent way to do this, perhaps by changing the 
value of ImageFile.tile for XPMs.  But I tried the obvious thing -- 
changing the "raw" designation to something else, and that seemed to 
break things even more.   Perhaps someone more familiar with this code 
could do better.



*Bug:* Could not write GIFs with transparency.  The pixels which should 
have been transparent were not.

*Fix:* Changed _save() in GifImagePlugin.py.   The code was looking in 
the wrong dictionary for the transparency value.


*
Bug:* Could not write PNGs with transparency.  The pixels which should 
have been transparent were not.

*Fix:* Changed _save() in PngImagePlugin.py.  The code was looking in 
the wrong dictionary for the transparency value.


-- 
Tom Heathcote

-- 
Tom Heathcote              Petris Technology
tom.heathcote at petris.com   154 Brent Street
Tel +44 20 8202 2433       London  NW4 2DR
Fax +44 20 8202 2287       England

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/image-sig/attachments/20061024/257bf27f/attachment-0001.htm 
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: changes.diff
Url: http://mail.python.org/pipermail/image-sig/attachments/20061024/257bf27f/attachment-0001.diff 


More information about the Image-SIG mailing list