From 3fc31c95cc4e3ef794f89389b383fafebeaa582e Mon Sep 17 00:00:00 2001 From: jst Date: Sat, 15 Sep 2012 19:30:32 +0200 Subject: [PATCH] Kernel simplified --- filters.go | 45 +++++++++++++++++++++++---------------------- resize_test.go | 2 +- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/filters.go b/filters.go index 057371a..d74d303 100644 --- a/filters.go +++ b/filters.go @@ -23,12 +23,12 @@ import ( ) // color.RGBA64 as array -type RGBA [4]uint16 +type rgba16 [4]uint16 // build RGBA from an arbitrary color -func toRGBA(c color.Color) RGBA { +func toRGBA(c color.Color) rgba16 { r, g, b, a := c.RGBA() - return RGBA{uint16(r), uint16(g), uint16(b), uint16(a)} + return rgba16{uint16(r), uint16(g), uint16(b), uint16(a)} } func clampToUint16(x float32) (y uint16) { @@ -41,15 +41,17 @@ func clampToUint16(x float32) (y uint16) { return } -func convolution1d(x float32, kernel func(float32, int) float32, p []RGBA) (c RGBA) { +func convolution1d(x float32, kernel func(float32) float32, p []rgba16) (c rgba16) { x -= float32(int(x)) + + m := float32(len(p)/2-1) var k float32 var sum float32 = 0 l := [4]float32{0.0, 0.0, 0.0, 0.0} for j := range p { - k = kernel(x, j) + k = kernel(x+m-float32(j)) sum += k for i := range c { l[i] += float32(p[j][i]) * k @@ -61,11 +63,11 @@ func convolution1d(x float32, kernel func(float32, int) float32, p []RGBA) (c RG return } -func filter(x, y float32, img image.Image, n int, kernel func(x float32, j int) float32) color.RGBA64 { +func filter(x, y float32, img image.Image, n int, kernel func(x float32) float32) color.RGBA64 { xf, yf := int(x)-n/2+1, int(y)-n/2+1 - row := make([]RGBA, n) - col := make([]RGBA, n) + row := make([]rgba16, n) + col := make([]rgba16, n) for i := 0; i < n; i++ { for j := 0; j < n; j++ { @@ -82,8 +84,8 @@ func filter(x, y float32, img image.Image, n int, kernel func(x float32, j int) // Approximates a value by returning the value of the nearest point. func NearestNeighbor(x, y float32, img image.Image) color.RGBA64 { n := 2 - kernel := func(x float32, j int) (y float32) { - if x+0.5 >= float32(j) && x+0.5 < float32(j)+1 { + kernel := func(x float32) (y float32) { + if x >= -0.5 && x < 0.5 { y = 1 } else { y = 0 @@ -96,9 +98,8 @@ func NearestNeighbor(x, y float32, img image.Image) color.RGBA64 { // Bicubic interpolation func Bilinear(x, y float32, img image.Image) color.RGBA64 { n := 2 - kernel := func(x float32, j int) float32 { - xa := float32(math.Abs(float64(x - float32(j)))) - return 1 - xa + kernel := func(x float32) float32 { + return 1 - float32(math.Abs(float64(x))) } return filter(x, y, img, n, kernel) } @@ -106,12 +107,12 @@ func Bilinear(x, y float32, img image.Image) color.RGBA64 { // Bicubic interpolation func Bicubic(x, y float32, img image.Image) color.RGBA64 { n := 4 - kernel := func(x float32, j int) (y float32) { - xa := float32(math.Abs(float64(x - float32(j-1)))) - if xa <= 1 { - y = 1.5*xa*xa*xa - 2.5*xa*xa + 1 + kernel := func(x float32) (y float32) { + absX := float32(math.Abs(float64(x))) + if absX <= 1 { + y = absX*absX*(1.5*absX-2.5) + 1 } else { - y = -0.5*xa*xa*xa + 2.5*xa*xa - 4*xa + 2 + y = absX*(absX*(2.5-0.5*absX)-4) + 2 } return } @@ -121,8 +122,8 @@ func Bicubic(x, y float32, img image.Image) color.RGBA64 { // Lanczos interpolation (a=2). func Lanczos2(x, y float32, img image.Image) color.RGBA64 { n := 4 - kernel := func(x float32, j int) float32 { - return float32(Sinc(float64(x-float32(j-1)))) * float32(Sinc(float64((x-float32(j-1))/float32(2)))) + kernel := func(x float32) float32 { + return float32(Sinc(float64(x))) * float32(Sinc(float64((x)/float32(2)))) } return filter(x, y, img, n, kernel) } @@ -130,8 +131,8 @@ func Lanczos2(x, y float32, img image.Image) color.RGBA64 { // Lanczos interpolation (a=3). func Lanczos3(x, y float32, img image.Image) color.RGBA64 { n := 6 - kernel := func(x float32, j int) float32 { - return float32(Sinc(float64(x-float32(j-2)))) * float32(Sinc(float64((x-float32(j-2))/float32(3)))) + kernel := func(x float32) float32 { + return float32(Sinc(float64(x))) * float32(Sinc(float64((x)/float32(3)))) } return filter(x, y, img, n, kernel) } diff --git a/resize_test.go b/resize_test.go index 0b1735a..8b0cf4f 100644 --- a/resize_test.go +++ b/resize_test.go @@ -14,7 +14,7 @@ func init() { func Test_Nearest(t *testing.T) { m := Resize(6, 0, img, NearestNeighbor) - if m.At(2, 2) != m.At(3, 3) { + if m.At(2, 2) == m.At(3, 3) { t.Fail() } }