blob: 004dfa7b799621373f4ea5f6848cbfa0696b8f1a [file] [log] [blame]
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package portable
import (
"image"
"image/color"
"testing"
)
type interpTest struct {
desc string
src []uint8
srcWidth int
x, y float32
expect uint8
}
func (p *interpTest) newSrc() *image.RGBA {
b := image.Rect(0, 0, p.srcWidth, len(p.src)/p.srcWidth)
src := image.NewRGBA(b)
i := 0
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; x < b.Max.X; x++ {
src.SetRGBA(x, y, color.RGBA{
R: p.src[i],
G: p.src[i],
B: p.src[i],
A: 0xff,
})
i++
}
}
return src
}
var interpTests = []interpTest{
{
desc: "center of a single white pixel should match that pixel",
src: []uint8{0x00},
srcWidth: 1,
x: 0.5,
y: 0.5,
expect: 0x00,
},
{
desc: "middle of a square is equally weighted",
src: []uint8{
0x00, 0xff,
0xff, 0x00,
},
srcWidth: 2,
x: 1.0,
y: 1.0,
expect: 0x80,
},
{
desc: "center of a pixel is just that pixel",
src: []uint8{
0x00, 0xff,
0xff, 0x00,
},
srcWidth: 2,
x: 1.5,
y: 0.5,
expect: 0xff,
},
{
desc: "asymmetry abounds",
src: []uint8{
0xaa, 0x11, 0x55,
0xff, 0x95, 0xdd,
},
srcWidth: 3,
x: 2.0,
y: 1.0,
expect: 0x76, // (0x11 + 0x55 + 0x95 + 0xdd) / 4
},
}
func TestBilinear(t *testing.T) {
for _, p := range interpTests {
src := p.newSrc()
c0 := bilinearGeneral(src, p.x, p.y)
c0R, c0G, c0B, c0A := c0.RGBA()
r := uint8(c0R >> 8)
g := uint8(c0G >> 8)
b := uint8(c0B >> 8)
a := uint8(c0A >> 8)
if r != g || r != b || a != 0xff {
t.Errorf("expect channels to match, got %v", c0)
continue
}
if r != p.expect {
t.Errorf("%s: got 0x%02x want 0x%02x", p.desc, r, p.expect)
continue
}
// fast path for *image.RGBA
c1 := bilinearRGBA(src, p.x, p.y)
if r != c1.R || g != c1.G || b != c1.B || a != c1.A {
t.Errorf("%s: RGBA fast path mismatch got %v want %v", p.desc, c1, c0)
continue
}
// fast path for *image.Alpha
alpha := image.NewAlpha(src.Bounds())
for y := src.Bounds().Min.Y; y < src.Bounds().Max.Y; y++ {
for x := src.Bounds().Min.X; x < src.Bounds().Max.X; x++ {
r, _, _, _ := src.At(x, y).RGBA()
alpha.Set(x, y, color.Alpha{A: uint8(r >> 8)})
}
}
c2 := bilinearAlpha(alpha, p.x, p.y)
if c2.A != r {
t.Errorf("%s: Alpha fast path mismatch got %v want %v", p.desc, c2, c0)
continue
}
}
}
func TestBilinearSubImage(t *testing.T) {
b0 := image.Rect(0, 0, 4, 4)
src0 := image.NewRGBA(b0)
b1 := image.Rect(1, 1, 3, 3)
src1 := src0.SubImage(b1).(*image.RGBA)
src1.Set(1, 1, color.RGBA{0x11, 0, 0, 0xff})
src1.Set(2, 1, color.RGBA{0x22, 0, 0, 0xff})
src1.Set(1, 2, color.RGBA{0x33, 0, 0, 0xff})
src1.Set(2, 2, color.RGBA{0x44, 0, 0, 0xff})
tests := []struct {
x, y float32
want uint32
}{
{1, 1, 0x11},
{3, 1, 0x22},
{1, 3, 0x33},
{3, 3, 0x44},
{2, 2, 0x2b},
}
for _, p := range tests {
r, _, _, _ := bilinear(src1, p.x, p.y).RGBA()
r >>= 8
if r != p.want {
t.Errorf("(%.0f, %.0f): got 0x%02x want 0x%02x", p.x, p.y, r, p.want)
}
}
}