OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [image/] [draw/] [draw_test.go] - Blame information for rev 749

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2010 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package draw
6
 
7
import (
8
        "image"
9
        "image/color"
10
        "testing"
11
)
12
 
13
func eq(c0, c1 color.Color) bool {
14
        r0, g0, b0, a0 := c0.RGBA()
15
        r1, g1, b1, a1 := c1.RGBA()
16
        return r0 == r1 && g0 == g1 && b0 == b1 && a0 == a1
17
}
18
 
19
func fillBlue(alpha int) image.Image {
20
        return image.NewUniform(color.RGBA{0, 0, uint8(alpha), uint8(alpha)})
21
}
22
 
23
func fillAlpha(alpha int) image.Image {
24
        return image.NewUniform(color.Alpha{uint8(alpha)})
25
}
26
 
27
func vgradGreen(alpha int) image.Image {
28
        m := image.NewRGBA(image.Rect(0, 0, 16, 16))
29
        for y := 0; y < 16; y++ {
30
                for x := 0; x < 16; x++ {
31
                        m.Set(x, y, color.RGBA{0, uint8(y * alpha / 15), 0, uint8(alpha)})
32
                }
33
        }
34
        return m
35
}
36
 
37
func vgradAlpha(alpha int) image.Image {
38
        m := image.NewAlpha(image.Rect(0, 0, 16, 16))
39
        for y := 0; y < 16; y++ {
40
                for x := 0; x < 16; x++ {
41
                        m.Set(x, y, color.Alpha{uint8(y * alpha / 15)})
42
                }
43
        }
44
        return m
45
}
46
 
47
func vgradGreenNRGBA(alpha int) image.Image {
48
        m := image.NewNRGBA(image.Rect(0, 0, 16, 16))
49
        for y := 0; y < 16; y++ {
50
                for x := 0; x < 16; x++ {
51
                        m.Set(x, y, color.RGBA{0, uint8(y * 0x11), 0, uint8(alpha)})
52
                }
53
        }
54
        return m
55
}
56
 
57
func vgradCr() image.Image {
58
        m := &image.YCbCr{
59
                Y:              make([]byte, 16*16),
60
                Cb:             make([]byte, 16*16),
61
                Cr:             make([]byte, 16*16),
62
                YStride:        16,
63
                CStride:        16,
64
                SubsampleRatio: image.YCbCrSubsampleRatio444,
65
                Rect:           image.Rect(0, 0, 16, 16),
66
        }
67
        for y := 0; y < 16; y++ {
68
                for x := 0; x < 16; x++ {
69
                        m.Cr[y*m.CStride+x] = uint8(y * 0x11)
70
                }
71
        }
72
        return m
73
}
74
 
75
func hgradRed(alpha int) Image {
76
        m := image.NewRGBA(image.Rect(0, 0, 16, 16))
77
        for y := 0; y < 16; y++ {
78
                for x := 0; x < 16; x++ {
79
                        m.Set(x, y, color.RGBA{uint8(x * alpha / 15), 0, 0, uint8(alpha)})
80
                }
81
        }
82
        return m
83
}
84
 
85
func gradYellow(alpha int) Image {
86
        m := image.NewRGBA(image.Rect(0, 0, 16, 16))
87
        for y := 0; y < 16; y++ {
88
                for x := 0; x < 16; x++ {
89
                        m.Set(x, y, color.RGBA{uint8(x * alpha / 15), uint8(y * alpha / 15), 0, uint8(alpha)})
90
                }
91
        }
92
        return m
93
}
94
 
95
type drawTest struct {
96
        desc     string
97
        src      image.Image
98
        mask     image.Image
99
        op       Op
100
        expected color.Color
101
}
102
 
103
var drawTests = []drawTest{
104
        // Uniform mask (0% opaque).
105
        {"nop", vgradGreen(255), fillAlpha(0), Over, color.RGBA{136, 0, 0, 255}},
106
        {"clear", vgradGreen(255), fillAlpha(0), Src, color.RGBA{0, 0, 0, 0}},
107
        // Uniform mask (100%, 75%, nil) and uniform source.
108
        // At (x, y) == (8, 8):
109
        // The destination pixel is {136, 0, 0, 255}.
110
        // The source pixel is {0, 0, 90, 90}.
111
        {"fill", fillBlue(90), fillAlpha(255), Over, color.RGBA{88, 0, 90, 255}},
112
        {"fillSrc", fillBlue(90), fillAlpha(255), Src, color.RGBA{0, 0, 90, 90}},
113
        {"fillAlpha", fillBlue(90), fillAlpha(192), Over, color.RGBA{100, 0, 68, 255}},
114
        {"fillAlphaSrc", fillBlue(90), fillAlpha(192), Src, color.RGBA{0, 0, 68, 68}},
115
        {"fillNil", fillBlue(90), nil, Over, color.RGBA{88, 0, 90, 255}},
116
        {"fillNilSrc", fillBlue(90), nil, Src, color.RGBA{0, 0, 90, 90}},
117
        // Uniform mask (100%, 75%, nil) and variable source.
118
        // At (x, y) == (8, 8):
119
        // The destination pixel is {136, 0, 0, 255}.
120
        // The source pixel is {0, 48, 0, 90}.
121
        {"copy", vgradGreen(90), fillAlpha(255), Over, color.RGBA{88, 48, 0, 255}},
122
        {"copySrc", vgradGreen(90), fillAlpha(255), Src, color.RGBA{0, 48, 0, 90}},
123
        {"copyAlpha", vgradGreen(90), fillAlpha(192), Over, color.RGBA{100, 36, 0, 255}},
124
        {"copyAlphaSrc", vgradGreen(90), fillAlpha(192), Src, color.RGBA{0, 36, 0, 68}},
125
        {"copyNil", vgradGreen(90), nil, Over, color.RGBA{88, 48, 0, 255}},
126
        {"copyNilSrc", vgradGreen(90), nil, Src, color.RGBA{0, 48, 0, 90}},
127
        // Uniform mask (100%, 75%, nil) and variable NRGBA source.
128
        // At (x, y) == (8, 8):
129
        // The destination pixel is {136, 0, 0, 255}.
130
        // The source pixel is {0, 136, 0, 90} in NRGBA-space, which is {0, 48, 0, 90} in RGBA-space.
131
        // The result pixel is different than in the "copy*" test cases because of rounding errors.
132
        {"nrgba", vgradGreenNRGBA(90), fillAlpha(255), Over, color.RGBA{88, 46, 0, 255}},
133
        {"nrgbaSrc", vgradGreenNRGBA(90), fillAlpha(255), Src, color.RGBA{0, 46, 0, 90}},
134
        {"nrgbaAlpha", vgradGreenNRGBA(90), fillAlpha(192), Over, color.RGBA{100, 34, 0, 255}},
135
        {"nrgbaAlphaSrc", vgradGreenNRGBA(90), fillAlpha(192), Src, color.RGBA{0, 34, 0, 68}},
136
        {"nrgbaNil", vgradGreenNRGBA(90), nil, Over, color.RGBA{88, 46, 0, 255}},
137
        {"nrgbaNilSrc", vgradGreenNRGBA(90), nil, Src, color.RGBA{0, 46, 0, 90}},
138
        // Uniform mask (100%, 75%, nil) and variable YCbCr source.
139
        // At (x, y) == (8, 8):
140
        // The destination pixel is {136, 0, 0, 255}.
141
        // The source pixel is {0, 0, 136} in YCbCr-space, which is {11, 38, 0, 255} in RGB-space.
142
        {"ycbcr", vgradCr(), fillAlpha(255), Over, color.RGBA{11, 38, 0, 255}},
143
        {"ycbcrSrc", vgradCr(), fillAlpha(255), Src, color.RGBA{11, 38, 0, 255}},
144
        {"ycbcrAlpha", vgradCr(), fillAlpha(192), Over, color.RGBA{42, 28, 0, 255}},
145
        {"ycbcrAlphaSrc", vgradCr(), fillAlpha(192), Src, color.RGBA{8, 28, 0, 192}},
146
        {"ycbcrNil", vgradCr(), nil, Over, color.RGBA{11, 38, 0, 255}},
147
        {"ycbcrNilSrc", vgradCr(), nil, Src, color.RGBA{11, 38, 0, 255}},
148
        // Variable mask and variable source.
149
        // At (x, y) == (8, 8):
150
        // The destination pixel is {136, 0, 0, 255}.
151
        // The source pixel is {0, 0, 255, 255}.
152
        // The mask pixel's alpha is 102, or 40%.
153
        {"generic", fillBlue(255), vgradAlpha(192), Over, color.RGBA{81, 0, 102, 255}},
154
        {"genericSrc", fillBlue(255), vgradAlpha(192), Src, color.RGBA{0, 0, 102, 102}},
155
}
156
 
157
func makeGolden(dst image.Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) image.Image {
158
        // Since golden is a newly allocated image, we don't have to check if the
159
        // input source and mask images and the output golden image overlap.
160
        b := dst.Bounds()
161
        sb := src.Bounds()
162
        mb := image.Rect(-1e9, -1e9, 1e9, 1e9)
163
        if mask != nil {
164
                mb = mask.Bounds()
165
        }
166
        golden := image.NewRGBA(image.Rect(0, 0, b.Max.X, b.Max.Y))
167
        for y := r.Min.Y; y < r.Max.Y; y++ {
168
                sy := y + sp.Y - r.Min.Y
169
                my := y + mp.Y - r.Min.Y
170
                for x := r.Min.X; x < r.Max.X; x++ {
171
                        if !(image.Pt(x, y).In(b)) {
172
                                continue
173
                        }
174
                        sx := x + sp.X - r.Min.X
175
                        if !(image.Pt(sx, sy).In(sb)) {
176
                                continue
177
                        }
178
                        mx := x + mp.X - r.Min.X
179
                        if !(image.Pt(mx, my).In(mb)) {
180
                                continue
181
                        }
182
 
183
                        const M = 1<<16 - 1
184
                        var dr, dg, db, da uint32
185
                        if op == Over {
186
                                dr, dg, db, da = dst.At(x, y).RGBA()
187
                        }
188
                        sr, sg, sb, sa := src.At(sx, sy).RGBA()
189
                        ma := uint32(M)
190
                        if mask != nil {
191
                                _, _, _, ma = mask.At(mx, my).RGBA()
192
                        }
193
                        a := M - (sa * ma / M)
194
                        golden.Set(x, y, color.RGBA64{
195
                                uint16((dr*a + sr*ma) / M),
196
                                uint16((dg*a + sg*ma) / M),
197
                                uint16((db*a + sb*ma) / M),
198
                                uint16((da*a + sa*ma) / M),
199
                        })
200
                }
201
        }
202
        return golden.SubImage(b)
203
}
204
 
205
func TestDraw(t *testing.T) {
206
        rr := []image.Rectangle{
207
                image.Rect(0, 0, 0, 0),
208
                image.Rect(0, 0, 16, 16),
209
                image.Rect(3, 5, 12, 10),
210
                image.Rect(0, 0, 9, 9),
211
                image.Rect(8, 8, 16, 16),
212
                image.Rect(8, 0, 9, 16),
213
                image.Rect(0, 8, 16, 9),
214
                image.Rect(8, 8, 9, 9),
215
                image.Rect(8, 8, 8, 8),
216
        }
217
        for _, r := range rr {
218
        loop:
219
                for _, test := range drawTests {
220
                        dst := hgradRed(255).(*image.RGBA).SubImage(r).(Image)
221
                        // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation.
222
                        golden := makeGolden(dst, image.Rect(0, 0, 16, 16), test.src, image.ZP, test.mask, image.ZP, test.op)
223
                        b := dst.Bounds()
224
                        if !b.Eq(golden.Bounds()) {
225
                                t.Errorf("draw %v %s: bounds %v versus %v", r, test.desc, dst.Bounds(), golden.Bounds())
226
                                continue
227
                        }
228
                        // Draw the same combination onto the actual dst using the optimized DrawMask implementation.
229
                        DrawMask(dst, image.Rect(0, 0, 16, 16), test.src, image.ZP, test.mask, image.ZP, test.op)
230
                        if image.Pt(8, 8).In(r) {
231
                                // Check that the resultant pixel at (8, 8) matches what we expect
232
                                // (the expected value can be verified by hand).
233
                                if !eq(dst.At(8, 8), test.expected) {
234
                                        t.Errorf("draw %v %s: at (8, 8) %v versus %v", r, test.desc, dst.At(8, 8), test.expected)
235
                                        continue
236
                                }
237
                        }
238
                        // Check that the resultant dst image matches the golden output.
239
                        for y := b.Min.Y; y < b.Max.Y; y++ {
240
                                for x := b.Min.X; x < b.Max.X; x++ {
241
                                        if !eq(dst.At(x, y), golden.At(x, y)) {
242
                                                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))
243
                                                continue loop
244
                                        }
245
                                }
246
                        }
247
                }
248
        }
249
}
250
 
251
func TestDrawOverlap(t *testing.T) {
252
        for _, op := range []Op{Over, Src} {
253
                for yoff := -2; yoff <= 2; yoff++ {
254
                loop:
255
                        for xoff := -2; xoff <= 2; xoff++ {
256
                                m := gradYellow(127).(*image.RGBA)
257
                                dst := m.SubImage(image.Rect(5, 5, 10, 10)).(*image.RGBA)
258
                                src := m.SubImage(image.Rect(5+xoff, 5+yoff, 10+xoff, 10+yoff)).(*image.RGBA)
259
                                b := dst.Bounds()
260
                                // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation.
261
                                golden := makeGolden(dst, b, src, src.Bounds().Min, nil, image.ZP, op)
262
                                if !b.Eq(golden.Bounds()) {
263
                                        t.Errorf("drawOverlap xoff=%d,yoff=%d: bounds %v versus %v", xoff, yoff, dst.Bounds(), golden.Bounds())
264
                                        continue
265
                                }
266
                                // Draw the same combination onto the actual dst using the optimized DrawMask implementation.
267
                                DrawMask(dst, b, src, src.Bounds().Min, nil, image.ZP, op)
268
                                // Check that the resultant dst image matches the golden output.
269
                                for y := b.Min.Y; y < b.Max.Y; y++ {
270
                                        for x := b.Min.X; x < b.Max.X; x++ {
271
                                                if !eq(dst.At(x, y), golden.At(x, y)) {
272
                                                        t.Errorf("drawOverlap xoff=%d,yoff=%d: at (%d, %d), %v versus golden %v", xoff, yoff, x, y, dst.At(x, y), golden.At(x, y))
273
                                                        continue loop
274
                                                }
275
                                        }
276
                                }
277
                        }
278
                }
279
        }
280
}
281
 
282
// TestNonZeroSrcPt checks drawing with a non-zero src point parameter.
283
func TestNonZeroSrcPt(t *testing.T) {
284
        a := image.NewRGBA(image.Rect(0, 0, 1, 1))
285
        b := image.NewRGBA(image.Rect(0, 0, 2, 2))
286
        b.Set(0, 0, color.RGBA{0, 0, 0, 5})
287
        b.Set(1, 0, color.RGBA{0, 0, 5, 5})
288
        b.Set(0, 1, color.RGBA{0, 5, 0, 5})
289
        b.Set(1, 1, color.RGBA{5, 0, 0, 5})
290
        Draw(a, image.Rect(0, 0, 1, 1), b, image.Pt(1, 1), Over)
291
        if !eq(color.RGBA{5, 0, 0, 5}, a.At(0, 0)) {
292
                t.Errorf("non-zero src pt: want %v got %v", color.RGBA{5, 0, 0, 5}, a.At(0, 0))
293
        }
294
}
295
 
296
func TestFill(t *testing.T) {
297
        rr := []image.Rectangle{
298
                image.Rect(0, 0, 0, 0),
299
                image.Rect(0, 0, 40, 30),
300
                image.Rect(10, 0, 40, 30),
301
                image.Rect(0, 20, 40, 30),
302
                image.Rect(10, 20, 40, 30),
303
                image.Rect(10, 20, 15, 25),
304
                image.Rect(10, 0, 35, 30),
305
                image.Rect(0, 15, 40, 16),
306
                image.Rect(24, 24, 25, 25),
307
                image.Rect(23, 23, 26, 26),
308
                image.Rect(22, 22, 27, 27),
309
                image.Rect(21, 21, 28, 28),
310
                image.Rect(20, 20, 29, 29),
311
        }
312
        for _, r := range rr {
313
                m := image.NewRGBA(image.Rect(0, 0, 40, 30)).SubImage(r).(*image.RGBA)
314
                b := m.Bounds()
315
                c := color.RGBA{11, 0, 0, 255}
316
                src := &image.Uniform{C: c}
317
                check := func(desc string) {
318
                        for y := b.Min.Y; y < b.Max.Y; y++ {
319
                                for x := b.Min.X; x < b.Max.X; x++ {
320
                                        if !eq(c, m.At(x, y)) {
321
                                                t.Errorf("%s fill: at (%d, %d), sub-image bounds=%v: want %v got %v", desc, x, y, r, c, m.At(x, y))
322
                                                return
323
                                        }
324
                                }
325
                        }
326
                }
327
                // Draw 1 pixel at a time.
328
                for y := b.Min.Y; y < b.Max.Y; y++ {
329
                        for x := b.Min.X; x < b.Max.X; x++ {
330
                                DrawMask(m, image.Rect(x, y, x+1, y+1), src, image.ZP, nil, image.ZP, Src)
331
                        }
332
                }
333
                check("pixel")
334
                // Draw 1 row at a time.
335
                c = color.RGBA{0, 22, 0, 255}
336
                src = &image.Uniform{C: c}
337
                for y := b.Min.Y; y < b.Max.Y; y++ {
338
                        DrawMask(m, image.Rect(b.Min.X, y, b.Max.X, y+1), src, image.ZP, nil, image.ZP, Src)
339
                }
340
                check("row")
341
                // Draw 1 column at a time.
342
                c = color.RGBA{0, 0, 33, 255}
343
                src = &image.Uniform{C: c}
344
                for x := b.Min.X; x < b.Max.X; x++ {
345
                        DrawMask(m, image.Rect(x, b.Min.Y, x+1, b.Max.Y), src, image.ZP, nil, image.ZP, Src)
346
                }
347
                check("column")
348
                // Draw the whole image at once.
349
                c = color.RGBA{44, 55, 66, 77}
350
                src = &image.Uniform{C: c}
351
                DrawMask(m, b, src, image.ZP, nil, image.ZP, Src)
352
                check("whole")
353
        }
354
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.