boutell: (Default)
[personal profile] boutell
The gd graphics library is and for many years has been the standard way of generating graphics on the fly in PHP and a lot of other web development languages. When you call imagecreatefromjpeg in PHP, you're using gd.

There are excellent alternatives that are in fact more capable in many ways, but people still dig gd for its dead-simple API and stodgy reliability.

gd is my doing— I originally built it back in '93 for a project at Cold Spring Harbor Laboratory and, in part since it was heavily based on freely available GIF compression and decompression code by Jef Poskanzer and David Rowley, I was able to make it open source software.

gd didn't catch on because of particularly brilliant code, I can say that for certain, but rather because it was easy to use and had a very consistent API. Things work like you'd expect and are called what you'd guess. I'm not much of a graphic designer, but it's fair to call me a good API designer (when I'm not being sloppy).

gd has been largely stable but did go through a few big changes. When Unisys suddenly began enforcing their patent on the compression used in GIF images, GIF compression had to disappear from gd for a few years. Folks who patched it back in without telling me as part of other contributions to gd taught me to read every line of code contributions carefully.

Then came gd 2.0, with support for truecolor images— meaning faithful reproduction of photos and support for JPEG— and alpha channels. Truecolor was widely appreciated. My somewhat sleazy implementation of alpha channels— only seven bits rather than eight to avoid big changes to the entire API— is not as widely used, partly because PNG alpha channel was supported so poorly by browsers for so long.

The last versions I was involved with saw the addition of animated GIF output support, which never quite made it into the PHP documentation. Since PHP has become by far the most public face of gd, that meant that it never really entered the consciousness of the average developer.

A few years ago I passed on maintenance of the gd library to Pierre-Alain Joye of the PHP project. I wasn't dealing with contributions in a timely manner and my work rarely involved graphics at the time, so it was time to pass the baton of this particular "cathedral-style," benevolently-dictated open source project to a more motivated party. Now gd seems to have gone a bit stale in its new home as well, but this is not entirely a bad thing since the code is quite mature and doesn't need radical transformation.

However... there is no such thing as bug-free code.

Yesterday I needed code to generate animated GIFs and, ironically, didn't remember gd's support for animated GIF output right away. It took me a bit of banging around to realize a fine solution for turning perfectly good JPEG photos into silly animated GIFs was right under my nose.

Unfortunately, it didn't work. With 256-color GIFs, I kept producing invalid GIF files. Which led me, for the first time in nearly a decade, to the gd source code that generates the GIF header:

        /*
         * Indicate that there is a global colour map
         */
        B = GlobalCM ? 0x80 : 0;

        /*
         * OR in the resolution
         */
        B |= (Resolution - 1) << 5;


With an 8-bit palette, Resolution - 1 = 7. Shift left five bits and you have just crushed the global colormap flag.

Augh! No wonder my animated GIFs with local colormaps weren't working.

I consulted the GIF specification and found the resolution should have been shifted over only four bits.

This bug is old. I mean, really old. It goes back to the code I borrowed from Jef Poskanzer who borrowed from it David Rowley who wrote it back in the year dot. Even the tool I used to track down the bug is old. It was never reported before because the resolution field is universally ignored and single-image GIFs made by gd always have a "global" colormap anyway. So the bug never manifested itself before animated GIF support was added.

I've submitted a bug fix to the new gd team, and given them a nudge elsewhere just in case they are, like me, sleeping comfortably knowing that gd can't possibly have any bugs left after seventeen years of happy production use... right?

It may take a while for that fix, along with the long-delayed documentation of and wrapper functions for animated GIF support, to find its way into PHP. But I plan to be a more vocal advocate for maintenance of gd now that it's back in my professional life as a web developer, among other things too sneaky and sekrit to talk about just now.

Date: 2010-08-22 05:29 pm (UTC)

Date: 2010-08-22 06:43 pm (UTC)
From: [identity profile] sambushell.livejournal.com
Nice illustrative example. I'm not even sure that a fairly strong unit test suite would have been likely to catch this.

Date: 2010-08-22 06:57 pm (UTC)
xtingu: (geek)
From: [personal profile] xtingu
I really enjoyed reading this.
That is all.

Date: 2010-08-22 08:20 pm (UTC)
From: [identity profile] wisn.livejournal.com
The edge case was phoning from downstairs!

September 2014

S M T W T F S
 123456
78910111213
14151617181920
2122232425 2627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Oct. 17th, 2017 10:19 pm
Powered by Dreamwidth Studios