From: Jed Denlea Date: Thu, 15 Jun 2017 22:53:09 +0000 (-0700) Subject: image/gif: fix writeImageBlock with SubImages X-Git-Tag: go1.9beta2~63 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c52aca1c761f724c3192ee0ac4f4a19754fc5948;p=gostls13.git image/gif: fix writeImageBlock with SubImages If an image has been cropped horizontally, writeImageBlock detects that its width and Stride differ and acts accordingly. However, if an image has been cropped vertically, trimming from the bottom, the whole original image will be written in place. This results in more data in the LZW stream than necessary, and many decoders including image/gif's itself will fail to load. Fixes #20692 Change-Id: Id332877e31bcf3729c89d8a50c1be0464028d82e Reviewed-on: https://go-review.googlesource.com/45972 Run-TryBot: Emmanuel Odeke Run-TryBot: Nigel Tao TryBot-Result: Gobot Gobot Reviewed-by: Nigel Tao --- diff --git a/src/image/gif/writer.go b/src/image/gif/writer.go index e68f7a4ed5..493c7549eb 100644 --- a/src/image/gif/writer.go +++ b/src/image/gif/writer.go @@ -274,7 +274,7 @@ func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte) lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth) if dx := b.Dx(); dx == pm.Stride { - _, e.err = lzww.Write(pm.Pix) + _, e.err = lzww.Write(pm.Pix[:dx*b.Dy()]) if e.err != nil { lzww.Close() return diff --git a/src/image/gif/writer_test.go b/src/image/gif/writer_test.go index bbedbfc36e..1bba9b8ece 100644 --- a/src/image/gif/writer_test.go +++ b/src/image/gif/writer_test.go @@ -471,6 +471,34 @@ func TestEncodeBadPalettes(t *testing.T) { } } +func TestEncodeCroppedSubImages(t *testing.T) { + // This test means to ensure that Encode honors the Bounds and Strides of + // images correctly when encoding. + whole := image.NewPaletted(image.Rect(0, 0, 100, 100), palette.Plan9) + subImages := []image.Rectangle{ + image.Rect(0, 0, 50, 50), + image.Rect(50, 0, 100, 50), + image.Rect(0, 50, 50, 50), + image.Rect(50, 50, 100, 100), + image.Rect(25, 25, 75, 75), + image.Rect(0, 0, 100, 50), + image.Rect(0, 50, 100, 100), + image.Rect(0, 0, 50, 100), + image.Rect(50, 0, 100, 100), + } + for _, sr := range subImages { + si := whole.SubImage(sr) + buf := bytes.NewBuffer(nil) + if err := Encode(buf, si, nil); err != nil { + t.Errorf("Encode: sr=%v: %v", sr, err) + continue + } + if _, err := Decode(buf); err != nil { + t.Errorf("Decode: sr=%v: %v", sr, err) + } + } +} + func BenchmarkEncode(b *testing.B) { b.StopTimer()