Include kernel boundary check

Filter kernels should yield Zero if they are evaluted outside their
intended size. Though filterModel.Interpolate doesn't do this by design,
it's better to include it anyways.
This commit is contained in:
jst 2012-12-10 18:56:53 +01:00
parent 3e06045c3f
commit dd1c157427
2 changed files with 28 additions and 13 deletions

View File

@ -29,6 +29,7 @@ func clampToUint16(x float32) (y uint16) {
if x < 0 {
y = 0
} else if x > float32(0xfffe) {
// "else if x > float32(0xffff)" will cause overflows!
y = 0xffff
}
return
@ -150,8 +151,14 @@ func NearestNeighbor(img image.Image, factor [2]float32) Filter {
// Bilinear interpolation
func Bilinear(img image.Image, factor [2]float32) Filter {
return createFilter(img, factor, 2, func(x float32) float32 {
return 1 - float32(math.Abs(float64(x)))
return createFilter(img, factor, 2, func(x float32) (y float32) {
absX := float32(math.Abs(float64(x)))
if absX <= 1 {
y = 1 - absX
} else {
y = 0
}
return
})
}
@ -161,8 +168,10 @@ func Bicubic(img image.Image, factor [2]float32) Filter {
absX := float32(math.Abs(float64(x)))
if absX <= 1 {
y = absX*absX*(1.5*absX-2.5) + 1
} else {
} else if absX <= 2 {
y = absX*(absX*(2.5-0.5*absX)-4) + 2
} else {
y = 0
}
return
})
@ -174,16 +183,23 @@ func MitchellNetravali(img image.Image, factor [2]float32) Filter {
absX := float32(math.Abs(float64(x)))
if absX <= 1 {
y = absX*absX*(7*absX-12) + 16.0/3
} else {
} else if absX <= 2 {
y = -(absX - 2) * (absX - 2) / 3 * (7*absX - 8)
} else {
y = 0
}
return
})
}
func lanczosKernel(a uint) func(float32) float32 {
return func(x float32) float32 {
return float32(Sinc(float64(x))) * float32(Sinc(float64(x/float32(a))))
return func(x float32) (y float32) {
if x > -float32(a) && x < float32(a) {
y = float32(Sinc(float64(x))) * float32(Sinc(float64(x/float32(a))))
} else {
y = 0
}
return
}
}

View File

@ -21,7 +21,7 @@ THIS SOFTWARE.
// utilized in the computations.
//
// Example:
// imgResized := resize.Resize(1000, 0, imgOld, Lanczos3)
// imgResized := resize.Resize(1000, 0, imgOld, resize.MitchellNetravali)
package resize
import (
@ -77,8 +77,8 @@ func Resize(width, height uint, img image.Image, interp InterpolationFunction) i
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; x < b.Max.X; x++ {
u, v = t.Eval(float32(x), float32(y))
//resizedImg.SetRGBA64(x, y, filter.Interpolate(u, v))
color = filter.Interpolate(u, v)
i := resizedImg.PixOffset(x, y)
resizedImg.Pix[i+0] = uint8(color.R >> 8)
resizedImg.Pix[i+1] = uint8(color.R)
@ -124,12 +124,11 @@ func calcFactors(width, height uint, oldWidth, oldHeight float32) (scaleX, scale
// Set filter scaling factor to avoid moire patterns.
// This is only useful in case of downscaling (factor>1).
func clampFactor(factor float32) (r float32) {
r = factor
if r < 1 {
r = 1
func clampFactor(factor float32) float32 {
if factor < 1 {
factor = 1
}
return
return factor
}
// Set number of parallel jobs