aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNigel Tao <nigeltao@golang.org>2011-07-08 09:54:21 +1000
committerNigel Tao <nigeltao@golang.org>2011-07-08 09:54:21 +1000
commitb39afde805f632bfbe5c4be7a68d01db03de2ce8 (patch)
treeeeb8b5ec1748d7650c0b166c1857e0c443224468
parentd1d466f6207ff0c90e3ae079578399e86328c631 (diff)
downloadgo-b39afde805f632bfbe5c4be7a68d01db03de2ce8.tar.gz
go-b39afde805f632bfbe5c4be7a68d01db03de2ce8.zip
image/draw: add draw tests where the destination image doesn't start
at (0, 0). Also refactor the test to use the SubImage method rather than monkeying with an image's Pix and Rect fields. R=r CC=golang-dev https://golang.org/cl/4678045
-rw-r--r--src/pkg/image/draw/draw_test.go112
1 files changed, 64 insertions, 48 deletions
diff --git a/src/pkg/image/draw/draw_test.go b/src/pkg/image/draw/draw_test.go
index edbf7b27ab..55435cc271 100644
--- a/src/pkg/image/draw/draw_test.go
+++ b/src/pkg/image/draw/draw_test.go
@@ -154,22 +154,32 @@ var drawTests = []drawTest{
{"genericSrc", fillBlue(255), vgradAlpha(192), Src, image.RGBAColor{0, 0, 102, 102}},
}
-func makeGolden(dst, src, mask image.Image, op Op) image.Image {
+func makeGolden(dst image.Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) image.Image {
// Since golden is a newly allocated image, we don't have to check if the
// input source and mask images and the output golden image overlap.
b := dst.Bounds()
- sx0 := src.Bounds().Min.X - b.Min.X
- sy0 := src.Bounds().Min.Y - b.Min.Y
- var mx0, my0 int
+ sb := src.Bounds()
+ mb := image.Rect(-1e9, -1e9, 1e9, 1e9)
if mask != nil {
- mx0 = mask.Bounds().Min.X - b.Min.X
- my0 = mask.Bounds().Min.Y - b.Min.Y
+ mb = mask.Bounds()
}
golden := image.NewRGBA(b.Max.X, b.Max.Y)
- for y := b.Min.Y; y < b.Max.Y; y++ {
- my, sy := my0+y, sy0+y
- for x := b.Min.X; x < b.Max.X; x++ {
- mx, sx := mx0+x, sx0+x
+ for y := r.Min.Y; y < r.Max.Y; y++ {
+ sy := y + sp.Y - r.Min.Y
+ my := y + mp.Y - r.Min.Y
+ for x := r.Min.X; x < r.Max.X; x++ {
+ if !(image.Point{x, y}.In(b)) {
+ continue
+ }
+ sx := x + sp.X - r.Min.X
+ if !(image.Point{sx, sy}.In(sb)) {
+ continue
+ }
+ mx := x + mp.X - r.Min.X
+ if !(image.Point{mx, my}.In(mb)) {
+ continue
+ }
+
const M = 1<<16 - 1
var dr, dg, db, da uint32
if op == Over {
@@ -189,35 +199,49 @@ func makeGolden(dst, src, mask image.Image, op Op) image.Image {
})
}
}
- golden.Rect = b
- return golden
+ return golden.SubImage(b)
}
func TestDraw(t *testing.T) {
-loop:
- for _, test := range drawTests {
- dst := hgradRed(255)
- // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation.
- golden := makeGolden(dst, test.src, test.mask, test.op)
- b := dst.Bounds()
- if !b.Eq(golden.Bounds()) {
- t.Errorf("draw %s: bounds %v versus %v", test.desc, dst.Bounds(), golden.Bounds())
- continue
- }
- // Draw the same combination onto the actual dst using the optimized DrawMask implementation.
- DrawMask(dst, b, test.src, image.ZP, test.mask, image.ZP, test.op)
- // Check that the resultant pixel at (8, 8) matches what we expect
- // (the expected value can be verified by hand).
- if !eq(dst.At(8, 8), test.expected) {
- t.Errorf("draw %s: at (8, 8) %v versus %v", test.desc, dst.At(8, 8), test.expected)
- continue
- }
- // Check that the resultant dst image matches the golden output.
- for y := b.Min.Y; y < b.Max.Y; y++ {
- for x := b.Min.X; x < b.Max.X; x++ {
- if !eq(dst.At(x, y), golden.At(x, y)) {
- t.Errorf("draw %s: at (%d, %d), %v versus golden %v", test.desc, x, y, dst.At(x, y), golden.At(x, y))
- continue loop
+ rr := []image.Rectangle{
+ image.Rect(0, 0, 0, 0),
+ image.Rect(0, 0, 16, 16),
+ image.Rect(3, 5, 12, 10),
+ image.Rect(0, 0, 9, 9),
+ image.Rect(8, 8, 16, 16),
+ image.Rect(8, 0, 9, 16),
+ image.Rect(0, 8, 16, 9),
+ image.Rect(8, 8, 9, 9),
+ image.Rect(8, 8, 8, 8),
+ }
+ for _, r := range rr {
+ loop:
+ for _, test := range drawTests {
+ dst := hgradRed(255).(*image.RGBA).SubImage(r).(Image)
+ // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation.
+ golden := makeGolden(dst, image.Rect(0, 0, 16, 16), test.src, image.ZP, test.mask, image.ZP, test.op)
+ b := dst.Bounds()
+ if !b.Eq(golden.Bounds()) {
+ t.Errorf("draw %v %s: bounds %v versus %v", r, test.desc, dst.Bounds(), golden.Bounds())
+ continue
+ }
+ // Draw the same combination onto the actual dst using the optimized DrawMask implementation.
+ DrawMask(dst, image.Rect(0, 0, 16, 16), test.src, image.ZP, test.mask, image.ZP, test.op)
+ if image.Pt(8, 8).In(r) {
+ // Check that the resultant pixel at (8, 8) matches what we expect
+ // (the expected value can be verified by hand).
+ if !eq(dst.At(8, 8), test.expected) {
+ t.Errorf("draw %v %s: at (8, 8) %v versus %v", r, test.desc, dst.At(8, 8), test.expected)
+ continue
+ }
+ }
+ // Check that the resultant dst image matches the golden output.
+ for y := b.Min.Y; y < b.Max.Y; y++ {
+ for x := b.Min.X; x < b.Max.X; x++ {
+ if !eq(dst.At(x, y), golden.At(x, y)) {
+ t.Errorf("draw %v %s: at (%d, %d), %v versus golden %v", r, test.desc, x, y, dst.At(x, y), golden.At(x, y))
+ continue loop
+ }
}
}
}
@@ -230,19 +254,11 @@ func TestDrawOverlap(t *testing.T) {
loop:
for xoff := -2; xoff <= 2; xoff++ {
m := gradYellow(127).(*image.RGBA)
- dst := &image.RGBA{
- Pix: m.Pix,
- Stride: m.Stride,
- Rect: image.Rect(5, 5, 10, 10),
- }
- src := &image.RGBA{
- Pix: m.Pix,
- Stride: m.Stride,
- Rect: image.Rect(5+xoff, 5+yoff, 10+xoff, 10+yoff),
- }
- // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation.
- golden := makeGolden(dst, src, nil, op)
+ dst := m.SubImage(image.Rect(5, 5, 10, 10)).(*image.RGBA)
+ src := m.SubImage(image.Rect(5+xoff, 5+yoff, 10+xoff, 10+yoff)).(*image.RGBA)
b := dst.Bounds()
+ // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation.
+ golden := makeGolden(dst, b, src, src.Bounds().Min, nil, image.ZP, op)
if !b.Eq(golden.Bounds()) {
t.Errorf("drawOverlap xoff=%d,yoff=%d: bounds %v versus %v", xoff, yoff, dst.Bounds(), golden.Bounds())
continue