b09281bd36
Benchmark each interpolation function for RGBA and YCbCr images. Reduce the image size used when benchmarking to reduce the influence of memory performance on results.
190 lines
4.2 KiB
Go
190 lines
4.2 KiB
Go
package resize
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
"runtime"
|
|
"testing"
|
|
)
|
|
|
|
var img = image.NewGray16(image.Rect(0, 0, 3, 3))
|
|
|
|
func init() {
|
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
|
img.Set(1, 1, color.White)
|
|
}
|
|
|
|
func Test_Param1(t *testing.T) {
|
|
m := Resize(0, 0, img, NearestNeighbor)
|
|
if m.Bounds() != img.Bounds() {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func Test_Param2(t *testing.T) {
|
|
m := Resize(100, 0, img, NearestNeighbor)
|
|
if m.Bounds() != image.Rect(0, 0, 100, 100) {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func Test_ZeroImg(t *testing.T) {
|
|
zeroImg := image.NewGray16(image.Rect(0, 0, 0, 0))
|
|
|
|
m := Resize(0, 0, zeroImg, NearestNeighbor)
|
|
if m.Bounds() != zeroImg.Bounds() {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func Test_CorrectResize(t *testing.T) {
|
|
zeroImg := image.NewGray16(image.Rect(0, 0, 256, 256))
|
|
|
|
m := Resize(60, 0, zeroImg, NearestNeighbor)
|
|
if m.Bounds() != image.Rect(0, 0, 60, 60) {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func Test_SameColor(t *testing.T) {
|
|
img := image.NewRGBA(image.Rect(0, 0, 20, 20))
|
|
for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ {
|
|
for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ {
|
|
img.SetRGBA(x, y, color.RGBA{0x80, 0x80, 0x80, 0xFF})
|
|
}
|
|
}
|
|
out := Resize(10, 10, img, Lanczos3)
|
|
for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ {
|
|
for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ {
|
|
color := img.At(x, y).(color.RGBA)
|
|
if color.R != 0x80 || color.G != 0x80 || color.B != 0x80 || color.A != 0xFF {
|
|
t.Fail()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_Bounds(t *testing.T) {
|
|
img := image.NewRGBA(image.Rect(20, 10, 200, 99))
|
|
out := Resize(80, 80, img, Lanczos2)
|
|
out.At(0, 0)
|
|
}
|
|
|
|
func Test_SameSizeReturnsOriginal(t *testing.T) {
|
|
img := image.NewRGBA(image.Rect(0, 0, 10, 10))
|
|
out := Resize(0, 0, img, Lanczos2)
|
|
|
|
if img != out {
|
|
t.Fail()
|
|
}
|
|
|
|
out = Resize(10, 10, img, Lanczos2)
|
|
|
|
if img != out {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
const (
|
|
// Use a small image size for benchmarks. We don't want memory performance
|
|
// to affect the benchmark results.
|
|
benchMaxX = 250
|
|
benchMaxY = 250
|
|
|
|
// Resize values near the original size require increase the amount of time
|
|
// resize spends converting the image.
|
|
benchWidth = 200
|
|
benchHeight = 200
|
|
)
|
|
|
|
func benchRGBA(b *testing.B, interp InterpolationFunction) {
|
|
m := image.NewRGBA(image.Rect(0, 0, benchMaxX, benchMaxY))
|
|
// Initialize m's pixels to create a non-uniform image.
|
|
for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
|
|
for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
|
|
i := m.PixOffset(x, y)
|
|
m.Pix[i+0] = uint8(y + 4*x)
|
|
m.Pix[i+1] = uint8(y + 4*x)
|
|
m.Pix[i+2] = uint8(y + 4*x)
|
|
m.Pix[i+3] = uint8(4*y + x)
|
|
}
|
|
}
|
|
|
|
var out image.Image
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
out = Resize(benchWidth, benchHeight, m, interp)
|
|
}
|
|
out.At(0, 0)
|
|
}
|
|
|
|
// The names of some interpolation functions are truncated so that the columns
|
|
// of 'go test -bench' line up.
|
|
func Benchmark_Nearest_RGBA(b *testing.B) {
|
|
benchRGBA(b, NearestNeighbor)
|
|
}
|
|
|
|
func Benchmark_Bilinear_RGBA(b *testing.B) {
|
|
benchRGBA(b, Bilinear)
|
|
}
|
|
|
|
func Benchmark_Bicubic_RGBA(b *testing.B) {
|
|
benchRGBA(b, Bicubic)
|
|
}
|
|
|
|
func Benchmark_Mitchell_RGBA(b *testing.B) {
|
|
benchRGBA(b, MitchellNetravali)
|
|
}
|
|
|
|
func Benchmark_Lanczos2_RGBA(b *testing.B) {
|
|
benchRGBA(b, Lanczos2)
|
|
}
|
|
|
|
func Benchmark_Lanczos3_RGBA(b *testing.B) {
|
|
benchRGBA(b, Lanczos3)
|
|
}
|
|
|
|
func benchYCbCr(b *testing.B, interp InterpolationFunction) {
|
|
m := image.NewYCbCr(image.Rect(0, 0, benchMaxX, benchMaxY), image.YCbCrSubsampleRatio422)
|
|
// Initialize m's pixels to create a non-uniform image.
|
|
for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
|
|
for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
|
|
yi := m.YOffset(x, y)
|
|
ci := m.COffset(x, y)
|
|
m.Y[yi] = uint8(16*y + x)
|
|
m.Cb[ci] = uint8(y + 16*x)
|
|
m.Cr[ci] = uint8(y + 16*x)
|
|
}
|
|
}
|
|
var out image.Image
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
out = Resize(benchWidth, benchHeight, m, interp)
|
|
}
|
|
out.At(0, 0)
|
|
}
|
|
|
|
func Benchmark_Nearest_YCC(b *testing.B) {
|
|
benchYCbCr(b, NearestNeighbor)
|
|
}
|
|
|
|
func Benchmark_Bilinear_YCC(b *testing.B) {
|
|
benchYCbCr(b, Bilinear)
|
|
}
|
|
|
|
func Benchmark_Bicubic_YCC(b *testing.B) {
|
|
benchYCbCr(b, Bicubic)
|
|
}
|
|
|
|
func Benchmark_Mitchell_YCC(b *testing.B) {
|
|
benchYCbCr(b, MitchellNetravali)
|
|
}
|
|
|
|
func Benchmark_Lanczos2_YCC(b *testing.B) {
|
|
benchYCbCr(b, Lanczos2)
|
|
}
|
|
|
|
func Benchmark_Lanczos3_YCC(b *testing.B) {
|
|
benchYCbCr(b, Lanczos3)
|
|
}
|