}
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
}
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},
}
}
-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),
}
}
+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