Commit c52aca1c authored by Jed Denlea's avatar Jed Denlea Committed by Nigel Tao

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 <emm.odeke@gmail.com>
Run-TryBot: Nigel Tao <nigeltao@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarNigel Tao <nigeltao@golang.org>
parent be9d7f6d
...@@ -274,7 +274,7 @@ func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte) ...@@ -274,7 +274,7 @@ func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte)
lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth) lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth)
if dx := b.Dx(); dx == pm.Stride { 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 { if e.err != nil {
lzww.Close() lzww.Close()
return return
......
...@@ -471,6 +471,34 @@ func TestEncodeBadPalettes(t *testing.T) { ...@@ -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) { func BenchmarkEncode(b *testing.B) {
b.StopTimer() b.StopTimer()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment