git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/imaging/resize_test.go (about)

     1  package imaging
     2  
     3  import (
     4  	"fmt"
     5  	"image"
     6  	"path/filepath"
     7  	"testing"
     8  )
     9  
    10  func TestResize(t *testing.T) {
    11  	testCases := []struct {
    12  		name string
    13  		src  image.Image
    14  		w, h int
    15  		f    ResampleFilter
    16  		want *image.NRGBA
    17  	}{
    18  		{
    19  			"Resize 2x2 1x1 box",
    20  			&image.NRGBA{
    21  				Rect:   image.Rect(-1, -1, 1, 1),
    22  				Stride: 2 * 4,
    23  				Pix: []uint8{
    24  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
    25  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
    26  				},
    27  			},
    28  			1, 1,
    29  			Box,
    30  			&image.NRGBA{
    31  				Rect:   image.Rect(0, 0, 1, 1),
    32  				Stride: 1 * 4,
    33  				Pix:    []uint8{0x55, 0x55, 0x55, 0xc0},
    34  			},
    35  		},
    36  		{
    37  			"Resize 2x2 1x2 box",
    38  			&image.NRGBA{
    39  				Rect:   image.Rect(-1, -1, 1, 1),
    40  				Stride: 2 * 4,
    41  				Pix: []uint8{
    42  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
    43  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
    44  				},
    45  			},
    46  			1, 2,
    47  			Box,
    48  			&image.NRGBA{
    49  				Rect:   image.Rect(0, 0, 1, 2),
    50  				Stride: 1 * 4,
    51  				Pix: []uint8{
    52  					0xff, 0x00, 0x00, 0x80,
    53  					0x00, 0x80, 0x80, 0xff,
    54  				},
    55  			},
    56  		},
    57  		{
    58  			"Resize 2x2 2x1 box",
    59  			&image.NRGBA{
    60  				Rect:   image.Rect(-1, -1, 1, 1),
    61  				Stride: 2 * 4,
    62  				Pix: []uint8{
    63  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
    64  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
    65  				},
    66  			},
    67  			2, 1,
    68  			Box,
    69  			&image.NRGBA{
    70  				Rect:   image.Rect(0, 0, 2, 1),
    71  				Stride: 2 * 4,
    72  				Pix: []uint8{
    73  					0x00, 0xff, 0x00, 0x80, 0x80, 0x00, 0x80, 0xff,
    74  				},
    75  			},
    76  		},
    77  		{
    78  			"Resize 2x2 2x2 box",
    79  			&image.NRGBA{
    80  				Rect:   image.Rect(-1, -1, 1, 1),
    81  				Stride: 2 * 4,
    82  				Pix: []uint8{
    83  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
    84  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
    85  				},
    86  			},
    87  			2, 2,
    88  			Box,
    89  			&image.NRGBA{
    90  				Rect:   image.Rect(0, 0, 2, 2),
    91  				Stride: 2 * 4,
    92  				Pix: []uint8{
    93  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
    94  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
    95  				},
    96  			},
    97  		},
    98  		{
    99  			"Resize 3x1 1x1 nearest",
   100  			&image.NRGBA{
   101  				Rect:   image.Rect(-1, -1, 2, 0),
   102  				Stride: 3 * 4,
   103  				Pix: []uint8{
   104  					0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   105  				},
   106  			},
   107  			1, 1,
   108  			NearestNeighbor,
   109  			&image.NRGBA{
   110  				Rect:   image.Rect(0, 0, 1, 1),
   111  				Stride: 1 * 4,
   112  				Pix:    []uint8{0x00, 0xff, 0x00, 0xff},
   113  			},
   114  		},
   115  		{
   116  			"Resize 2x2 0x4 box",
   117  			&image.NRGBA{
   118  				Rect:   image.Rect(-1, -1, 1, 1),
   119  				Stride: 2 * 4,
   120  				Pix: []uint8{
   121  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   122  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   123  				},
   124  			},
   125  			0, 4,
   126  			Box,
   127  			&image.NRGBA{
   128  				Rect:   image.Rect(0, 0, 4, 4),
   129  				Stride: 4 * 4,
   130  				Pix: []uint8{
   131  					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
   132  					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
   133  					0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
   134  					0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
   135  				},
   136  			},
   137  		},
   138  		{
   139  			"Resize 2x2 4x0 linear",
   140  			&image.NRGBA{
   141  				Rect:   image.Rect(-1, -1, 1, 1),
   142  				Stride: 2 * 4,
   143  				Pix: []uint8{
   144  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   145  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   146  				},
   147  			},
   148  			4, 0,
   149  			Linear,
   150  			&image.NRGBA{
   151  				Rect:   image.Rect(0, 0, 4, 4),
   152  				Stride: 4 * 4,
   153  				Pix: []uint8{
   154  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x40, 0xff, 0x00, 0x00, 0xbf, 0xff, 0x00, 0x00, 0xff,
   155  					0x00, 0xff, 0x00, 0x40, 0x6e, 0x6d, 0x25, 0x70, 0xb0, 0x14, 0x3b, 0xcf, 0xbf, 0x00, 0x40, 0xff,
   156  					0x00, 0xff, 0x00, 0xbf, 0x14, 0xb0, 0x3b, 0xcf, 0x33, 0x33, 0x99, 0xef, 0x40, 0x00, 0xbf, 0xff,
   157  					0x00, 0xff, 0x00, 0xff, 0x00, 0xbf, 0x40, 0xff, 0x00, 0x40, 0xbf, 0xff, 0x00, 0x00, 0xff, 0xff,
   158  				},
   159  			},
   160  		},
   161  		{
   162  			"Resize 0x0 1x1 box",
   163  			&image.NRGBA{
   164  				Rect:   image.Rect(-1, -1, -1, -1),
   165  				Stride: 0,
   166  				Pix:    []uint8{},
   167  			},
   168  			1, 1,
   169  			Box,
   170  			&image.NRGBA{},
   171  		},
   172  		{
   173  			"Resize 2x2 0x0 box",
   174  			&image.NRGBA{
   175  				Rect:   image.Rect(-1, -1, 1, 1),
   176  				Stride: 2 * 4,
   177  				Pix: []uint8{
   178  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   179  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   180  				},
   181  			},
   182  			0, 0,
   183  			Box,
   184  			&image.NRGBA{},
   185  		},
   186  		{
   187  			"Resize 2x2 -1x0 box",
   188  			&image.NRGBA{
   189  				Rect:   image.Rect(-1, -1, 1, 1),
   190  				Stride: 2 * 4,
   191  				Pix: []uint8{
   192  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   193  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   194  				},
   195  			},
   196  			-1, 0,
   197  			Box,
   198  			&image.NRGBA{},
   199  		},
   200  	}
   201  	for _, tc := range testCases {
   202  		t.Run(tc.name, func(t *testing.T) {
   203  			got := Resize(tc.src, tc.w, tc.h, tc.f)
   204  			if !compareNRGBA(got, tc.want, 0) {
   205  				t.Fatalf("got result %#v want %#v", got, tc.want)
   206  			}
   207  		})
   208  	}
   209  }
   210  
   211  func TestResampleFilters(t *testing.T) {
   212  	for _, filter := range []ResampleFilter{
   213  		NearestNeighbor,
   214  		Box,
   215  		Linear,
   216  		Hermite,
   217  		MitchellNetravali,
   218  		CatmullRom,
   219  		BSpline,
   220  		Gaussian,
   221  		Lanczos,
   222  		Hann,
   223  		Hamming,
   224  		Blackman,
   225  		Bartlett,
   226  		Welch,
   227  		Cosine,
   228  	} {
   229  		t.Run("", func(t *testing.T) {
   230  			src := image.NewNRGBA(image.Rect(-1, -1, 2, 3))
   231  			got := Resize(src, 5, 6, filter)
   232  			want := image.NewNRGBA(image.Rect(0, 0, 5, 6))
   233  			if !compareNRGBA(got, want, 0) {
   234  				t.Fatalf("got result %#v want %#v", got, want)
   235  			}
   236  			if filter.Kernel != nil {
   237  				if x := filter.Kernel(filter.Support + 0.0001); x != 0 {
   238  					t.Fatalf("got kernel value %f want 0", x)
   239  				}
   240  			}
   241  		})
   242  	}
   243  }
   244  
   245  func TestResizeGolden(t *testing.T) {
   246  	for name, filter := range map[string]ResampleFilter{
   247  		"out_resize_nearest.png": NearestNeighbor,
   248  		"out_resize_linear.png":  Linear,
   249  		"out_resize_catrom.png":  CatmullRom,
   250  		"out_resize_lanczos.png": Lanczos,
   251  	} {
   252  		got := Resize(testdataBranchesPNG, 150, 0, filter)
   253  		want, err := Open("testdata/" + name)
   254  		if err != nil {
   255  			t.Fatalf("failed to open image: %v", err)
   256  		}
   257  		if !compareNRGBAGolden(got, toNRGBA(want)) {
   258  			t.Fatalf("resulting image differs from golden: %s", name)
   259  		}
   260  	}
   261  }
   262  
   263  func TestFit(t *testing.T) {
   264  	testCases := []struct {
   265  		name string
   266  		src  image.Image
   267  		w, h int
   268  		f    ResampleFilter
   269  		want *image.NRGBA
   270  	}{
   271  		{
   272  			"Fit 2x2 1x10 box",
   273  			&image.NRGBA{
   274  				Rect:   image.Rect(-1, -1, 1, 1),
   275  				Stride: 2 * 4,
   276  				Pix: []uint8{
   277  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   278  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   279  				},
   280  			},
   281  			1, 10,
   282  			Box,
   283  			&image.NRGBA{
   284  				Rect:   image.Rect(0, 0, 1, 1),
   285  				Stride: 1 * 4,
   286  				Pix:    []uint8{0x55, 0x55, 0x55, 0xc0},
   287  			},
   288  		},
   289  		{
   290  			"Fit 2x2 10x1 box",
   291  			&image.NRGBA{
   292  				Rect:   image.Rect(-1, -1, 1, 1),
   293  				Stride: 2 * 4,
   294  				Pix: []uint8{
   295  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   296  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   297  				},
   298  			},
   299  			10, 1,
   300  			Box,
   301  			&image.NRGBA{
   302  				Rect:   image.Rect(0, 0, 1, 1),
   303  				Stride: 1 * 4,
   304  				Pix:    []uint8{0x55, 0x55, 0x55, 0xc0},
   305  			},
   306  		},
   307  		{
   308  			"Fit 2x2 10x10 box",
   309  			&image.NRGBA{
   310  				Rect:   image.Rect(-1, -1, 1, 1),
   311  				Stride: 2 * 4,
   312  				Pix: []uint8{
   313  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   314  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   315  				},
   316  			},
   317  			10, 10,
   318  			Box,
   319  			&image.NRGBA{
   320  				Rect:   image.Rect(0, 0, 2, 2),
   321  				Stride: 2 * 4,
   322  				Pix: []uint8{
   323  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   324  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   325  				},
   326  			},
   327  		},
   328  		{
   329  			"Fit 0x0 1x1 box",
   330  			&image.NRGBA{
   331  				Rect:   image.Rect(-1, -1, -1, -1),
   332  				Stride: 0,
   333  				Pix:    []uint8{},
   334  			},
   335  			1, 1,
   336  			Box,
   337  			&image.NRGBA{},
   338  		},
   339  		{
   340  			"Fit 2x2 0x0 box",
   341  			&image.NRGBA{
   342  				Rect:   image.Rect(-1, -1, 1, 1),
   343  				Stride: 2 * 4,
   344  				Pix: []uint8{
   345  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   346  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   347  				},
   348  			},
   349  			0, 0,
   350  			Box,
   351  			&image.NRGBA{},
   352  		},
   353  		{
   354  			"Fit 2x2 -1x0 box",
   355  			&image.NRGBA{
   356  				Rect:   image.Rect(-1, -1, 1, 1),
   357  				Stride: 2 * 4,
   358  				Pix: []uint8{
   359  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   360  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   361  				},
   362  			},
   363  			-1, 0,
   364  			Box,
   365  			&image.NRGBA{},
   366  		},
   367  	}
   368  	for _, tc := range testCases {
   369  		t.Run(tc.name, func(t *testing.T) {
   370  			got := Fit(tc.src, tc.w, tc.h, tc.f)
   371  			if !compareNRGBA(got, tc.want, 0) {
   372  				t.Fatalf("got result %#v want %#v", got, tc.want)
   373  			}
   374  		})
   375  	}
   376  }
   377  
   378  func TestFitGolden(t *testing.T) {
   379  	got := Fit(testdataBranchesPNG, 150, 150, Box)
   380  	name := filepath.Join("testdata", "out_fit.png")
   381  	want, err := Open(name)
   382  	if err != nil {
   383  		t.Fatalf("failed to open image: %v", err)
   384  	}
   385  	if !compareNRGBAGolden(got, toNRGBA(want)) {
   386  		t.Fatalf("resulting image differs from golden: %s", name)
   387  	}
   388  }
   389  
   390  func TestFill(t *testing.T) {
   391  	testCases := []struct {
   392  		name string
   393  		src  image.Image
   394  		w, h int
   395  		a    Anchor
   396  		f    ResampleFilter
   397  		want *image.NRGBA
   398  	}{
   399  		{
   400  			"Fill 4x4 4x4 TopRight Box",
   401  			&image.NRGBA{
   402  				Rect:   image.Rect(-1, -1, 3, 3),
   403  				Stride: 4 * 4,
   404  				Pix: []uint8{
   405  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   406  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   407  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   408  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   409  				},
   410  			},
   411  			4, 4,
   412  			TopRight,
   413  			Box,
   414  			&image.NRGBA{
   415  				Rect:   image.Rect(0, 0, 4, 4),
   416  				Stride: 4 * 4,
   417  				Pix: []uint8{
   418  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   419  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   420  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   421  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   422  				},
   423  			},
   424  		},
   425  		{
   426  			"Fill 4x4 0x4 Left Box",
   427  			&image.NRGBA{
   428  				Rect:   image.Rect(-1, -1, 3, 3),
   429  				Stride: 4 * 4,
   430  				Pix: []uint8{
   431  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   432  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   433  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   434  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   435  				},
   436  			},
   437  			0, 4,
   438  			Left,
   439  			Box,
   440  			&image.NRGBA{},
   441  		},
   442  		{
   443  			"Fill 0x0 4x4 Right Box",
   444  			&image.NRGBA{},
   445  			4, 4,
   446  			Right,
   447  			Box,
   448  			&image.NRGBA{},
   449  		},
   450  		{
   451  			"Fill 100x200 20x10 Center Linear",
   452  			image.NewRGBA(image.Rect(0, 0, 100, 200)),
   453  			20, 10,
   454  			Center,
   455  			Linear,
   456  			image.NewNRGBA(image.Rect(0, 0, 20, 10)),
   457  		},
   458  		{
   459  			"Fill 10x20 20x10 Center Linear",
   460  			image.NewRGBA(image.Rect(0, 0, 10, 20)),
   461  			20, 10,
   462  			Center,
   463  			Linear,
   464  			image.NewNRGBA(image.Rect(0, 0, 20, 10)),
   465  		},
   466  	}
   467  	for _, tc := range testCases {
   468  		t.Run(tc.name, func(t *testing.T) {
   469  			got := Fill(tc.src, tc.w, tc.h, tc.a, tc.f)
   470  			if !compareNRGBA(got, tc.want, 0) {
   471  				t.Fatalf("got result %#v want %#v", got, tc.want)
   472  			}
   473  		})
   474  	}
   475  }
   476  
   477  func TestFillGolden(t *testing.T) {
   478  	anchorPoints := map[string]Anchor{
   479  		"left":   Left,
   480  		"center": Center,
   481  		"right":  Right,
   482  	}
   483  	for apName, ap := range anchorPoints {
   484  		got := Fill(testdataBranchesPNG, 150, 150, ap, Box)
   485  		name := filepath.Join("testdata", "out_fill_"+apName+".png")
   486  		want, err := Open(name)
   487  		if err != nil {
   488  			t.Fatalf("failed to open image: %v", err)
   489  		}
   490  		if !compareNRGBAGolden(got, toNRGBA(want)) {
   491  			t.Fatalf("resulting image differs from golden: %s", name)
   492  		}
   493  	}
   494  }
   495  
   496  func TestResizeAndCrop(t *testing.T) {
   497  	testCases := []struct {
   498  		name string
   499  		src  image.Image
   500  		w, h int
   501  		a    Anchor
   502  		f    ResampleFilter
   503  		want *image.NRGBA
   504  	}{
   505  		{
   506  			"resizeAndCrop 4x4 2x2 Center Nearest",
   507  			&image.NRGBA{
   508  				Rect:   image.Rect(-1, -1, 3, 3),
   509  				Stride: 4 * 4,
   510  				Pix: []uint8{
   511  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   512  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   513  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   514  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   515  				},
   516  			},
   517  			2, 2,
   518  			Center,
   519  			NearestNeighbor,
   520  			&image.NRGBA{
   521  				Rect:   image.Rect(0, 0, 2, 2),
   522  				Stride: 2 * 4,
   523  				Pix: []uint8{
   524  					0x14, 0x15, 0x16, 0x17, 0x1c, 0x1d, 0x1e, 0x1f,
   525  					0x34, 0x35, 0x36, 0x37, 0x3c, 0x3d, 0x3e, 0x3f,
   526  				},
   527  			},
   528  		},
   529  		{
   530  			"resizeAndCrop 4x4 1x4 TopLeft Nearest",
   531  			&image.NRGBA{
   532  				Rect:   image.Rect(-1, -1, 3, 3),
   533  				Stride: 4 * 4,
   534  				Pix: []uint8{
   535  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   536  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   537  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   538  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   539  				},
   540  			},
   541  			1, 4,
   542  			TopLeft,
   543  			NearestNeighbor,
   544  			&image.NRGBA{
   545  				Rect:   image.Rect(0, 0, 1, 4),
   546  				Stride: 1 * 4,
   547  				Pix: []uint8{
   548  					0x00, 0x01, 0x02, 0x03,
   549  					0x10, 0x11, 0x12, 0x13,
   550  					0x20, 0x21, 0x22, 0x23,
   551  					0x30, 0x31, 0x32, 0x33,
   552  				},
   553  			},
   554  		},
   555  		{
   556  			"resizeAndCrop 4x4 8x2 Bottom Nearest",
   557  			&image.NRGBA{
   558  				Rect:   image.Rect(-1, -1, 3, 3),
   559  				Stride: 4 * 4,
   560  				Pix: []uint8{
   561  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   562  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   563  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   564  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   565  				},
   566  			},
   567  			8, 2,
   568  			Bottom,
   569  			NearestNeighbor,
   570  			&image.NRGBA{
   571  				Rect:   image.Rect(0, 0, 8, 2),
   572  				Stride: 8 * 4,
   573  				Pix: []uint8{
   574  					0x30, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3c, 0x3d, 0x3e, 0x3f,
   575  					0x30, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3c, 0x3d, 0x3e, 0x3f,
   576  				},
   577  			},
   578  		},
   579  		{
   580  			"resizeAndCrop 4x4 2x8 Top Nearest",
   581  			&image.NRGBA{
   582  				Rect:   image.Rect(-1, -1, 3, 3),
   583  				Stride: 4 * 4,
   584  				Pix: []uint8{
   585  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   586  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   587  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   588  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   589  				},
   590  			},
   591  			2, 8,
   592  			Top,
   593  			NearestNeighbor,
   594  			&image.NRGBA{
   595  				Rect:   image.Rect(0, 0, 2, 8),
   596  				Stride: 2 * 4,
   597  				Pix: []uint8{
   598  					0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
   599  					0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
   600  					0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
   601  					0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
   602  					0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
   603  					0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
   604  					0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
   605  					0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
   606  				},
   607  			},
   608  		},
   609  		{
   610  			"resizeAndCrop 4x4 4x4 TopRight Box",
   611  			&image.NRGBA{
   612  				Rect:   image.Rect(-1, -1, 3, 3),
   613  				Stride: 4 * 4,
   614  				Pix: []uint8{
   615  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   616  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   617  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   618  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   619  				},
   620  			},
   621  			4, 4,
   622  			TopRight,
   623  			Box,
   624  			&image.NRGBA{
   625  				Rect:   image.Rect(0, 0, 4, 4),
   626  				Stride: 4 * 4,
   627  				Pix: []uint8{
   628  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   629  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   630  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   631  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   632  				},
   633  			},
   634  		},
   635  	}
   636  	for _, tc := range testCases {
   637  		t.Run(tc.name, func(t *testing.T) {
   638  			got := resizeAndCrop(tc.src, tc.w, tc.h, tc.a, tc.f)
   639  			if !compareNRGBA(got, tc.want, 0) {
   640  				t.Fatalf("got result %#v want %#v", got, tc.want)
   641  			}
   642  		})
   643  	}
   644  }
   645  
   646  func TestCropAndResize(t *testing.T) {
   647  	testCases := []struct {
   648  		name string
   649  		src  image.Image
   650  		w, h int
   651  		a    Anchor
   652  		f    ResampleFilter
   653  		want *image.NRGBA
   654  	}{
   655  		{
   656  			"cropAndResize 4x4 2x2 Center Nearest",
   657  			&image.NRGBA{
   658  				Rect:   image.Rect(-1, -1, 3, 3),
   659  				Stride: 4 * 4,
   660  				Pix: []uint8{
   661  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   662  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   663  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   664  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   665  				},
   666  			},
   667  			2, 2,
   668  			Center,
   669  			NearestNeighbor,
   670  			&image.NRGBA{
   671  				Rect:   image.Rect(0, 0, 2, 2),
   672  				Stride: 2 * 4,
   673  				Pix: []uint8{
   674  					0x14, 0x15, 0x16, 0x17, 0x1c, 0x1d, 0x1e, 0x1f,
   675  					0x34, 0x35, 0x36, 0x37, 0x3c, 0x3d, 0x3e, 0x3f,
   676  				},
   677  			},
   678  		},
   679  		{
   680  			"cropAndResize 4x4 1x4 TopLeft Nearest",
   681  			&image.NRGBA{
   682  				Rect:   image.Rect(-1, -1, 3, 3),
   683  				Stride: 4 * 4,
   684  				Pix: []uint8{
   685  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   686  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   687  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   688  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   689  				},
   690  			},
   691  			1, 4,
   692  			TopLeft,
   693  			NearestNeighbor,
   694  			&image.NRGBA{
   695  				Rect:   image.Rect(0, 0, 1, 4),
   696  				Stride: 1 * 4,
   697  				Pix: []uint8{
   698  					0x00, 0x01, 0x02, 0x03,
   699  					0x10, 0x11, 0x12, 0x13,
   700  					0x20, 0x21, 0x22, 0x23,
   701  					0x30, 0x31, 0x32, 0x33,
   702  				},
   703  			},
   704  		},
   705  		{
   706  			"cropAndResize 4x4 8x2 Bottom Nearest",
   707  			&image.NRGBA{
   708  				Rect:   image.Rect(-1, -1, 3, 3),
   709  				Stride: 4 * 4,
   710  				Pix: []uint8{
   711  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   712  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   713  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   714  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   715  				},
   716  			},
   717  			8, 2,
   718  			Bottom,
   719  			NearestNeighbor,
   720  			&image.NRGBA{
   721  				Rect:   image.Rect(0, 0, 8, 2),
   722  				Stride: 8 * 4,
   723  				Pix: []uint8{
   724  					0x30, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3c, 0x3d, 0x3e, 0x3f,
   725  					0x30, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3c, 0x3d, 0x3e, 0x3f,
   726  				},
   727  			},
   728  		},
   729  		{
   730  			"cropAndResize 4x4 2x8 Top Nearest",
   731  			&image.NRGBA{
   732  				Rect:   image.Rect(-1, -1, 3, 3),
   733  				Stride: 4 * 4,
   734  				Pix: []uint8{
   735  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   736  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   737  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   738  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   739  				},
   740  			},
   741  			2, 8,
   742  			Top,
   743  			NearestNeighbor,
   744  			&image.NRGBA{
   745  				Rect:   image.Rect(0, 0, 2, 8),
   746  				Stride: 2 * 4,
   747  				Pix: []uint8{
   748  					0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07,
   749  					0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07,
   750  					0x14, 0x15, 0x16, 0x17, 0x14, 0x15, 0x16, 0x17,
   751  					0x14, 0x15, 0x16, 0x17, 0x14, 0x15, 0x16, 0x17,
   752  					0x24, 0x25, 0x26, 0x27, 0x24, 0x25, 0x26, 0x27,
   753  					0x24, 0x25, 0x26, 0x27, 0x24, 0x25, 0x26, 0x27,
   754  					0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37,
   755  					0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37,
   756  				},
   757  			},
   758  		},
   759  		{
   760  			"cropAndResize 4x4 4x4 TopRight Box",
   761  			&image.NRGBA{
   762  				Rect:   image.Rect(-1, -1, 3, 3),
   763  				Stride: 4 * 4,
   764  				Pix: []uint8{
   765  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   766  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   767  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   768  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   769  				},
   770  			},
   771  			4, 4,
   772  			TopRight,
   773  			Box,
   774  			&image.NRGBA{
   775  				Rect:   image.Rect(0, 0, 4, 4),
   776  				Stride: 4 * 4,
   777  				Pix: []uint8{
   778  					0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   779  					0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   780  					0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   781  					0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   782  				},
   783  			},
   784  		},
   785  	}
   786  	for _, tc := range testCases {
   787  		t.Run(tc.name, func(t *testing.T) {
   788  			got := cropAndResize(tc.src, tc.w, tc.h, tc.a, tc.f)
   789  			if !compareNRGBA(got, tc.want, 0) {
   790  				t.Fatalf("got result %#v want %#v", got, tc.want)
   791  			}
   792  		})
   793  	}
   794  }
   795  
   796  func TestThumbnail(t *testing.T) {
   797  	testCases := []struct {
   798  		name string
   799  		src  image.Image
   800  		w, h int
   801  		f    ResampleFilter
   802  		want *image.NRGBA
   803  	}{
   804  		{
   805  			"Thumbnail 6x2 1x1 box",
   806  			&image.NRGBA{
   807  				Rect:   image.Rect(-1, -1, 5, 1),
   808  				Stride: 6 * 4,
   809  				Pix: []uint8{
   810  					0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   811  					0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   812  				},
   813  			},
   814  			1, 1,
   815  			Box,
   816  			&image.NRGBA{
   817  				Rect:   image.Rect(0, 0, 1, 1),
   818  				Stride: 1 * 4,
   819  				Pix:    []uint8{0x55, 0x55, 0x55, 0xc0},
   820  			},
   821  		},
   822  		{
   823  			"Thumbnail 2x6 1x1 box",
   824  			&image.NRGBA{
   825  				Rect:   image.Rect(-1, -1, 1, 5),
   826  				Stride: 2 * 4,
   827  				Pix: []uint8{
   828  					0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   829  					0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   830  					0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
   831  					0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
   832  					0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   833  					0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   834  				},
   835  			},
   836  			1, 1,
   837  			Box,
   838  			&image.NRGBA{
   839  				Rect:   image.Rect(0, 0, 1, 1),
   840  				Stride: 1 * 4,
   841  				Pix:    []uint8{0x55, 0x55, 0x55, 0xc0},
   842  			},
   843  		},
   844  		{
   845  			"Thumbnail 1x3 2x2 box",
   846  			&image.NRGBA{
   847  				Rect:   image.Rect(-1, -1, 0, 2),
   848  				Stride: 1 * 4,
   849  				Pix: []uint8{
   850  					0x00, 0x00, 0x00, 0x00,
   851  					0xff, 0x00, 0x00, 0xff,
   852  					0xff, 0xff, 0xff, 0xff,
   853  				},
   854  			},
   855  			2, 2,
   856  			Box,
   857  			&image.NRGBA{
   858  				Rect:   image.Rect(0, 0, 2, 2),
   859  				Stride: 2 * 4,
   860  				Pix: []uint8{
   861  					0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
   862  					0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
   863  				},
   864  			},
   865  		},
   866  	}
   867  	for _, tc := range testCases {
   868  		t.Run(tc.name, func(t *testing.T) {
   869  			got := Thumbnail(tc.src, tc.w, tc.h, tc.f)
   870  			if !compareNRGBA(got, tc.want, 0) {
   871  				t.Fatalf("got result %#v want %#v", got, tc.want)
   872  			}
   873  		})
   874  	}
   875  }
   876  
   877  func BenchmarkResize(b *testing.B) {
   878  	for _, dir := range []string{"Down", "Up"} {
   879  		for _, filter := range []string{"NearestNeighbor", "Linear", "CatmullRom", "Lanczos"} {
   880  			for _, format := range []string{"JPEG", "PNG"} {
   881  				var size int
   882  				switch dir {
   883  				case "Down":
   884  					size = 100
   885  				case "Up":
   886  					size = 1000
   887  				}
   888  
   889  				var f ResampleFilter
   890  				switch filter {
   891  				case "NearestNeighbor":
   892  					f = NearestNeighbor
   893  				case "Linear":
   894  					f = Linear
   895  				case "CatmullRom":
   896  					f = CatmullRom
   897  				case "Lanczos":
   898  					f = Lanczos
   899  				}
   900  
   901  				var img image.Image
   902  				switch format {
   903  				case "JPEG":
   904  					img = testdataBranchesJPG
   905  				case "PNG":
   906  					img = testdataBranchesPNG
   907  				}
   908  
   909  				b.Run(fmt.Sprintf("%s %s %s", dir, filter, format), func(b *testing.B) {
   910  					b.ReportAllocs()
   911  					for i := 0; i < b.N; i++ {
   912  						Resize(img, size, size, f)
   913  					}
   914  				})
   915  			}
   916  		}
   917  	}
   918  }
   919  
   920  func BenchmarkFill(b *testing.B) {
   921  	for _, dir := range []string{"Vertical", "Horizontal"} {
   922  		for _, filter := range []string{"NearestNeighbor", "Linear", "CatmullRom", "Lanczos"} {
   923  			for _, format := range []string{"JPEG", "PNG"} {
   924  				var width, height int
   925  				switch dir {
   926  				case "Vertical":
   927  					width = 100
   928  					height = 1000
   929  				case "Horizontal":
   930  					width = 1000
   931  					height = 100
   932  				}
   933  
   934  				var f ResampleFilter
   935  				switch filter {
   936  				case "NearestNeighbor":
   937  					f = NearestNeighbor
   938  				case "Linear":
   939  					f = Linear
   940  				case "CatmullRom":
   941  					f = CatmullRom
   942  				case "Lanczos":
   943  					f = Lanczos
   944  				}
   945  
   946  				var img image.Image
   947  				switch format {
   948  				case "JPEG":
   949  					img = testdataBranchesJPG
   950  				case "PNG":
   951  					img = testdataBranchesPNG
   952  				}
   953  
   954  				b.Run(fmt.Sprintf("%s %s %s", dir, filter, format), func(b *testing.B) {
   955  					b.ReportAllocs()
   956  					for i := 0; i < b.N; i++ {
   957  						Fill(img, width, height, Center, f)
   958  					}
   959  				})
   960  			}
   961  		}
   962  	}
   963  }