aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2011-07-19 11:47:15 +1000
committerRob Pike <r@golang.org>2011-07-19 11:47:15 +1000
commita5a94f5d57842e0914767cbe78fd821bfd291c9f (patch)
tree686f92f26f881da003651e0fa5eaa29e6c06320c
parent7a18fc3bcb75bb92dc382dac5c6e9105ab861e5f (diff)
downloadgo-a5a94f5d57842e0914767cbe78fd821bfd291c9f.tar.gz
go-a5a94f5d57842e0914767cbe78fd821bfd291c9f.zip
gif: fix local color map and coordinates
R=nigeltao CC=golang-dev https://golang.org/cl/4759051
-rw-r--r--src/pkg/image/gif/reader.go33
1 files changed, 19 insertions, 14 deletions
diff --git a/src/pkg/image/gif/reader.go b/src/pkg/image/gif/reader.go
index 98ac01cca2..e39b797460 100644
--- a/src/pkg/image/gif/reader.go
+++ b/src/pkg/image/gif/reader.go
@@ -28,7 +28,9 @@ const (
fColorMapFollows = 1 << 7
// Image fields.
- ifInterlace = 1 << 6
+ ifLocalColorTable = 1 << 7
+ ifInterlace = 1 << 6
+ ifPixelSizeMask = 7
// Graphic control flags.
gcTransparentColorSet = 1 << 0
@@ -190,7 +192,9 @@ Loop:
}
// Undo the interlacing if necessary.
- d.uninterlace(m)
+ if d.imageFields&ifInterlace != 0 {
+ uninterlace(m)
+ }
d.image = append(d.image, m)
d.delay = append(d.delay, d.delayTime)
@@ -236,6 +240,9 @@ func (d *decoder) readColorMap() (image.PalettedColorModel, os.Error) {
return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize)
}
numColors := 1 << d.pixelSize
+ if d.imageFields&ifLocalColorTable != 0 {
+ numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1)
+ }
numValues := 3 * numColors
_, err := io.ReadFull(d.r, d.tmp[0:numValues])
if err != nil {
@@ -322,15 +329,15 @@ func (d *decoder) newImageFromDescriptor() (*image.Paletted, os.Error) {
if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil {
return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
}
- // TODO: This code (throughout) ignores the top and left values,
- // and assumes (in interlacing, for example) that the images'
- // widths and heights are all the same.
- _ = int(d.tmp[0]) + int(d.tmp[1])<<8 // TODO: honor left value
- _ = int(d.tmp[2]) + int(d.tmp[3])<<8 // TODO: honor top value
+ left := int(d.tmp[0]) + int(d.tmp[1])<<8
+ top := int(d.tmp[2]) + int(d.tmp[3])<<8
width := int(d.tmp[4]) + int(d.tmp[5])<<8
height := int(d.tmp[6]) + int(d.tmp[7])<<8
d.imageFields = d.tmp[8]
- return image.NewPaletted(width, height, nil), nil
+ m := image.NewPaletted(width, height, nil)
+ // Overwrite the rectangle to take account of left and top.
+ m.Rect = image.Rect(left, top, left+width, top+height)
+ return m, nil
}
func (d *decoder) readBlock() (int, os.Error) {
@@ -354,13 +361,11 @@ var interlacing = []interlaceScan{
{2, 1}, // Group 4 : Every 2nd. row, starting with row 1.
}
-func (d *decoder) uninterlace(m *image.Paletted) {
- if d.imageFields&ifInterlace == 0 {
- return
- }
+// uninterlace rearranges the pixels in m to account for interlaced input.
+func uninterlace(m *image.Paletted) {
var nPix []uint8
- dx := d.width
- dy := d.height
+ dx := m.Bounds().Dx()
+ dy := m.Bounds().Dy()
nPix = make([]uint8, dx*dy)
offset := 0 // steps through the input by sequential scan lines.
for _, pass := range interlacing {