]> Cypherpunks repositories - gostls13.git/commitdiff
image/gif: fix writeImageBlock with SubImages
authorJed Denlea <jed@fastly.com>
Thu, 15 Jun 2017 22:53:09 +0000 (15:53 -0700)
committerNigel Tao <nigeltao@golang.org>
Fri, 16 Jun 2017 05:45:48 +0000 (05:45 +0000)
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 <emm.odeke@gmail.com>
Run-TryBot: Nigel Tao <nigeltao@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
src/image/gif/writer.go
src/image/gif/writer_test.go

index e68f7a4ed5c8a541c72e7caf12740f5edbaa6723..493c7549eb2ab8c93ff86b541f5a9e8312b9ecd3 100644 (file)
@@ -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
index bbedbfc36e6a3c66c6266cc01184788f7917cf5c..1bba9b8ece58290bd2ad76b72a47f2f252b8180d 100644 (file)
@@ -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()