From 294efa80bb4b2ed3e1b2ff1b71dcdf7bf02ac827 Mon Sep 17 00:00:00 2001 From: jst Date: Thu, 23 Aug 2012 19:36:02 +0200 Subject: [PATCH] Prevent resize from doing things multiple times if #CPUs > width --- README.md | 2 +- resize.go | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 35f3da2..6639e7c 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ func main() { file.Close() // resize to width 1000 using Lanczos resampling - // and preserve aspect ration + // and preserve aspect ratio m := resize.Resize(1000, 0, img, resize.Lanczos3) out, err := os.Create("test_resized.jpg") diff --git a/resize.go b/resize.go index 57c7797..a3ac3d0 100644 --- a/resize.go +++ b/resize.go @@ -21,7 +21,7 @@ THIS SOFTWARE. // utilized in the computations. // // Example: -// imgResized := resize.Resize(1000, -1, imgOld, Lanczos3) +// imgResized := resize.Resize(1000, 0, imgOld, Lanczos3) package resize import ( @@ -70,9 +70,9 @@ func calcFactors(width, height uint, oldWidth, oldHeight float32) (scaleX, scale // an image type InterpolationFunction func(float32, float32, image.Image) color.RGBA64 -// Resize an image to new width w and height h using the interpolation function interp. +// Resize an image to new width and height using the interpolation function interp. // A new image with the given dimensions will be returned. -// If one of the parameters w or h is set to 0, its size will be calculated so that +// If one of the parameters width or height is set to 0, its size will be calculated so that // the aspect ratio is that of the originating image. // The resizing algorithm uses channels for parallel computation. func Resize(width, height uint, img image.Image, interp InterpolationFunction) image.Image { @@ -83,26 +83,35 @@ func Resize(width, height uint, img image.Image, interp InterpolationFunction) i scaleX, scaleY := calcFactors(width, height, oldWidth, oldHeight) t := Trans2{scaleX, 0, float32(oldBounds.Min.X), 0, scaleY, float32(oldBounds.Min.Y)} - m := image.NewRGBA64(image.Rect(0, 0, int(oldWidth/scaleX), int(oldHeight/scaleY))) - b := m.Bounds() + resizedImg := image.NewRGBA64(image.Rect(0, 0, int(oldWidth/scaleX), int(oldHeight/scaleY))) + b := resizedImg.Bounds() + + // prevent resize from doing too much work + // if #CPUs > width + n := 1 + if (NCPU < b.Dy()) { + n = NCPU + } else { + n = b.Dy() + } - c := make(chan int, NCPU) - for i := 0; i < NCPU; i++ { + c := make(chan int, n) + for i := 0; i < n; i++ { go func(b image.Rectangle, c chan int) { var u, v float32 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)) - m.SetRGBA64(x, y, interp(u, v, img)) + resizedImg.SetRGBA64(x, y, interp(u, v, img)) } } c <- 1 - }(image.Rect(b.Min.X, b.Min.Y+i*(b.Dy())/NCPU, b.Max.X, b.Min.Y+(i+1)*(b.Dy())/NCPU), c) + }(image.Rect(b.Min.X, b.Min.Y+i*(b.Dy())/n, b.Max.X, b.Min.Y+(i+1)*(b.Dy())/n), c) } - for i := 0; i < NCPU; i++ { + for i := 0; i < n; i++ { <-c } - return m + return resizedImg }