IOError: decoder jpeg not available
Moving a Zope instance made Plone sites lose image thumbnail generation. Seemingly odd PIL behaviour.
As often happens in hosting we recently moved some sites from one server to another. In this case a server had gone bang and so we rebuilt everything on a new server running the latest Ubuntu LTS.
Of course, one issue in moving the hosting was that the new server installation didn't come with the same versions of software installed as the old one did. In this case our Zope instance needs Python 2.3 - a fine vintage - but our new Ubuntu installation has Python 2.5 as the lowest available version for install by the package manager.
Thankfully, in the open source world it's easy to build older versions to run pretty much anywhere you want; so in a very short time we had the Zope instance up and running on our homemade Python 2.3 complete with Python Imaging Library (PIL).
Or so we thought.
After a short while we noticed an issue that thumbnails were not being generated when new images were uploaded. In the log was found:
File ".../lib/python2.3/site-packages/PIL/ImageFile.py", line 189, in load
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
File "...lib/python2.3/site-packages/PIL/Image.py", line 385, in _getdecoder
raise IOError("decoder %s not available" % decoder_name)
IOError: decoder jpeg not available
This error suggests that PIL had not been built with libjpeg support, however when building PIL it had output the following:
*** PIL CORE support not installed *** TKINTER support not installed --- JPEG support ok --- ZLIB (PNG/ZIP) support ok *** FREETYPE2 support not installed *** LITTLECMS support not installed
which indicates that libjpeg and zlib were both found during the build.
After a bit of rebuilding and head scratching the Plone community came to the rescue here:
http://plone.org/documentation/error/ioerror-decoder-jpeg-not-available
In our case we had simply omitted to specify the root of the libjpeg install (for us this is simply /usr because it was installed by the package manager).
So the crucial thing for us was to replace in PIL's setup.py :
JPEG_ROOT = None ZLIB_ROOT = None
JPEG_ROOT = libinclude("/usr/")
ZLIB_ROOT = libinclude("/usr/")It's a bit odd that it goes on and builds anyway with this missing but now we know about it we'll be looking out for it next time.



