Skip to content

image/gif: last color in per-image Palette is different from global Palette #13724

@pierrre

Description

@pierrre

Go version: 1.5.2 & 1.6beta1

I tried to decode an animated GIF image. (https://raw.githubusercontent.com/pierrre/imageserver/master/testdata/animated.gif)
I get a GIF with a Palette ColorModel, and a slice of Paletted images.
If I compare the global palette, with the palette of each frame, the last color is different.

I wrote a small program:

package main

import (
    "bytes"
    "fmt"
    "image/color"
    "image/gif"
    "io/ioutil"
)

func main() {
    b, err := ioutil.ReadFile("/home/pierre/Go/src/github.com/pierrre/imageserver/testdata/animated.gif")
    if err != nil {
        panic(err)
    }
    g, err := gif.DecodeAll(bytes.NewReader(b))
    if err != nil {
        panic(err)
    }
    if g.Config.ColorModel == nil {
        fmt.Println("no global color model")
        return
    }
    pa, ok := g.Config.ColorModel.(color.Palette)
    if !ok {
        fmt.Println("global color model is not a Palette")
        return
    }
    if len(pa) == 0 {
        fmt.Println("global palette is empty")
        return
    }
    for i, p := range g.Image {
        if len(p.Palette) != len(pa) {
            fmt.Printf("image %d: palette length is not equal: current=%d, global=%d\n", i, len(p.Palette), len(pa))
            continue
        }
        for j := range p.Palette {
            if p.Palette[j] != pa[j] {
                fmt.Printf("image %d: palette index %d: color is not equal: current=%#v, global=%#v\n", i, j, p.Palette[j], pa[j])
            }
        }
    }
    fmt.Printf("background index: %d\n", g.BackgroundIndex)
}

I get:

image 0: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 1: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 2: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 3: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 4: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 5: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 6: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 7: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 8: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 9: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 10: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 11: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 12: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 13: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 14: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 15: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 16: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 17: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 18: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 19: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 20: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 21: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 22: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 23: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 24: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 25: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 26: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 27: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 28: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 29: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 30: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 31: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 32: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 33: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 34: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
image 35: palette index 255: color is not equal: current=color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, global=color.RGBA{R:0xff, G:0xff, B:0xff, A:0xff}
background index: 255

At index 255, the color is transparent in all frames, and white in the global palette.

If the ColorModel is defined in GIF, and it's a non empty Palette, I expect to have the same Palette in all frames.

Is it related to the background color index?

Thank you.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions