155 lines
3.2 KiB
Go
155 lines
3.2 KiB
Go
// 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)
|
|
}
|
|
}
|
|
}
|