[Image-SIG] Patch: Better compression of png-images

Flynn Marquardt pil at flynnux.de
Wed Jul 29 08:05:04 CEST 2009

Am Mittwoch, den 29.07.2009, 00:11 +0400 schrieb Alexey Borzenkov:
> On Tue, Jul 28, 2009 at 2:16 PM, Flynn Marquardt<pil at flynnux.de> wrote:
> > I never got corrupt images, but I applied the attached patch anyway.
> Well, it seemed that the bigger the image, the bigger the chance for
> corruption. In my case (with images 800x600 and the like in size) it
> was something like 2 corrupted images out of 20. I didn't even
> attribute it to Z_NO_FLUSH at first, thinking there was strange
> problems in my conversion logic, until I saw that ACDSee was saying
> "corrupt image" in the status bar.
OK, that's the difference, I only produce pictures of 256x256 pixels
(tiles of a map). so I never run into this ...

> > P.S.: There is another size bloating feature in PIL: all palettes are
> > stored full size (usually 256 entries) instead only storing the real
> > used colors. This especially is a problem with pictures with only a few
> > colors, where then the palette is much bigger than the compressed data.
> >
> > Do you see any chance to fix this? I took alook, but it seems not so
> > easy.
> Well, it certainly doesn't affect me. :) 1.1.6 doesn't seem to support
> partial palettes anyway, you can only assign all 256 colors, and
> remapping colors would be crazy (since I use PIL for game
> localizations mostly, I often need the *exact* palette [which is often
> separate and shared among several images in the game], and wouldn't
> want PIL to do anything fancy with it). Besides, that's under 1k
> anyway, you should definitely use pngcrush if sizes like that matter
> to you.
I'm only talking about pictures, that really have only a few different
colors in it. In the file PIL/PngImagePlugin.py the size is hard coded
        # attempt to minimize storage requirements for palette images

        if im.encoderinfo.has_key("bits"):

            # number of bits specified by user
            n = 1 << im.encoderinfo["bits"]


            # check palette contents
            n = 256 # FIXME

256 entries, and in libImaging/Quant.c the palette ist forced to have
256 entries:

        for (i = j = 0; i < (int) paletteLength; i++) {
            *pp++ = palette[i].c.r;
            *pp++ = palette[i].c.g;
            *pp++ = palette[i].c.b;
            *pp++ = 255;
        for (; i < 256; i++) {
            *pp++ = 0;
            *pp++ = 0;
            *pp++ = 0;
            *pp++ = 255;

Also I'm confused about the different methods for palettes:


I was not able to produce a patch, that fixes both. The second e.g. is
used in the png-plugin. 

More information about the Image-SIG mailing list