From 5f7b0bc36693c3790e4370c2892e10365a622aff Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Tue, 17 May 2011 15:47:14 -0700 Subject: [PATCH] image/jpeg: fix bounds calculation for grayscale JPEG images. Also add grayscale test cases for image/decode_test. R=r CC=golang-dev https://golang.org/cl/4526063 --- src/pkg/image/decode_test.go | 46 +++++++++++++-------- src/pkg/image/jpeg/reader.go | 1 + src/pkg/image/testdata/video-005.gray.jpeg | Bin 0 -> 5618 bytes src/pkg/image/testdata/video-005.gray.png | Bin 0 -> 14974 bytes 4 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 src/pkg/image/testdata/video-005.gray.jpeg create mode 100644 src/pkg/image/testdata/video-005.gray.png diff --git a/src/pkg/image/decode_test.go b/src/pkg/image/decode_test.go index c957c8209e..540d5eda5c 100644 --- a/src/pkg/image/decode_test.go +++ b/src/pkg/image/decode_test.go @@ -17,24 +17,27 @@ import ( _ "image/tiff" ) -const goldenFile = "testdata/video-001.png" - type imageTest struct { - filename string - tolerance int + goldenFilename string + filename string + tolerance int } var imageTests = []imageTest{ - {"testdata/video-001.bmp", 0}, + {"testdata/video-001.png", "testdata/video-001.bmp", 0}, // GIF images are restricted to a 256-color palette and the conversion // to GIF loses significant image quality. - {"testdata/video-001.gif", 64 << 8}, - {"testdata/video-001.interlaced.gif", 64 << 8}, - {"testdata/video-001.5bpp.gif", 128 << 8}, + {"testdata/video-001.png", "testdata/video-001.gif", 64 << 8}, + {"testdata/video-001.png", "testdata/video-001.interlaced.gif", 64 << 8}, + {"testdata/video-001.png", "testdata/video-001.5bpp.gif", 128 << 8}, // JPEG is a lossy format and hence needs a non-zero tolerance. - {"testdata/video-001.jpeg", 8 << 8}, - {"testdata/video-001.png", 0}, - {"testdata/video-001.tiff", 0}, + {"testdata/video-001.png", "testdata/video-001.jpeg", 8 << 8}, + {"testdata/video-001.png", "testdata/video-001.png", 0}, + {"testdata/video-001.png", "testdata/video-001.tiff", 0}, + + // Test grayscale images. + {"testdata/video-005.gray.png", "testdata/video-005.gray.jpeg", 8 << 8}, + {"testdata/video-005.gray.png", "testdata/video-005.gray.png", 0}, } func decode(filename string) (image.Image, string, os.Error) { @@ -74,26 +77,33 @@ func withinTolerance(c0, c1 image.Color, tolerance int) bool { } func TestDecode(t *testing.T) { - golden, _, err := decode(goldenFile) - if err != nil { - t.Errorf("%s: %v", goldenFile, err) - } + golden := make(map[string]image.Image) loop: for _, it := range imageTests { + g := golden[it.goldenFilename] + if g == nil { + var err os.Error + g, _, err = decode(it.goldenFilename) + if err != nil { + t.Errorf("%s: %v", it.goldenFilename, err) + continue loop + } + golden[it.goldenFilename] = g + } m, imageFormat, err := decode(it.filename) if err != nil { t.Errorf("%s: %v", it.filename, err) continue loop } - b := golden.Bounds() + b := g.Bounds() if !b.Eq(m.Bounds()) { t.Errorf("%s: want bounds %v got %v", it.filename, b, m.Bounds()) continue loop } for y := b.Min.Y; y < b.Max.Y; y++ { for x := b.Min.X; x < b.Max.X; x++ { - if !withinTolerance(golden.At(x, y), m.At(x, y), it.tolerance) { - t.Errorf("%s: at (%d, %d), want %v got %v", it.filename, x, y, golden.At(x, y), m.At(x, y)) + if !withinTolerance(g.At(x, y), m.At(x, y), it.tolerance) { + t.Errorf("%s: at (%d, %d), want %v got %v", it.filename, x, y, g.At(x, y), m.At(x, y)) continue loop } } diff --git a/src/pkg/image/jpeg/reader.go b/src/pkg/image/jpeg/reader.go index f3a473b351..ef8383a35e 100644 --- a/src/pkg/image/jpeg/reader.go +++ b/src/pkg/image/jpeg/reader.go @@ -200,6 +200,7 @@ func (d *decoder) processDQT(n int) os.Error { func (d *decoder) makeImg(h0, v0, mxx, myy int) { if d.nComp == nGrayComponent { d.img1 = image.NewGray(8*mxx, 8*myy) + d.img1.Rect = image.Rect(0, 0, d.width, d.height) return } var subsampleRatio ycbcr.SubsampleRatio diff --git a/src/pkg/image/testdata/video-005.gray.jpeg b/src/pkg/image/testdata/video-005.gray.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..f9d6e5cdb419815e32e2f62de82de1e9973ac08a GIT binary patch literal 5618 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 M!V%g-QTb#4*^fDFjQ{`u literal 0 HcmV?d00001 diff --git a/src/pkg/image/testdata/video-005.gray.png b/src/pkg/image/testdata/video-005.gray.png new file mode 100644 index 0000000000000000000000000000000000000000..0b0ee753845970bd00a133d8016f30bdd36b9cde GIT binary patch literal 14974 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 literal 0 HcmV?d00001 -- 2.50.0