From 4bf24024c98957ba1e4ece8d3d5c5a3499f9cc45 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Thu, 12 Mar 2015 17:50:07 +1100 Subject: [PATCH] draw: add a test for src translation invariance. Change-Id: Iedd4cc4e2b88c5fa9e4fcd547756588e4d87bfff Reviewed-on: https://go-review.googlesource.com/7471 Reviewed-by: Rob Pike --- draw/scale_test.go | 58 +++++++++++++++++++++++++++++++++++++++ testdata/testpattern.png | Bin 0 -> 3195 bytes 2 files changed, 58 insertions(+) create mode 100644 testdata/testpattern.png diff --git a/draw/scale_test.go b/draw/scale_test.go index ef5192e..30a82c6 100644 --- a/draw/scale_test.go +++ b/draw/scale_test.go @@ -131,6 +131,64 @@ func TestScaleClipCommute(t *testing.T) { } } +// translatedImage is an image m translated by t. +type translatedImage struct { + m image.Image + t image.Point +} + +func (t *translatedImage) At(x, y int) color.Color { return t.m.At(x-t.t.X, y-t.t.Y) } +func (t *translatedImage) Bounds() image.Rectangle { return t.m.Bounds().Add(t.t) } +func (t *translatedImage) ColorModel() color.Model { return t.m.ColorModel() } + +// TestSrcTranslationInvariance tests that Scale and Transform are invariant +// under src translations. Specifically, when some source pixels are not in the +// bottom-right quadrant of src coordinate space, we consistently round down, +// not round towards zero. +func TestSrcTranslationInvariance(t *testing.T) { + f, err := os.Open("../testdata/testpattern.png") + if err != nil { + t.Fatalf("Open: %v", err) + } + defer f.Close() + src, _, err := image.Decode(f) + if err != nil { + t.Fatalf("Decode: %v", err) + } + qs := []Interpolator{ + NearestNeighbor, + ApproxBiLinear, + CatmullRom, + } + deltas := []image.Point{ + {+0, +0}, + {+0, +5}, + {+0, -5}, + {+5, +0}, + {-5, +0}, + {+8, +8}, + {+8, -8}, + {-8, +8}, + {-8, -8}, + } + + for _, q := range qs { + want := image.NewRGBA(image.Rect(0, 0, 200, 200)) + q.Scale(want, want.Bounds(), src, src.Bounds(), nil) + for _, delta := range deltas { + tsrc := &translatedImage{src, delta} + + got := image.NewRGBA(image.Rect(0, 0, 200, 200)) + q.Scale(got, got.Bounds(), tsrc, tsrc.Bounds(), nil) + if !bytes.Equal(got.Pix, want.Pix) { + t.Errorf("pix differ for delta=%v, q=%T", delta, q) + } + + // TODO: Transform. + } + } +} + // The fooWrapper types wrap the dst or src image to avoid triggering the // type-specific fast path implementations. type ( diff --git a/testdata/testpattern.png b/testdata/testpattern.png new file mode 100644 index 0000000000000000000000000000000000000000..ec87bb56a242d27b89b952553bb50bbc84d60ac2 GIT binary patch literal 3195 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 Lxn70t)#yI}H2;5! literal 0 HcmV?d00001