package main import ( "bytes" "image" "image/jpeg" "testing" ) // testPhoto returns a JPEG-decoded (so *image.YCbCr, 4:2:0) image with an odd // size and a non-zero origin to exercise the plane offset arithmetic. func testPhoto(t testing.TB, w, h int) *image.YCbCr { t.Helper() src := image.NewRGBA(image.Rect(0, 0, w, h)) for i := range src.Pix { src.Pix[i] = uint8(i*7 + i/w) } var buf bytes.Buffer if err := jpeg.Encode(&buf, src, &jpeg.Options{Quality: 90}); err != nil { t.Fatal(err) } img, err := jpeg.Decode(&buf) if err != nil { t.Fatal(err) } return img.(*image.YCbCr).SubImage(image.Rect(3, 5, w, h)).(*image.YCbCr) } func TestResizeBoxYCbCrMatchesGeneric(t *testing.T) { src := testPhoto(t, 1001, 667) fast := resizeBox(src, 120).(*image.RGBA) // Hide the concrete type so resizeBox takes the generic At() path. slow := resizeBox(struct{ image.Image }{src}, 120).(*image.RGBA) if fast.Bounds() != slow.Bounds() { t.Fatalf("bounds %v != %v", fast.Bounds(), slow.Bounds()) } for i := range fast.Pix { if fast.Pix[i] != slow.Pix[i] { t.Fatalf("pixel byte %d: fast %d, generic %d", i, fast.Pix[i], slow.Pix[i]) } } } func BenchmarkResizeBox(b *testing.B) { src := testPhoto(b, 4000, 3000) b.Run("ycbcr", func(b *testing.B) { for i := 0; i < b.N; i++ { resizeBox(src, 300) } }) b.Run("generic", func(b *testing.B) { for i := 0; i < b.N; i++ { resizeBox(struct{ image.Image }{src}, 300) } }) }