[Image-SIG] Animated GIF problem

Noboru Uchida noboru.uchida.777 at gmail.com
Thu Nov 13 12:51:02 CET 2008

Hi. Excuse my poor English.

* Problem:

Some animated GIFs can't be played properly.
You can see this using "player.py" sample script and
Animated GIF files, which doesn't have per-frame palettes.

When playing back Animated GIFs, you can use Image.seek(),
then you call Image.paste() or something.

I found this is not enough for animated GIF file, which doesn't have
per-frame local palette informations.

In such a file, the global palette *must* be used to render GIF frame,
but the global palette doesn't seem properly used by PIL.
As a result, after second frame, rendering results are broken.

* Reason:

1. In GifImageFile._open(), ImagePalette instance for
the global palette is created using ImagePalette.raw(),
and saved as "global_palette" variable.

2. In GifImageFile.seek(), when GIF file doesn't have per-flame local
palette, global palette is set to "palette" variable.
This is not a copy. Now both "palette" and "global_palette"
point to same ImagePalette instance.

3. In Image.load(), palette.dirty, palette.mode and palette.rawmode
are overwritten (why?).

4. When seeking to second frame, and second frame doesn't have local
palette, variable "palette" is set to "global_palette".
But, this time, "global_palette" is already overwritten in step 3.

5. In Image.load(), this time, palette.dirty is None. More over,
palette.rawmode is broken because of step 3.
As a result, proper palette information seems not given to C
implementation code.

* Workaround:

After seek(), I can manually fix palette information as following:

image.palette.dirty = 1
image.palette.rawmode = "RGB"

and do loading/rendering jobs.
But, I think this should be done in PIL code, not users' one.

More information about the Image-SIG mailing list