Commit a54dca83 authored by Rob Pike's avatar Rob Pike

image/gif: implement transparency.

At least, as I understand it. The spec is unclear about what happens
with a local color map.

R=nigeltao, r2
CC=golang-dev
https://golang.org/cl/4515045
parent 38d7bcf5
...@@ -69,13 +69,13 @@ type decoder struct { ...@@ -69,13 +69,13 @@ type decoder struct {
// From image descriptor. // From image descriptor.
imageFields byte imageFields byte
// From graphics control.
transparentIndex byte
// Computed. // Computed.
pixelSize uint pixelSize uint
globalColorMap image.PalettedColorModel globalColorMap image.PalettedColorModel
// Computed but unused (TODO).
transparentIndex byte
// Used when decoding. // Used when decoding.
delay []int delay []int
image []*image.Paletted image []*image.Paletted
...@@ -165,6 +165,8 @@ Loop: ...@@ -165,6 +165,8 @@ Loop:
if err != nil { if err != nil {
break break
} }
// TODO: do we set transparency in this map too? That would be
// d.setTransparency(m.Palette)
} else { } else {
m.Palette = d.globalColorMap m.Palette = d.globalColorMap
} }
...@@ -304,13 +306,19 @@ func (d *decoder) readGraphicControl() os.Error { ...@@ -304,13 +306,19 @@ func (d *decoder) readGraphicControl() os.Error {
} }
d.flags = d.tmp[1] d.flags = d.tmp[1]
d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
if d.flags&gcTransparentColorSet != 0 { if d.flags&gcTransparentColorSet == 0 {
d.transparentIndex = d.tmp[4] d.transparentIndex = d.tmp[4]
return os.ErrorString("gif: can't handle transparency") d.setTransparency(d.globalColorMap)
} }
return nil return nil
} }
func (d *decoder) setTransparency(colorMap image.PalettedColorModel) {
if int(d.transparentIndex) < len(colorMap) {
colorMap[d.transparentIndex] = image.RGBAColor{}
}
}
func (d *decoder) newImageFromDescriptor() (*image.Paletted, os.Error) { func (d *decoder) newImageFromDescriptor() (*image.Paletted, os.Error) {
if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil { if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil {
return nil, fmt.Errorf("gif: can't read image descriptor: %s", err) return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
...@@ -336,8 +344,7 @@ func (d *decoder) readBlock() (int, os.Error) { ...@@ -336,8 +344,7 @@ func (d *decoder) readBlock() (int, os.Error) {
// Decode reads a GIF image from r and returns the first embedded // Decode reads a GIF image from r and returns the first embedded
// image as an image.Image. // image as an image.Image.
// Limitation: The file must be 8 bits per pixel and have no interlacing // Limitation: The file must be 8 bits per pixel and have no interlacing.
// or transparency.
func Decode(r io.Reader) (image.Image, os.Error) { func Decode(r io.Reader) (image.Image, os.Error) {
var d decoder var d decoder
if err := d.decode(r, false); err != nil { if err := d.decode(r, false); err != nil {
...@@ -355,8 +362,7 @@ type GIF struct { ...@@ -355,8 +362,7 @@ type GIF struct {
// DecodeAll reads a GIF image from r and returns the sequential frames // DecodeAll reads a GIF image from r and returns the sequential frames
// and timing information. // and timing information.
// Limitation: The file must be 8 bits per pixel and have no interlacing // Limitation: The file must be 8 bits per pixel and have no interlacing.
// or transparency.
func DecodeAll(r io.Reader) (*GIF, os.Error) { func DecodeAll(r io.Reader) (*GIF, os.Error) {
var d decoder var d decoder
if err := d.decode(r, false); err != nil { if err := d.decode(r, false); err != nil {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment