Remove LUT based filters.

Caching kernel weights makes using the LUT based approach obsolete. Now they seem to be even slower than their counterparts.
This commit is contained in:
jst 2014-01-28 18:54:57 +01:00
parent 9884534579
commit 446eea2f7b
3 changed files with 0 additions and 61 deletions

View File

@ -36,9 +36,7 @@ The provided interpolation functions are (from fast to slow execution time)
- `Bilinear`: [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation)
- `Bicubic`: [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation)
- `MitchellNetravali`: [Mitchell-Netravali interpolation](http://dl.acm.org/citation.cfm?id=378514)
- `Lanczos2Lut`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2 using a look-up table for fast computation
- `Lanczos2`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2
- `Lanczos3Lut`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3 using a look-up table for fast computation
- `Lanczos3`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3
Which of these methods gives the best results depends on your use case.

View File

@ -156,35 +156,6 @@ func createFilter(img image.Image, factor float32, size int, kernel func(float32
return
}
// Return a filter kernel that performs nearly identically to the provided
// kernel, but generates and uses a precomputed table rather than executing
// the kernel for each evaluation. The table is generated with tableSize
// values that cover the kernal domain from -maxX to +maxX. The input kernel
// is assumed to be symmetrical around 0, so the table only includes values
// from 0 to maxX.
func tableKernel(kernel func(float32) float32, tableSize int,
maxX float32) func(float32) float32 {
// precompute an array of filter coefficients
weights := make([]float32, tableSize+1)
for i := range weights {
weights[i] = kernel(maxX * float32(i) / float32(tableSize))
}
weights[tableSize] = 0.0
return func(x float32) float32 {
if x < 0.0 {
x = -x
}
indf := x / maxX * float32(tableSize)
ind := int(indf)
if ind >= tableSize {
return 0.0
}
return weights[ind] + (weights[ind+1]-weights[ind])*(indf-float32(ind))
}
}
// Nearest-neighbor interpolation
func NearestNeighbor(img image.Image, factor float32) Filter {
return createFilter(img, factor, 2, func(x float32) (y float32) {
@ -263,21 +234,7 @@ func Lanczos2(img image.Image, factor float32) Filter {
return createFilter(img, factor, 4, lanczosKernel(2))
}
// Lanczos interpolation (a=2) using a look-up table
// to speed up computation
func Lanczos2Lut(img image.Image, factor float32) Filter {
return createFilter(img, factor, 4,
tableKernel(lanczosKernel(2), lanczosTableSize, 2.0))
}
// Lanczos interpolation (a=3)
func Lanczos3(img image.Image, factor float32) Filter {
return createFilter(img, factor, 6, lanczosKernel(3))
}
// Lanczos interpolation (a=3) using a look-up table
// to speed up computation
func Lanczos3Lut(img image.Image, factor float32) Filter {
return createFilter(img, factor, 6,
tableKernel(lanczosKernel(3), lanczosTableSize, 3.0))
}

View File

@ -61,14 +61,6 @@ func Benchmark_BigResizeLanczos3(b *testing.B) {
m.At(0, 0)
}
func Benchmark_BigResizeLanczos3Lut(b *testing.B) {
var m image.Image
for i := 0; i < b.N; i++ {
m = Resize(1000, 1000, img, Lanczos3Lut)
}
m.At(0, 0)
}
func Benchmark_Reduction(b *testing.B) {
largeImg := image.NewRGBA(image.Rect(0, 0, 1000, 1000))
@ -107,18 +99,10 @@ func Benchmark_LargeJpegThumbMitchellNetravali(b *testing.B) {
jpegThumb(b, MitchellNetravali)
}
func Benchmark_LargeJpegThumbLanczos2Lut(b *testing.B) {
jpegThumb(b, Lanczos2Lut)
}
func Benchmark_LargeJpegThumbLanczos2(b *testing.B) {
jpegThumb(b, Lanczos2)
}
func Benchmark_LargeJpegThumbLanczos3Lut(b *testing.B) {
jpegThumb(b, Lanczos3Lut)
}
func Benchmark_LargeJpegThumbLanczos3(b *testing.B) {
jpegThumb(b, Lanczos3)
}