]> Cypherpunks repositories - gostls13.git/commitdiff
image/gif: allow encoding a single-frame image whose top-left corner
authorNigel Tao <nigeltao@golang.org>
Tue, 5 May 2015 07:39:09 +0000 (17:39 +1000)
committerNigel Tao <nigeltao@golang.org>
Wed, 6 May 2015 01:00:58 +0000 (01:00 +0000)
isn't (0, 0).

Also fix a s/b.Min.X/b.Max.X/ typo in bounds checking.

Fixes #10676

Change-Id: Ie5ff7ec20ca30367a8e65d32061959a2d8e089e9
Reviewed-on: https://go-review.googlesource.com/9712
Reviewed-by: Rob Pike <r@golang.org>
src/image/gif/writer.go
src/image/gif/writer_test.go

index e14d0346028d00c882dab01690347373609fc951..dd317901d483f7029f6d07de6ac77acb1854aa1f 100644 (file)
@@ -190,7 +190,7 @@ func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte)
        }
 
        b := pm.Bounds()
-       if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 || b.Min.X < 0 || b.Min.X >= 1<<16 || b.Min.Y < 0 || b.Min.Y >= 1<<16 {
+       if b.Min.X < 0 || b.Max.X >= 1<<16 || b.Min.Y < 0 || b.Max.Y >= 1<<16 {
                e.err = errors.New("gif: image block is too large to encode")
                return
        }
@@ -365,6 +365,15 @@ func Encode(w io.Writer, m image.Image, o *Options) error {
                opts.Drawer.Draw(pm, b, m, image.ZP)
        }
 
+       // When calling Encode instead of EncodeAll, the single-frame image is
+       // translated such that its top-left corner is (0, 0), so that the single
+       // frame completely fills the overall GIF's bounds.
+       if pm.Rect.Min != (image.Point{}) {
+               dup := *pm
+               dup.Rect = dup.Rect.Sub(dup.Rect.Min)
+               pm = &dup
+       }
+
        return EncodeAll(w, &GIF{
                Image: []*image.Paletted{pm},
                Delay: []int{0},
index d33976e415a502517be7b0f3dbd94a59d7d92802..db61a5c3c2ecc4c9fb742eca6165efc3dcd158eb 100644 (file)
@@ -297,7 +297,7 @@ func TestEncodeZeroGIF(t *testing.T) {
        }
 }
 
-func TestEncodeFrameOutOfBounds(t *testing.T) {
+func TestEncodeAllFramesOutOfBounds(t *testing.T) {
        images := []*image.Paletted{
                image.NewPaletted(image.Rect(0, 0, 5, 5), palette.Plan9),
                image.NewPaletted(image.Rect(2, 2, 8, 8), palette.Plan9),
@@ -326,6 +326,32 @@ func TestEncodeFrameOutOfBounds(t *testing.T) {
        }
 }
 
+func TestEncodeNonZeroMinPoint(t *testing.T) {
+       points := []image.Point{
+               image.Point{-8, -9},
+               image.Point{-4, -4},
+               image.Point{-3, +3},
+               image.Point{+0, +0},
+               image.Point{+2, +2},
+       }
+       for _, p := range points {
+               src := image.NewPaletted(image.Rectangle{Min: p, Max: p.Add(image.Point{6, 6})}, palette.Plan9)
+               var buf bytes.Buffer
+               if err := Encode(&buf, src, nil); err != nil {
+                       t.Errorf("p=%v: Encode: %v", p, err)
+                       continue
+               }
+               m, err := Decode(&buf)
+               if err != nil {
+                       t.Errorf("p=%v: Decode: %v", p, err)
+                       continue
+               }
+               if got, want := m.Bounds(), image.Rect(0, 0, 6, 6); got != want {
+                       t.Errorf("p=%v: got %v, want %v", p, got, want)
+               }
+       }
+}
+
 func TestEncodeImplicitConfigSize(t *testing.T) {
        // For backwards compatibility for Go 1.4 and earlier code, the Config
        // field is optional, and if zero, the width and height is implied by the