Browse Source

more benchmarks, new test images

Grigory Dryapak 7 years ago
parent
commit
e855101abf

+ 20 - 21
README.md

@@ -5,7 +5,6 @@
 [![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master)](https://coveralls.io/github/disintegration/imaging?branch=master)
 [![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master)](https://coveralls.io/github/disintegration/imaging?branch=master)
 
 
 Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.). 
 Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.). 
-This package is based on the standard Go image package and works best along with it. 
 
 
 Image manipulation functions provided by the package take any image type 
 Image manipulation functions provided by the package take any image type 
 that implements `image.Image` interface as an input, and return a new image of 
 that implements `image.Image` interface as an input, and return a new image of 
@@ -56,9 +55,9 @@ The full list of supported filters:  NearestNeighbor, Box, Linear, Hermite, Mitc
 
 
 The original image.
 The original image.
 
 
-![srcImage](testdata/lena_512.png)
+![srcImage](testdata/branches.png)
 
 
-The same image resized from 512x512px to 128x128px using different resampling filters.
+The same image resized from 600x400px to 150x100px using different resampling filters.
 From faster (lower quality) to slower (higher quality):
 From faster (lower quality) to slower (higher quality):
 
 
 Filter                    | Resize result
 Filter                    | Resize result
@@ -79,7 +78,7 @@ Sigma parameter allows to control the strength of the blurring effect.
 
 
 Original image                     | Sigma = 0.5                            | Sigma = 1.5
 Original image                     | Sigma = 0.5                            | Sigma = 1.5
 -----------------------------------|----------------------------------------|---------------------------------------
 -----------------------------------|----------------------------------------|---------------------------------------
-![srcImage](testdata/lena_128.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
 
 
 ### Sharpening
 ### Sharpening
 
 
@@ -91,7 +90,7 @@ dstImage := imaging.Sharpen(srcImage, 0.5)
 
 
 Original image                     | Sigma = 0.5                               | Sigma = 1.5
 Original image                     | Sigma = 0.5                               | Sigma = 1.5
 -----------------------------------|-------------------------------------------|------------------------------------------
 -----------------------------------|-------------------------------------------|------------------------------------------
-![srcImage](testdata/lena_128.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
 
 
 ### Gamma correction
 ### Gamma correction
 
 
@@ -101,7 +100,7 @@ dstImage := imaging.AdjustGamma(srcImage, 0.75)
 
 
 Original image                     | Gamma = 0.75                             | Gamma = 1.25
 Original image                     | Gamma = 0.75                             | Gamma = 1.25
 -----------------------------------|------------------------------------------|-----------------------------------------
 -----------------------------------|------------------------------------------|-----------------------------------------
-![srcImage](testdata/lena_128.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
 
 
 ### Contrast adjustment
 ### Contrast adjustment
 
 
@@ -109,9 +108,9 @@ Original image                     | Gamma = 0.75                             |
 dstImage := imaging.AdjustContrast(srcImage, 20)
 dstImage := imaging.AdjustContrast(srcImage, 20)
 ```
 ```
 
 
-Original image                     | Contrast = 10                              | Contrast = -10
+Original image                     | Contrast = 15                              | Contrast = -15
 -----------------------------------|--------------------------------------------|-------------------------------------------
 -----------------------------------|--------------------------------------------|-------------------------------------------
-![srcImage](testdata/lena_128.png) | ![dstImage](testdata/out_contrast_p10.png) | ![dstImage](testdata/out_contrast_m10.png)
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
 
 
 ### Brightness adjustment
 ### Brightness adjustment
 
 
@@ -121,7 +120,7 @@ dstImage := imaging.AdjustBrightness(srcImage, 20)
 
 
 Original image                     | Brightness = 10                              | Brightness = -10
 Original image                     | Brightness = 10                              | Brightness = -10
 -----------------------------------|----------------------------------------------|---------------------------------------------
 -----------------------------------|----------------------------------------------|---------------------------------------------
-![srcImage](testdata/lena_128.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
 
 
 ## Example code
 ## Example code
 
 
@@ -137,20 +136,20 @@ import (
 )
 )
 
 
 func main() {
 func main() {
-	// Open the test image.
-	src, err := imaging.Open("testdata/lena_512.png")
+	// Open a test image.
+	src, err := imaging.Open("testdata/flowers.png")
 	if err != nil {
 	if err != nil {
 		log.Fatalf("Open failed: %v", err)
 		log.Fatalf("Open failed: %v", err)
 	}
 	}
 
 
-	// Crop the original image to 350x350px size using the center anchor.
-	src = imaging.CropAnchor(src, 350, 350, imaging.Center)
+	// Crop the original image to 300x300px size using the center anchor.
+	src = imaging.CropAnchor(src, 300, 300, imaging.Center)
 
 
-	// Resize the cropped image to width = 256px preserving the aspect ratio.
-	src = imaging.Resize(src, 256, 0, imaging.Lanczos)
+	// Resize the cropped image to width = 200px preserving the aspect ratio.
+	src = imaging.Resize(src, 200, 0, imaging.Lanczos)
 
 
 	// Create a blurred version of the image.
 	// Create a blurred version of the image.
-	img1 := imaging.Blur(src, 2)
+	img1 := imaging.Blur(src, 5)
 
 
 	// Create a grayscale version of the image with higher contrast and sharpness.
 	// Create a grayscale version of the image with higher contrast and sharpness.
 	img2 := imaging.Grayscale(src)
 	img2 := imaging.Grayscale(src)
@@ -172,13 +171,13 @@ func main() {
 	)
 	)
 
 
 	// Create a new image and paste the four produced images into it.
 	// Create a new image and paste the four produced images into it.
-	dst := imaging.New(512, 512, color.NRGBA{0, 0, 0, 0})
+	dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
 	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
 	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
-	dst = imaging.Paste(dst, img2, image.Pt(0, 256))
-	dst = imaging.Paste(dst, img3, image.Pt(256, 0))
-	dst = imaging.Paste(dst, img4, image.Pt(256, 256))
+	dst = imaging.Paste(dst, img2, image.Pt(0, 200))
+	dst = imaging.Paste(dst, img3, image.Pt(200, 0))
+	dst = imaging.Paste(dst, img4, image.Pt(200, 200))
 
 
-	// Save the resulting image using JPEG format.
+	// Save the resulting image as JPEG.
 	err = imaging.Save(dst, "testdata/out_example.jpg")
 	err = imaging.Save(dst, "testdata/out_example.jpg")
 	if err != nil {
 	if err != nil {
 		log.Fatalf("Save failed: %v", err)
 		log.Fatalf("Save failed: %v", err)

+ 47 - 17
adjust_test.go

@@ -42,6 +42,13 @@ func TestGrayscale(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkGrayscale(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Grayscale(testdataBranchesJPG)
+	}
+}
+
 func TestInvert(t *testing.T) {
 func TestInvert(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -79,6 +86,13 @@ func TestInvert(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkInvert(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Invert(testdataBranchesJPG)
+	}
+}
+
 func TestAdjustContrast(t *testing.T) {
 func TestAdjustContrast(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -207,15 +221,11 @@ func TestAdjustContrast(t *testing.T) {
 }
 }
 
 
 func TestAdjustContrastGolden(t *testing.T) {
 func TestAdjustContrastGolden(t *testing.T) {
-	src, err := Open("testdata/lena_128.png")
-	if err != nil {
-		t.Errorf("Open: %v", err)
-	}
 	for name, p := range map[string]float64{
 	for name, p := range map[string]float64{
-		"out_contrast_m10.png": -10,
-		"out_contrast_p10.png": 10,
+		"out_contrast_m15.png": -15,
+		"out_contrast_p15.png": 15,
 	} {
 	} {
-		got := AdjustContrast(src, p)
+		got := AdjustContrast(testdataFlowersSmallPNG, p)
 		want, err := Open("testdata/" + name)
 		want, err := Open("testdata/" + name)
 		if err != nil {
 		if err != nil {
 			t.Errorf("Open: %v", err)
 			t.Errorf("Open: %v", err)
@@ -226,6 +236,13 @@ func TestAdjustContrastGolden(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkAdjustContrast(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		AdjustContrast(testdataBranchesJPG, 10)
+	}
+}
+
 func TestAdjustBrightness(t *testing.T) {
 func TestAdjustBrightness(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -354,15 +371,11 @@ func TestAdjustBrightness(t *testing.T) {
 }
 }
 
 
 func TestAdjustBrightnessGolden(t *testing.T) {
 func TestAdjustBrightnessGolden(t *testing.T) {
-	src, err := Open("testdata/lena_128.png")
-	if err != nil {
-		t.Errorf("Open: %v", err)
-	}
 	for name, p := range map[string]float64{
 	for name, p := range map[string]float64{
 		"out_brightness_m10.png": -10,
 		"out_brightness_m10.png": -10,
 		"out_brightness_p10.png": 10,
 		"out_brightness_p10.png": 10,
 	} {
 	} {
-		got := AdjustBrightness(src, p)
+		got := AdjustBrightness(testdataFlowersSmallPNG, p)
 		want, err := Open("testdata/" + name)
 		want, err := Open("testdata/" + name)
 		if err != nil {
 		if err != nil {
 			t.Errorf("Open: %v", err)
 			t.Errorf("Open: %v", err)
@@ -373,6 +386,13 @@ func TestAdjustBrightnessGolden(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkAdjustBrightness(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		AdjustBrightness(testdataBranchesJPG, 10)
+	}
+}
+
 func TestAdjustGamma(t *testing.T) {
 func TestAdjustGamma(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -457,15 +477,11 @@ func TestAdjustGamma(t *testing.T) {
 }
 }
 
 
 func TestAdjustGammaGolden(t *testing.T) {
 func TestAdjustGammaGolden(t *testing.T) {
-	src, err := Open("testdata/lena_128.png")
-	if err != nil {
-		t.Errorf("Open: %v", err)
-	}
 	for name, g := range map[string]float64{
 	for name, g := range map[string]float64{
 		"out_gamma_0.75.png": 0.75,
 		"out_gamma_0.75.png": 0.75,
 		"out_gamma_1.25.png": 1.25,
 		"out_gamma_1.25.png": 1.25,
 	} {
 	} {
-		got := AdjustGamma(src, g)
+		got := AdjustGamma(testdataFlowersSmallPNG, g)
 		want, err := Open("testdata/" + name)
 		want, err := Open("testdata/" + name)
 		if err != nil {
 		if err != nil {
 			t.Errorf("Open: %v", err)
 			t.Errorf("Open: %v", err)
@@ -476,6 +492,13 @@ func TestAdjustGammaGolden(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkAdjustGamma(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		AdjustGamma(testdataBranchesJPG, 1.5)
+	}
+}
+
 func TestAdjustSigmoid(t *testing.T) {
 func TestAdjustSigmoid(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -562,3 +585,10 @@ func TestAdjustSigmoid(t *testing.T) {
 		}
 		}
 	}
 	}
 }
 }
+
+func BenchmarkAdjustSigmoid(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		AdjustSigmoid(testdataBranchesJPG, 0.5, 3.0)
+	}
+}

+ 4 - 14
convolution_test.go

@@ -233,15 +233,10 @@ func TestConvolve5x5(t *testing.T) {
 }
 }
 
 
 func BenchmarkConvolve3x3(b *testing.B) {
 func BenchmarkConvolve3x3(b *testing.B) {
-	b.StopTimer()
-	img, err := Open("testdata/lena_512.png")
-	if err != nil {
-		b.Fatalf("Open: %v", err)
-	}
-	b.StartTimer()
+	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
 		Convolve3x3(
 		Convolve3x3(
-			img,
+			testdataBranchesJPG,
 			[9]float64{
 			[9]float64{
 				-1, -1, 0,
 				-1, -1, 0,
 				-1, 0, 1,
 				-1, 0, 1,
@@ -253,15 +248,10 @@ func BenchmarkConvolve3x3(b *testing.B) {
 }
 }
 
 
 func BenchmarkConvolve5x5(b *testing.B) {
 func BenchmarkConvolve5x5(b *testing.B) {
-	b.StopTimer()
-	img, err := Open("testdata/lena_512.png")
-	if err != nil {
-		b.Fatalf("Open: %v", err)
-	}
-	b.StartTimer()
+	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
 		Convolve5x5(
 		Convolve5x5(
-			img,
+			testdataBranchesJPG,
 			[25]float64{
 			[25]float64{
 				-1, -1, -1, -1, 0,
 				-1, -1, -1, -1, 0,
 				-1, -1, -1, 0, 1,
 				-1, -1, -1, 0, 1,

+ 2 - 0
doc.go

@@ -0,0 +1,2 @@
+// Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.).
+package imaging

+ 6 - 24
effects_test.go

@@ -89,15 +89,11 @@ func TestBlur(t *testing.T) {
 }
 }
 
 
 func TestBlurGolden(t *testing.T) {
 func TestBlurGolden(t *testing.T) {
-	src, err := Open("testdata/lena_128.png")
-	if err != nil {
-		t.Errorf("Open: %v", err)
-	}
 	for name, sigma := range map[string]float64{
 	for name, sigma := range map[string]float64{
 		"out_blur_0.5.png": 0.5,
 		"out_blur_0.5.png": 0.5,
 		"out_blur_1.5.png": 1.5,
 		"out_blur_1.5.png": 1.5,
 	} {
 	} {
-		got := Blur(src, sigma)
+		got := Blur(testdataFlowersSmallPNG, sigma)
 		want, err := Open("testdata/" + name)
 		want, err := Open("testdata/" + name)
 		if err != nil {
 		if err != nil {
 			t.Errorf("Open: %v", err)
 			t.Errorf("Open: %v", err)
@@ -109,14 +105,9 @@ func TestBlurGolden(t *testing.T) {
 }
 }
 
 
 func BenchmarkBlur(b *testing.B) {
 func BenchmarkBlur(b *testing.B) {
-	b.StopTimer()
-	img, err := Open("testdata/lena_512.png")
-	if err != nil {
-		b.Fatalf("Open: %v", err)
-	}
-	b.StartTimer()
+	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
-		Blur(img, 3)
+		Blur(testdataBranchesJPG, 3)
 	}
 	}
 }
 }
 
 
@@ -222,15 +213,11 @@ func TestSharpen(t *testing.T) {
 }
 }
 
 
 func TestSharpenGolden(t *testing.T) {
 func TestSharpenGolden(t *testing.T) {
-	src, err := Open("testdata/lena_128.png")
-	if err != nil {
-		t.Errorf("Open: %v", err)
-	}
 	for name, sigma := range map[string]float64{
 	for name, sigma := range map[string]float64{
 		"out_sharpen_0.5.png": 0.5,
 		"out_sharpen_0.5.png": 0.5,
 		"out_sharpen_1.5.png": 1.5,
 		"out_sharpen_1.5.png": 1.5,
 	} {
 	} {
-		got := Sharpen(src, sigma)
+		got := Sharpen(testdataFlowersSmallPNG, sigma)
 		want, err := Open("testdata/" + name)
 		want, err := Open("testdata/" + name)
 		if err != nil {
 		if err != nil {
 			t.Errorf("Open: %v", err)
 			t.Errorf("Open: %v", err)
@@ -242,13 +229,8 @@ func TestSharpenGolden(t *testing.T) {
 }
 }
 
 
 func BenchmarkSharpen(b *testing.B) {
 func BenchmarkSharpen(b *testing.B) {
-	b.StopTimer()
-	img, err := Open("testdata/lena_512.png")
-	if err != nil {
-		b.Fatalf("Open: %v", err)
-	}
-	b.StartTimer()
+	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
-		Sharpen(img, 3)
+		Sharpen(testdataBranchesJPG, 3)
 	}
 	}
 }
 }

+ 12 - 12
example_test.go

@@ -9,20 +9,20 @@ import (
 )
 )
 
 
 func Example() {
 func Example() {
-	// Open the test image.
-	src, err := imaging.Open("testdata/lena_512.png")
+	// Open a test image.
+	src, err := imaging.Open("testdata/flowers.png")
 	if err != nil {
 	if err != nil {
 		log.Fatalf("Open failed: %v", err)
 		log.Fatalf("Open failed: %v", err)
 	}
 	}
 
 
-	// Crop the original image to 350x350px size using the center anchor.
-	src = imaging.CropAnchor(src, 350, 350, imaging.Center)
+	// Crop the original image to 300x300px size using the center anchor.
+	src = imaging.CropAnchor(src, 300, 300, imaging.Center)
 
 
-	// Resize the cropped image to width = 256px preserving the aspect ratio.
-	src = imaging.Resize(src, 256, 0, imaging.Lanczos)
+	// Resize the cropped image to width = 200px preserving the aspect ratio.
+	src = imaging.Resize(src, 200, 0, imaging.Lanczos)
 
 
 	// Create a blurred version of the image.
 	// Create a blurred version of the image.
-	img1 := imaging.Blur(src, 2)
+	img1 := imaging.Blur(src, 5)
 
 
 	// Create a grayscale version of the image with higher contrast and sharpness.
 	// Create a grayscale version of the image with higher contrast and sharpness.
 	img2 := imaging.Grayscale(src)
 	img2 := imaging.Grayscale(src)
@@ -44,13 +44,13 @@ func Example() {
 	)
 	)
 
 
 	// Create a new image and paste the four produced images into it.
 	// Create a new image and paste the four produced images into it.
-	dst := imaging.New(512, 512, color.NRGBA{0, 0, 0, 0})
+	dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
 	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
 	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
-	dst = imaging.Paste(dst, img2, image.Pt(0, 256))
-	dst = imaging.Paste(dst, img3, image.Pt(256, 0))
-	dst = imaging.Paste(dst, img4, image.Pt(256, 256))
+	dst = imaging.Paste(dst, img2, image.Pt(0, 200))
+	dst = imaging.Paste(dst, img3, image.Pt(200, 0))
+	dst = imaging.Paste(dst, img4, image.Pt(200, 200))
 
 
-	// Save the resulting image using JPEG format.
+	// Save the resulting image as JPEG.
 	err = imaging.Save(dst, "testdata/out_example.jpg")
 	err = imaging.Save(dst, "testdata/out_example.jpg")
 	if err != nil {
 	if err != nil {
 		log.Fatalf("Save failed: %v", err)
 		log.Fatalf("Save failed: %v", err)

+ 2 - 12
helpers.go

@@ -1,9 +1,3 @@
-// Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.).
-// This package is based on the standard Go image package and works best along with it.
-//
-// Image manipulation functions provided by the package take any image type
-// that implements `image.Image` interface as an input, and return a new image of
-// `*image.NRGBA` type (32bit RGBA colors, not premultiplied by alpha).
 package imaging
 package imaging
 
 
 import (
 import (
@@ -59,10 +53,7 @@ var (
 // Decode reads an image from r.
 // Decode reads an image from r.
 func Decode(r io.Reader) (image.Image, error) {
 func Decode(r io.Reader) (image.Image, error) {
 	img, _, err := image.Decode(r)
 	img, _, err := image.Decode(r)
-	if err != nil {
-		return nil, err
-	}
-	return toNRGBA(img), nil
+	return img, err
 }
 }
 
 
 // Open loads an image from file
 // Open loads an image from file
@@ -72,8 +63,7 @@ func Open(filename string) (image.Image, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 	defer file.Close()
 	defer file.Close()
-	img, err := Decode(file)
-	return img, err
+	return Decode(file)
 }
 }
 
 
 type encodeConfig struct {
 type encodeConfig struct {

+ 7 - 0
helpers_test.go

@@ -140,6 +140,13 @@ func TestNew(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkNew(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		New(1024, 1024, color.White)
+	}
+}
+
 func TestFormats(t *testing.T) {
 func TestFormats(t *testing.T) {
 	formatNames := map[Format]string{
 	formatNames := map[Format]string{
 		JPEG:       "JPEG",
 		JPEG:       "JPEG",

+ 7 - 0
histogram_test.go

@@ -40,3 +40,10 @@ func TestHistogram(t *testing.T) {
 		}
 		}
 	}
 	}
 }
 }
+
+func BenchmarkHistogram(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Histogram(testdataBranchesJPG)
+	}
+}

+ 39 - 35
resize_test.go

@@ -1,6 +1,7 @@
 package imaging
 package imaging
 
 
 import (
 import (
+	"fmt"
 	"image"
 	"image"
 	"testing"
 	"testing"
 )
 )
@@ -202,17 +203,13 @@ func TestResize(t *testing.T) {
 }
 }
 
 
 func TestResizeGolden(t *testing.T) {
 func TestResizeGolden(t *testing.T) {
-	src, err := Open("testdata/lena_512.png")
-	if err != nil {
-		t.Errorf("Open: %v", err)
-	}
 	for name, filter := range map[string]ResampleFilter{
 	for name, filter := range map[string]ResampleFilter{
 		"out_resize_nearest.png": NearestNeighbor,
 		"out_resize_nearest.png": NearestNeighbor,
 		"out_resize_linear.png":  Linear,
 		"out_resize_linear.png":  Linear,
 		"out_resize_catrom.png":  CatmullRom,
 		"out_resize_catrom.png":  CatmullRom,
 		"out_resize_lanczos.png": Lanczos,
 		"out_resize_lanczos.png": Lanczos,
 	} {
 	} {
-		got := Resize(src, 128, 0, filter)
+		got := Resize(testdataBranchesPNG, 150, 0, filter)
 		want, err := Open("testdata/" + name)
 		want, err := Open("testdata/" + name)
 		if err != nil {
 		if err != nil {
 			t.Errorf("Open: %v", err)
 			t.Errorf("Open: %v", err)
@@ -591,38 +588,45 @@ func TestThumbnail(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func BenchmarkResizeLanczosUp(b *testing.B) {
-	benchmarkResize(b, "testdata/lena_128.png", 512, Lanczos)
-}
+func BenchmarkResize(b *testing.B) {
+	for _, dir := range []string{"Down", "Up"} {
+		for _, filter := range []string{"NearestNeighbor", "Linear", "CatmullRom", "Lanczos"} {
+			for _, format := range []string{"JPEG", "PNG"} {
+				var size int
+				switch dir {
+				case "Down":
+					size = 100
+				case "Up":
+					size = 1000
+				}
 
 
-func BenchmarkResizeLinearUp(b *testing.B) {
-	benchmarkResize(b, "testdata/lena_128.png", 512, Linear)
-}
+				var f ResampleFilter
+				switch filter {
+				case "NearestNeighbor":
+					f = NearestNeighbor
+				case "Linear":
+					f = Linear
+				case "CatmullRom":
+					f = CatmullRom
+				case "Lanczos":
+					f = Lanczos
+				}
 
 
-func BenchmarkResizeNearestNeighborUp(b *testing.B) {
-	benchmarkResize(b, "testdata/lena_128.png", 512, NearestNeighbor)
-}
+				var img image.Image
+				switch format {
+				case "JPEG":
+					img = testdataBranchesJPG
+				case "PNG":
+					img = testdataBranchesPNG
+				}
 
 
-func BenchmarkResizeLanczosDown(b *testing.B) {
-	benchmarkResize(b, "testdata/lena_512.png", 128, Lanczos)
-}
-
-func BenchmarkResizeLinearDown(b *testing.B) {
-	benchmarkResize(b, "testdata/lena_512.png", 128, Linear)
-}
-
-func BenchmarkResizeNearestNeighborDown(b *testing.B) {
-	benchmarkResize(b, "testdata/lena_512.png", 128, NearestNeighbor)
-}
-
-func benchmarkResize(b *testing.B, filename string, size int, f ResampleFilter) {
-	b.StopTimer()
-	img, err := Open(filename)
-	if err != nil {
-		b.Fatalf("Open: %v", err)
-	}
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Resize(img, size, size, f)
+				b.Run(fmt.Sprintf("%s %s %s", dir, filter, format), func(b *testing.B) {
+					b.ReportAllocs()
+					for i := 0; i < b.N; i++ {
+						Resize(img, size, size, f)
+					}
+				})
+			}
+		}
 	}
 	}
 }
 }

BIN
testdata/branches.jpg


BIN
testdata/branches.png


BIN
testdata/flowers.png


BIN
testdata/flowers_small.png


BIN
testdata/out_blur_0.5.png


BIN
testdata/out_blur_1.5.png


BIN
testdata/out_brightness_m10.png


BIN
testdata/out_brightness_p10.png


BIN
testdata/out_contrast_m15.png


BIN
testdata/out_contrast_p15.png


BIN
testdata/out_example.jpg


BIN
testdata/out_gamma_0.75.png


BIN
testdata/out_gamma_1.25.png


BIN
testdata/out_resize_catrom.png


BIN
testdata/out_resize_lanczos.png


BIN
testdata/out_resize_linear.png


BIN
testdata/out_resize_nearest.png


BIN
testdata/out_sharpen_0.5.png


BIN
testdata/out_sharpen_1.5.png


+ 21 - 0
tools_test.go

@@ -42,6 +42,13 @@ func TestCrop(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkCrop(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Crop(testdataBranchesJPG, image.Rect(100, 100, 300, 300))
+	}
+}
+
 func TestCropCenter(t *testing.T) {
 func TestCropCenter(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -481,6 +488,13 @@ func TestPaste(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkPaste(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Paste(testdataBranchesJPG, testdataFlowersSmallPNG, image.Pt(100, 100))
+	}
+}
+
 func TestPasteCenter(t *testing.T) {
 func TestPasteCenter(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -604,6 +618,13 @@ func TestOverlay(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkOverlay(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Overlay(testdataBranchesJPG, testdataFlowersSmallPNG, image.Pt(100, 100), 0.5)
+	}
+}
+
 func TestOverlayCenter(t *testing.T) {
 func TestOverlayCenter(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string

+ 56 - 0
transform_test.go

@@ -43,6 +43,13 @@ func TestFlipH(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkFlipH(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		FlipH(testdataBranchesJPG)
+	}
+}
+
 func TestFlipV(t *testing.T) {
 func TestFlipV(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -80,6 +87,13 @@ func TestFlipV(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkFlipV(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		FlipV(testdataBranchesJPG)
+	}
+}
+
 func TestTranspose(t *testing.T) {
 func TestTranspose(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -116,6 +130,13 @@ func TestTranspose(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkTranspose(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Transpose(testdataBranchesJPG)
+	}
+}
+
 func TestTransverse(t *testing.T) {
 func TestTransverse(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -152,6 +173,13 @@ func TestTransverse(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkTransverse(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Transverse(testdataBranchesJPG)
+	}
+}
+
 func TestRotate90(t *testing.T) {
 func TestRotate90(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -188,6 +216,13 @@ func TestRotate90(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkRotate90(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Rotate90(testdataBranchesJPG)
+	}
+}
+
 func TestRotate180(t *testing.T) {
 func TestRotate180(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -225,6 +260,13 @@ func TestRotate180(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkRotate180(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Rotate180(testdataBranchesJPG)
+	}
+}
+
 func TestRotate270(t *testing.T) {
 func TestRotate270(t *testing.T) {
 	td := []struct {
 	td := []struct {
 		desc string
 		desc string
@@ -261,6 +303,13 @@ func TestRotate270(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func BenchmarkRotate270(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Rotate270(testdataBranchesJPG)
+	}
+}
+
 func TestRotate(t *testing.T) {
 func TestRotate(t *testing.T) {
 	testCases := []struct {
 	testCases := []struct {
 		desc  string
 		desc  string
@@ -579,3 +628,10 @@ func TestRotate(t *testing.T) {
 		}
 		}
 	}
 	}
 }
 }
+
+func BenchmarkRotate(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		Rotate(testdataBranchesJPG, 30, color.Transparent)
+	}
+}

+ 22 - 8
utils_test.go

@@ -1,11 +1,27 @@
 package imaging
 package imaging
 
 
 import (
 import (
+	"image"
 	"runtime"
 	"runtime"
 	"testing"
 	"testing"
 )
 )
 
 
-func testParallelN(enabled bool, n, procs int) bool {
+var (
+	testdataBranchesJPG     = mustOpen("testdata/branches.jpg")
+	testdataBranchesPNG     = mustOpen("testdata/branches.png")
+	testdataFlowersPNG      = mustOpen("testdata/flowers.png")
+	testdataFlowersSmallPNG = mustOpen("testdata/flowers_small.png")
+)
+
+func mustOpen(filename string) image.Image {
+	img, err := Open(filename)
+	if err != nil {
+		panic(err)
+	}
+	return img
+}
+
+func testParallelN(n, procs int) bool {
 	data := make([]bool, n)
 	data := make([]bool, n)
 	before := runtime.GOMAXPROCS(0)
 	before := runtime.GOMAXPROCS(0)
 	runtime.GOMAXPROCS(procs)
 	runtime.GOMAXPROCS(procs)
@@ -14,22 +30,20 @@ func testParallelN(enabled bool, n, procs int) bool {
 			data[i] = true
 			data[i] = true
 		}
 		}
 	})
 	})
+	runtime.GOMAXPROCS(before)
 	for i := 0; i < n; i++ {
 	for i := 0; i < n; i++ {
 		if !data[i] {
 		if !data[i] {
 			return false
 			return false
 		}
 		}
 	}
 	}
-	runtime.GOMAXPROCS(before)
 	return true
 	return true
 }
 }
 
 
 func TestParallel(t *testing.T) {
 func TestParallel(t *testing.T) {
-	for _, e := range []bool{true, false} {
-		for _, n := range []int{1, 10, 100, 1000} {
-			for _, p := range []int{1, 2, 4, 8, 16, 100} {
-				if !testParallelN(e, n, p) {
-					t.Errorf("test [parallel %v %d %d] failed", e, n, p)
-				}
+	for _, n := range []int{0, 1, 10, 100, 1000} {
+		for _, p := range []int{1, 2, 4, 8, 16, 100} {
+			if !testParallelN(n, p) {
+				t.Errorf("test [parallel %d %d] failed", n, p)
 			}
 			}
 		}
 		}
 	}
 	}