]> Cypherpunks repositories - gostls13.git/commitdiff
gif: fix local color map and coordinates
authorRob Pike <r@golang.org>
Tue, 19 Jul 2011 01:47:15 +0000 (11:47 +1000)
committerRob Pike <r@golang.org>
Tue, 19 Jul 2011 01:47:15 +0000 (11:47 +1000)
R=nigeltao
CC=golang-dev
https://golang.org/cl/4759051

src/pkg/image/gif/reader.go

index 98ac01cca2c2cf125195ea55c268577ea7b5243b..e39b79746049ce5251ed5c970764b171b5ed547e 100644 (file)
@@ -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 {