PIL and jpeg “decoding error” — THE REVENGE

OS: 10.6.6
PIL: 1.1.6 (initially), 1.1.7 (eventually)
IJG JPEG: 7 (initially, 8 (eventually)

Scroll down to SOLUTION if that’s what you want.

My hard-fought installation of PIL was not letting me work with JPEGs. When I tried, I got this:


from PIL import Image
img = Image.open("/Some/image/path.jpg")
#No problem; hasn't loaded yet
img.load()
#IOError: decoding error when reading image file

SAD BOOSH.

I Googled many, many things and tried many, many things to install PIL correctly. I tried the procedure I had before (linked above). I tried installing all permutations of IJG’s JPEG libraries (jpeg-6 to jpeg-8) and PIL (Imaging 1.1.6 and Imaging 1.1.7), because 1.1.7′s documentation still lists jpeg-6 or jpeg-6b as a requisite, and I couldn’t be sure that was a mistake (comments lie! Agile forever! BLARRRGH!)

Per the advice of various message boards and blogs, I cleaned away the PIL and libjpeg presence on my machine before every install attempt:


find . -name PIL\*
and delete away!

I tried gcc-4.0 and gcc-4.2. Neither worked.

I checked the linkage of the created PIL library, and it seemed good each time. The farthest I got was with PIL 1.1.7 and JPEG library 8, and the linkage details were these:


> otool -L /Library/Python/2.6/site-packages/PIL/_imaging.so
/Library/Python/2.6/site-packages/PIL/_imaging.so:
   /opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
   /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

By “the farthest I got,” I mean I got the following warning buried in the output when running “make” on PIL:


_imaging.c:3017: warning: initialization from incompatible pointer type
_imaging.c:3077: warning: initialization from incompatible pointer type

(some details on this warning)

I was like, huh, maybe that’s no big deal? But when I ran selftest.py on the installation (and yes I checked that selftest.py was running on the proper PIL), I got this message:


--- TKINTER support ok
--- JPEG support ok
--- ZLIB (PNG/ZIP) support ok
--- FREETYPE2 support ok
Hide footer
*****************************************************************
Failure in example: _info(Image.open("Images/lena.jpg"))
from line #24 of selftest.testimage
Exception raised:
Traceback (most recent call last):
File "./doctest.py", line 499, in _run_examples_inner
exec compile(source, "", "single") in globs
File "", line 1, in
File "./selftest.py", line 22, in _info
im.load()
File "PIL/ImageFile.py", line 207, in load
raise IOError(error + " when reading image file")
IOError: decoding error when reading image file
1 items had failures:
1 of 57 in selftest.testimage
***Test Failed*** 1 failures.
*** 1 tests of 57 failed.

So I guess those warnings did matter. Depressing. I couldn’t load a jpeg. I tried and tried my installation every which way, but I couldn’t.

So finally I just freakin’ asked a teammate how he did it. And he said he just followed the normal instructions for IJG JPEG 8 and PIL 1.1.7 and everything worked and it was no big deal.

So I tried that.

And I still got the above “decoding error” on selftest.py.

So depressing.

So then I was like, “Dang it. Just give me your PIL folder.”

And he gave me his PIL folder (from /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages).

And I copied it to the following locations on my computer:

/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
/Library/Python/2.6/site-packages

And then I ran python.


>>> pilImage = Image.open("/Some/image/file.jpg")
>>> pilImage.load()

THAT’S IT. That’s what I’d been waiting for all day. ALL DAY.

You want to do this, too? Here’s the zip of the PIL installation he gave me — with various linkages detailed below:

PIL 1.1.7 linked against jpeg-8

(Note that I was able to paste this folder because I had jpeg-8 installed — and according to its normal, boring installation instructions in its install.txt. Nothing special. Nothing fancy.)

Curiously, I ran otool on the good PIL installation, and this was the result:


[developer2 5] ~ > otool -L /Library/Python/2.6/site-packages/PIL/_imaging.so
/Library/Python/2.6/site-packages/PIL/_imaging.so:
/opt/local/lib/libjpeg.8.dylib (compatibility version 9.0.0, current version 9.2.0)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 103.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

So he has two more linkages, and his apparent version of jpeg-8 was different from mine. I have no idea if that’s significant.

He also said he may have set an architecture flag during his installation process, and he suspects that’s what made the difference. He’s the one with the working PIL, so I’m tempted to believe him.

SOLUTION

Backfiguring from that, I found PIL + libjpeg on Mac with no stress,I hope :-) on Sickk’s Blog. Here is Sickk’s command for installing libjpeg on Snow Leopard:


CC="gcc -arch i386" ./configure --enable-static --enable-shared

Dammit all to hell. This was two links away from a page I was working from during all my installation attempts, and I just never clicked on it. I guess I should be grateful and not mad. I’m gramadful. Thank you, Sickk.

libjpeg installs to /usr/local/lib by default, so the line you want to edit in PIL’s setup.py is probably:


JPEG_ROOT = libinclude("usr/local")

This link on libjpeg might also be useful.