diff --git a/filters.go b/filters.go index b8cdbd0..6973548 100644 --- a/filters.go +++ b/filters.go @@ -115,16 +115,30 @@ func Bicubic(img image.Image) Filter { }, make([]rgba16, 4), make([]rgba16, 4)} } +func MitchellNetravali(img image.Image) Filter { + return &filterModel{img, 4, func(x float32) (y float32) { + absX := float32(math.Abs(float64(x))) + if absX <= 1 { + y = absX*absX*(7*absX-12) + 16.0/3 + } else { + y = -(absX - 2) * (absX - 2) / 3 * (7*absX - 8) + } + return + }, make([]rgba16, 4), make([]rgba16, 4)} +} + +func lanczosKernel(a uint) func(float32) float32 { + return func(x float32) float32 { + return float32(Sinc(float64(x))) * float32(Sinc(float64(x/float32(a)))) + } +} + // Lanczos interpolation (a=2). func Lanczos2(img image.Image) Filter { - return &filterModel{img, 4, func(x float32) float32 { - return float32(Sinc(float64(x))) * float32(Sinc(float64((x)/float32(2)))) - }, make([]rgba16, 4), make([]rgba16, 4)} + return &filterModel{img, 4, lanczosKernel(2), make([]rgba16, 4), make([]rgba16, 4)} } // Lanczos interpolation (a=3). func Lanczos3(img image.Image) Filter { - return &filterModel{img, 6, func(x float32) float32 { - return float32(Sinc(float64(x))) * float32(Sinc(float64((x)/float32(3)))) - }, make([]rgba16, 6), make([]rgba16, 6)} + return &filterModel{img, 6, lanczosKernel(3), make([]rgba16, 6), make([]rgba16, 6)} } diff --git a/resize_test.go b/resize_test.go index 8b0cf4f..149f07f 100644 --- a/resize_test.go +++ b/resize_test.go @@ -3,12 +3,14 @@ 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) } @@ -43,6 +45,9 @@ func Test_ZeroImg(t *testing.T) { } func Benchmark_BigResize(b *testing.B) { - m := Resize(1000, 1000, img, Lanczos3) + var m image.Image + for i := 0; i < b.N; i++ { + m = Resize(1000, 1000, img, Lanczos3) + } m.At(0, 0) }