Repository: go
Issue: image: optimize Image.At().RGBA()
Labels: Performance

In the Go standard library (and x/image), we can see several calls that look like `Image.At().RGBA()`.
These calls mostly happen in y/x loops.
They are slow because they allocate memory.

I have written a library that speeds up `Image.At().RGBA()`.
It is available on https://github.com/pierrre/imageutil

If you call https://godoc.org/github.com/pierrre/imageutil#NewAtFunc with an image, it returns a https://godoc.org/github.com/pierrre/imageutil#AtFunc
A `AtFunc` returns the RGBA value (uint32) for a given pixel (x/y).
A call to `NewAtFunc()` allocates memory, but it only happens 1 time per image.
A call to a `AtFunc` doesn't allocate memory (most of the time).

There is also `NewSetFunc()` that helps to set RGBA values to an image.
It works the same way.

My code is just a copy/paste of the Go standard library, but organized differently.

Benchmarks!

I've written benchmarks for "encode" functions.
It only tests blank images, but it will give you an idea.

``` go
package benchimageencode

import (
    "bytes"
    "image"
    "image/color"
    "image/gif"
    "image/jpeg"
    "image/png"
    "io"
    "strconv"
    "testing"

    "golang.org/x/image/bmp"
    "golang.org/x/image/tiff"
)

func Benchmark(b *testing.B) {
    buf := new(bytes.Buffer)
    for _, tcEnc := range []struct {
        name string
        enc  func(w io.Writer, im image.Image) error
    }{
        {
            "JPEG",
            func(w io.Writer, im image.Image) error {
                return jpeg.Encode(w, im, nil)
            },
        },
        {"PNG", png.Encode},
        {
            "GIF",
            func(w io.Writer, im image.Image) error {
                return gif.Encode(w, im, nil)
            },
        },
        {"BMP", bmp.Encode},
        {
            "TIFF",
            func(w io.Writer, im image.Image) error {
                return tiff.Encode(w, im, nil)
            },
        },
    } {
        b.Run(tcEnc.name, func(b *testing.B) {
            for _, tcIm := range []struct {
                name     string
                newImage func(image.Rectangle) image.Image
            }{
                {
                    "RGBA",
                    func(r image.Rectangle) image.Image {
                        return image.NewRGBA(r)
                    },
                },
                {
                    "RGBA64",
                    func(r image.Rectangle) image.Image {
                        return image.NewRGBA64(r)
                    },
                },
                {
                    "NRGBA",
                    func(r image.Rectangle) image.Image {
                        return image.NewNRGBA(r)
                    },
                },
                {
                    "NRGBA64",
                    func(r image.Rectangle) image.Image {
                        return image.NewNRGBA64(r)
                    },
                },
                {
                    "Alpha",
                    func(r image.Rectangle) image.Image {
                        return image.NewAlpha(r)
                    },
                },
                {
                    "Alpha16",
                    func(r image.Rectangle) image.Image {
                        return image.NewAlpha16(r)
                    },
                },
                {
                    "Gray",
                    func(r image.Rectangle) image.Image {
                        return image.NewGray(r)
                    },
                },
                {
                    "Gray16",
                    func(r image.Rectangle) image.Image {
                        return image.NewGray16(r)
                    },
                },
                {
                    "Paletted",
                    func(r image.Rectangle) image.Image {
                        return image.NewPaletted(r, color.Palette{
                            color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xFF},
                            color.RGBA{R: 0xFF, G: 0x00, B: 0x00, A: 0xFF},
                            color.RGBA{R: 0x00, G: 0xFF, B: 0x00, A: 0xFF},
                            color.RGBA{R: 0x00, G: 0x00, B: 0xFF, A: 0xFF},
                        })
                    },
                },
                {
                    "YCbCr",
                    func(r image.Rectangle) image.Image {
                        return image.NewYCbCr(r, image.YCbCrSubsampleRatio444)
                    },
                },
                {
                    "NYCbCrA",
                    func(r image.Rectangle) image.Image {
                        return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio444)
                    },
                },
                {
                    "CMYK",
                    func(r image.Rectangle) image.Image {
                        return image.NewCMYK(r)
                    },
                },
            } {
                b.Run(tcIm.name, func(b *testing.B) {
                    for _, size := range []int{
                        10, 100, 1000,
                    } {
                        im := tcIm.newImage(image.Rect(0, 0, size, size))
                        b.Run(strconv.Itoa(size), func(b *testing.B) {
                            for i := 0; i < b.N; i++ {
                                buf.Reset()
                                err := tcEnc.enc(buf, im)
                                if err != nil {
                                    b.Fatal(err)
                                }
                            }
                        })
                    }
                })
            }
        })
    }
}
```

Results:

```
benchmark                          old ns/op      new ns/op      delta
Benchmark/JPEG/RGBA/10-8           6891           6922           +0.45%
Benchmark/JPEG/RGBA/100-8          243797         226064         -7.27%
Benchmark/JPEG/RGBA/1000-8         18211697       18183751       -0.15%
Benchmark/JPEG/RGBA64/10-8         15505          8078           -47.90%
Benchmark/JPEG/RGBA64/100-8        654661         284739         -56.51%
Benchmark/JPEG/RGBA64/1000-8       51987889       22906425       -55.94%
Benchmark/JPEG/NRGBA/10-8          15891          7327           -53.89%
Benchmark/JPEG/NRGBA/100-8         646659         257388         -60.20%
Benchmark/JPEG/NRGBA/1000-8        53610219       20396700       -61.95%
Benchmark/JPEG/NRGBA64/10-8        16586          7310           -55.93%
Benchmark/JPEG/NRGBA64/100-8       718770         256065         -64.37%
Benchmark/JPEG/NRGBA64/1000-8      55099237       20160389       -63.41%
Benchmark/JPEG/Alpha/10-8          13366          7624           -42.96%
Benchmark/JPEG/Alpha/100-8         535532         274982         -48.65%
Benchmark/JPEG/Alpha/1000-8        43495216       21314882       -50.99%
Benchmark/JPEG/Alpha16/10-8        14041          7849           -44.10%
Benchmark/JPEG/Alpha16/100-8       567633         271382         -52.19%
Benchmark/JPEG/Alpha16/1000-8      46175342       21845906       -52.69%
Benchmark/JPEG/Gray/10-8           4124           4114           -0.24%
Benchmark/JPEG/Gray/100-8          80502          81061          +0.69%
Benchmark/JPEG/Gray/1000-8         7237756        7227977        -0.14%
Benchmark/JPEG/Gray16/10-8         13816          7688           -44.35%
Benchmark/JPEG/Gray16/100-8        565986         273270         -51.72%
Benchmark/JPEG/Gray16/1000-8       46435379       21609969       -53.46%
Benchmark/JPEG/Paletted/10-8       9504           7861           -17.29%
Benchmark/JPEG/Paletted/100-8      339095         277612         -18.13%
Benchmark/JPEG/Paletted/1000-8     27374214       22215206       -18.85%
Benchmark/JPEG/YCbCr/10-8          16747          8353           -50.12%
Benchmark/JPEG/YCbCr/100-8         693129         293951         -57.59%
Benchmark/JPEG/YCbCr/1000-8        56055246       23340037       -58.36%
Benchmark/JPEG/NYCbCrA/10-8        17758          9100           -48.76%
Benchmark/JPEG/NYCbCrA/100-8       753606         331801         -55.97%
Benchmark/JPEG/NYCbCrA/1000-8      61176716       27043470       -55.79%
Benchmark/JPEG/CMYK/10-8           16301          8968           -44.98%
Benchmark/JPEG/CMYK/100-8          664311         332938         -49.88%
Benchmark/JPEG/CMYK/1000-8         53249646       26513162       -50.21%
Benchmark/PNG/RGBA/10-8            233825         234277         +0.19%
Benchmark/PNG/RGBA/100-8           1318376        1244438        -5.61%
Benchmark/PNG/RGBA/1000-8          87804961       87500804       -0.35%
Benchmark/PNG/RGBA64/10-8          234305         241012         +2.86%
Benchmark/PNG/RGBA64/100-8         1560487        1571785        +0.72%
Benchmark/PNG/RGBA64/1000-8        116953559      115641713      -1.12%
Benchmark/PNG/NRGBA/10-8           224863         215643         -4.10%
Benchmark/PNG/NRGBA/100-8          543683         477847         -12.11%
Benchmark/PNG/NRGBA/1000-8         22236178       22087216       -0.67%
Benchmark/PNG/NRGBA64/10-8         278971         229319         -17.80%
Benchmark/PNG/NRGBA64/100-8        1338571        1344189        +0.42%
Benchmark/PNG/NRGBA64/1000-8       94600702       92419064       -2.31%
Benchmark/PNG/Alpha/10-8           226913         235867         +3.95%
Benchmark/PNG/Alpha/100-8          1237592        1212220        -2.05%
Benchmark/PNG/Alpha/1000-8         87412677       86772330       -0.73%
Benchmark/PNG/Alpha16/10-8         238503         230353         -3.42%
Benchmark/PNG/Alpha16/100-8        1534150        1577323        +2.81%
Benchmark/PNG/Alpha16/1000-8       114207844      113559204      -0.57%
Benchmark/PNG/Gray/10-8            240275         224893         -6.40%
Benchmark/PNG/Gray/100-8           349896         319882         -8.58%
Benchmark/PNG/Gray/1000-8          5872431        5918043        +0.78%
Benchmark/PNG/Gray16/10-8          232315         219746         -5.41%
Benchmark/PNG/Gray16/100-8         856544         922971         +7.76%
Benchmark/PNG/Gray16/1000-8        51153358       50292261       -1.68%
Benchmark/PNG/Paletted/10-8        222739         229109         +2.86%
Benchmark/PNG/Paletted/100-8       320867         322279         +0.44%
Benchmark/PNG/Paletted/1000-8      5880143        5995715        +1.97%
Benchmark/PNG/YCbCr/10-8           264396         229815         -13.08%
Benchmark/PNG/YCbCr/100-8          1119731        944250         -15.67%
Benchmark/PNG/YCbCr/1000-8         72874727       42894471       -41.14%
Benchmark/PNG/NYCbCrA/10-8         254977         239658         -6.01%
Benchmark/PNG/NYCbCrA/100-8        1646790        1662818        +0.97%
Benchmark/PNG/NYCbCrA/1000-8       126894096      125769798      -0.89%
Benchmark/PNG/CMYK/10-8            288477         227636         -21.09%
Benchmark/PNG/CMYK/100-8           1050239        883844         -15.84%
Benchmark/PNG/CMYK/1000-8          68309463       42997860       -37.05%
Benchmark/BMP/RGBA/10-8            2357           2337           -0.85%
Benchmark/BMP/RGBA/100-8           19857          19835          -0.11%
Benchmark/BMP/RGBA/1000-8          1699880        1658537        -2.43%
Benchmark/BMP/RGBA64/10-8          5892           2893           -50.90%
Benchmark/BMP/RGBA64/100-8         370764         72362          -80.48%
Benchmark/BMP/RGBA64/1000-8        37558621       6772522        -81.97%
Benchmark/BMP/NRGBA/10-8           5587           2754           -50.71%
Benchmark/BMP/NRGBA/100-8          330937         57430          -82.65%
Benchmark/BMP/NRGBA/1000-8         32697775       5413184        -83.44%
Benchmark/BMP/NRGBA64/10-8         6067           2779           -54.19%
Benchmark/BMP/NRGBA64/100-8        379282         59023          -84.44%
Benchmark/BMP/NRGBA64/1000-8       36784396       5547886        -84.92%
Benchmark/BMP/Alpha/10-8           4947           2691           -45.60%
Benchmark/BMP/Alpha/100-8          268719         54878          -79.58%
Benchmark/BMP/Alpha/1000-8         26591321       5049983        -81.01%
Benchmark/BMP/Alpha16/10-8         5236           2747           -47.54%
Benchmark/BMP/Alpha16/100-8        290536         57670          -80.15%
Benchmark/BMP/Alpha16/1000-8       28806912       5421961        -81.18%
Benchmark/BMP/Gray/10-8            3576           3575           -0.03%
Benchmark/BMP/Gray/100-8           4829           4768           -1.26%
Benchmark/BMP/Gray/1000-8          58899          57669          -2.09%
Benchmark/BMP/Gray16/10-8          5166           2781           -46.17%
Benchmark/BMP/Gray16/100-8         287760         57665          -79.96%
Benchmark/BMP/Gray16/1000-8        28462012       5463188        -80.81%
Benchmark/BMP/Paletted/10-8        3210           3358           +4.61%
Benchmark/BMP/Paletted/100-8       4386           4546           +3.65%
Benchmark/BMP/Paletted/1000-8      58090          58225          +0.23%
Benchmark/BMP/YCbCr/10-8           6046           2999           -50.40%
Benchmark/BMP/YCbCr/100-8          387509         79009          -79.61%
Benchmark/BMP/YCbCr/1000-8         38474751       7584745        -80.29%
Benchmark/BMP/NYCbCrA/10-8         6739           3387           -49.74%
Benchmark/BMP/NYCbCrA/100-8        462438         116874         -74.73%
Benchmark/BMP/NYCbCrA/1000-8       45898191       11495621       -74.95%
Benchmark/BMP/CMYK/10-8            5594           3105           -44.49%
Benchmark/BMP/CMYK/100-8           339544         90794          -73.26%
Benchmark/BMP/CMYK/1000-8          33004703       8738049        -73.52%
Benchmark/TIFF/RGBA/10-8           2312           2509           +8.52%
Benchmark/TIFF/RGBA/100-8          4122           3509           -14.87%
Benchmark/TIFF/RGBA/1000-8         295062         288624         -2.18%
Benchmark/TIFF/RGBA64/10-8         2698           2657           -1.52%
Benchmark/TIFF/RGBA64/100-8        63975          65120          +1.79%
Benchmark/TIFF/RGBA64/1000-8       6303790        6177960        -2.00%
Benchmark/TIFF/NRGBA/10-8          1867           1850           -0.91%
Benchmark/TIFF/NRGBA/100-8         2997           3031           +1.13%
Benchmark/TIFF/NRGBA/1000-8        293275         297403         +1.41%
Benchmark/TIFF/NRGBA64/10-8        2641           2737           +3.63%
Benchmark/TIFF/NRGBA64/100-8       64303          64035          -0.42%
Benchmark/TIFF/NRGBA64/1000-8      6227868        6260150        +0.52%
Benchmark/TIFF/Alpha/10-8          4791           2631           -45.08%
Benchmark/TIFF/Alpha/100-8         270968         60194          -77.79%
Benchmark/TIFF/Alpha/1000-8        26615543       5647306        -78.78%
Benchmark/TIFF/Alpha16/10-8        5037           2701           -46.38%
Benchmark/TIFF/Alpha16/100-8       293523         68395          -76.70%
Benchmark/TIFF/Alpha16/1000-8      29014088       6497133        -77.61%
Benchmark/TIFF/Gray/10-8           1481           1431           -3.38%
Benchmark/TIFF/Gray/100-8          1652           1657           +0.30%
Benchmark/TIFF/Gray/1000-8         36243          38499          +6.22%
Benchmark/TIFF/Gray16/10-8         1728           1826           +5.67%
Benchmark/TIFF/Gray16/100-8        19916          20041          +0.63%
Benchmark/TIFF/Gray16/1000-8       1682497        1682254        -0.01%
Benchmark/TIFF/Paletted/10-8       4276           4374           +2.29%
Benchmark/TIFF/Paletted/100-8      4759           4690           -1.45%
Benchmark/TIFF/Paletted/1000-8     39673          39281          -0.99%
Benchmark/TIFF/YCbCr/10-8          5862           2863           -51.16%
Benchmark/TIFF/YCbCr/100-8         383112         90709          -76.32%
Benchmark/TIFF/YCbCr/1000-8        37969567       8576337        -77.41%
Benchmark/TIFF/NYCbCrA/10-8        6511           3511           -46.08%
Benchmark/TIFF/NYCbCrA/100-8       454029         125287         -72.41%
Benchmark/TIFF/NYCbCrA/1000-8      45109329       11977360       -73.45%
Benchmark/TIFF/CMYK/10-8           5431           3017           -44.45%
Benchmark/TIFF/CMYK/100-8          331066         96960          -70.71%
Benchmark/TIFF/CMYK/1000-8         33648362       9402967        -72.06%

benchmark                          old allocs     new allocs     delta
Benchmark/JPEG/RGBA/10-8           4              5              +25.00%
Benchmark/JPEG/RGBA/100-8          4              5              +25.00%
Benchmark/JPEG/RGBA/1000-8         4              5              +25.00%
Benchmark/JPEG/RGBA64/10-8         260            5              -98.08%
Benchmark/JPEG/RGBA64/100-8        12548          5              -99.96%
Benchmark/JPEG/RGBA64/1000-8       1016068        5              -100.00%
Benchmark/JPEG/NRGBA/10-8          260            5              -98.08%
Benchmark/JPEG/NRGBA/100-8         12548          5              -99.96%
Benchmark/JPEG/NRGBA/1000-8        1016068        5              -100.00%
Benchmark/JPEG/NRGBA64/10-8        260            5              -98.08%
Benchmark/JPEG/NRGBA64/100-8       12548          5              -99.96%
Benchmark/JPEG/NRGBA64/1000-8      1016068        5              -100.00%
Benchmark/JPEG/Alpha/10-8          260            5              -98.08%
Benchmark/JPEG/Alpha/100-8         12548          5              -99.96%
Benchmark/JPEG/Alpha/1000-8        1016068        5              -100.00%
Benchmark/JPEG/Alpha16/10-8        260            5              -98.08%
Benchmark/JPEG/Alpha16/100-8       12548          5              -99.96%
Benchmark/JPEG/Alpha16/1000-8      1016068        5              -100.00%
Benchmark/JPEG/Gray/10-8           4              4              +0.00%
Benchmark/JPEG/Gray/100-8          4              4              +0.00%
Benchmark/JPEG/Gray/1000-8         4              4              +0.00%
Benchmark/JPEG/Gray16/10-8         260            5              -98.08%
Benchmark/JPEG/Gray16/100-8        12548          5              -99.96%
Benchmark/JPEG/Gray16/1000-8       1016068        5              -100.00%
Benchmark/JPEG/Paletted/10-8       4              6              +50.00%
Benchmark/JPEG/Paletted/100-8      4              6              +50.00%
Benchmark/JPEG/Paletted/1000-8     4              6              +50.00%
Benchmark/JPEG/YCbCr/10-8          260            5              -98.08%
Benchmark/JPEG/YCbCr/100-8         12548          5              -99.96%
Benchmark/JPEG/YCbCr/1000-8        1016068        5              -100.00%
Benchmark/JPEG/NYCbCrA/10-8        260            5              -98.08%
Benchmark/JPEG/NYCbCrA/100-8       12548          5              -99.96%
Benchmark/JPEG/NYCbCrA/1000-8      1016068        5              -100.00%
Benchmark/JPEG/CMYK/10-8           260            5              -98.08%
Benchmark/JPEG/CMYK/100-8          12548          5              -99.96%
Benchmark/JPEG/CMYK/1000-8         1016068        5              -100.00%
Benchmark/PNG/RGBA/10-8            232            233            +0.43%
Benchmark/PNG/RGBA/100-8           20032          20033          +0.00%
Benchmark/PNG/RGBA/1000-8          2000032        2000033        +0.00%
Benchmark/PNG/RGBA64/10-8          232            233            +0.43%
Benchmark/PNG/RGBA64/100-8         20032          20033          +0.00%
Benchmark/PNG/RGBA64/1000-8        2000032        2000033        +0.00%
Benchmark/PNG/NRGBA/10-8           32             33             +3.12%
Benchmark/PNG/NRGBA/100-8          32             33             +3.12%
Benchmark/PNG/NRGBA/1000-8         32             33             +3.12%
Benchmark/PNG/NRGBA64/10-8         132            133            +0.76%
Benchmark/PNG/NRGBA64/100-8        10032          10033          +0.01%
Benchmark/PNG/NRGBA64/1000-8       1000032        1000033        +0.00%
Benchmark/PNG/Alpha/10-8           232            233            +0.43%
Benchmark/PNG/Alpha/100-8          20032          20033          +0.00%
Benchmark/PNG/Alpha/1000-8         2000032        2000033        +0.00%
Benchmark/PNG/Alpha16/10-8         232            233            +0.43%
Benchmark/PNG/Alpha16/100-8        20032          20033          +0.00%
Benchmark/PNG/Alpha16/1000-8       2000032        2000033        +0.00%
Benchmark/PNG/Gray/10-8            32             33             +3.12%
Benchmark/PNG/Gray/100-8           32             33             +3.12%
Benchmark/PNG/Gray/1000-8          32             33             +3.12%
Benchmark/PNG/Gray16/10-8          132            133            +0.76%
Benchmark/PNG/Gray16/100-8         10032          10033          +0.01%
Benchmark/PNG/Gray16/1000-8        1000032        1000033        +0.00%
Benchmark/PNG/Paletted/10-8        38             40             +5.26%
Benchmark/PNG/Paletted/100-8       38             40             +5.26%
Benchmark/PNG/Paletted/1000-8      38             40             +5.26%
Benchmark/PNG/YCbCr/10-8           132            33             -75.00%
Benchmark/PNG/YCbCr/100-8          10032          33             -99.67%
Benchmark/PNG/YCbCr/1000-8         1000032        33             -100.00%
Benchmark/PNG/NYCbCrA/10-8         232            233            +0.43%
Benchmark/PNG/NYCbCrA/100-8        20032          20033          +0.00%
Benchmark/PNG/NYCbCrA/1000-8       2000032        2000033        +0.00%
Benchmark/PNG/CMYK/10-8            132            33             -75.00%
Benchmark/PNG/CMYK/100-8           10032          33             -99.67%
Benchmark/PNG/CMYK/1000-8          1000032        33             -100.00%
Benchmark/BMP/RGBA/10-8            33             33             +0.00%
Benchmark/BMP/RGBA/100-8           33             33             +0.00%
Benchmark/BMP/RGBA/1000-8          33             33             +0.00%
Benchmark/BMP/RGBA64/10-8          133            34             -74.44%
Benchmark/BMP/RGBA64/100-8         10033          34             -99.66%
Benchmark/BMP/RGBA64/1000-8        1000033        34             -100.00%
Benchmark/BMP/NRGBA/10-8           133            34             -74.44%
Benchmark/BMP/NRGBA/100-8          10033          34             -99.66%
Benchmark/BMP/NRGBA/1000-8         1000033        34             -100.00%
Benchmark/BMP/NRGBA64/10-8         133            34             -74.44%
Benchmark/BMP/NRGBA64/100-8        10033          34             -99.66%
Benchmark/BMP/NRGBA64/1000-8       1000033        34             -100.00%
Benchmark/BMP/Alpha/10-8           133            34             -74.44%
Benchmark/BMP/Alpha/100-8          10033          34             -99.66%
Benchmark/BMP/Alpha/1000-8         1000033        34             -100.00%
Benchmark/BMP/Alpha16/10-8         133            34             -74.44%
Benchmark/BMP/Alpha16/100-8        10033          34             -99.66%
Benchmark/BMP/Alpha16/1000-8       1000033        34             -100.00%
Benchmark/BMP/Gray/10-8            37             37             +0.00%
Benchmark/BMP/Gray/100-8           36             36             +0.00%
Benchmark/BMP/Gray/1000-8          36             36             +0.00%
Benchmark/BMP/Gray16/10-8          133            34             -74.44%
Benchmark/BMP/Gray16/100-8         10033          34             -99.66%
Benchmark/BMP/Gray16/1000-8        1000033        34             -100.00%
Benchmark/BMP/Paletted/10-8        37             37             +0.00%
Benchmark/BMP/Paletted/100-8       36             36             +0.00%
Benchmark/BMP/Paletted/1000-8      36             36             +0.00%
Benchmark/BMP/YCbCr/10-8           133            34             -74.44%
Benchmark/BMP/YCbCr/100-8          10033          34             -99.66%
Benchmark/BMP/YCbCr/1000-8         1000033        34             -100.00%
Benchmark/BMP/NYCbCrA/10-8         133            34             -74.44%
Benchmark/BMP/NYCbCrA/100-8        10033          34             -99.66%
Benchmark/BMP/NYCbCrA/1000-8       1000033        34             -100.00%
Benchmark/BMP/CMYK/10-8            133            34             -74.44%
Benchmark/BMP/CMYK/100-8           10033          34             -99.66%
Benchmark/BMP/CMYK/1000-8          1000033        34             -100.00%
Benchmark/TIFF/RGBA/10-8           25             25             +0.00%
Benchmark/TIFF/RGBA/100-8          25             25             +0.00%
Benchmark/TIFF/RGBA/1000-8         25             25             +0.00%
Benchmark/TIFF/RGBA64/10-8         27             27             +0.00%
Benchmark/TIFF/RGBA64/100-8        27             27             +0.00%
Benchmark/TIFF/RGBA64/1000-8       27             27             +0.00%
Benchmark/TIFF/NRGBA/10-8          25             25             +0.00%
Benchmark/TIFF/NRGBA/100-8         25             25             +0.00%
Benchmark/TIFF/NRGBA/1000-8        25             25             +0.00%
Benchmark/TIFF/NRGBA64/10-8        27             27             +0.00%
Benchmark/TIFF/NRGBA64/100-8       27             27             +0.00%
Benchmark/TIFF/NRGBA64/1000-8      27             27             +0.00%
Benchmark/TIFF/Alpha/10-8          126            27             -78.57%
Benchmark/TIFF/Alpha/100-8         10026          27             -99.73%
Benchmark/TIFF/Alpha/1000-8        1000026        27             -100.00%
Benchmark/TIFF/Alpha16/10-8        126            27             -78.57%
Benchmark/TIFF/Alpha16/100-8       10026          27             -99.73%
Benchmark/TIFF/Alpha16/1000-8      1000026        27             -100.00%
Benchmark/TIFF/Gray/10-8           24             24             +0.00%
Benchmark/TIFF/Gray/100-8          24             24             +0.00%
Benchmark/TIFF/Gray/1000-8         24             24             +0.00%
Benchmark/TIFF/Gray16/10-8         25             25             +0.00%
Benchmark/TIFF/Gray16/100-8        25             25             +0.00%
Benchmark/TIFF/Gray16/1000-8       25             25             +0.00%
Benchmark/TIFF/Paletted/10-8       27             27             +0.00%
Benchmark/TIFF/Paletted/100-8      27             27             +0.00%
Benchmark/TIFF/Paletted/1000-8     27             27             +0.00%
Benchmark/TIFF/YCbCr/10-8          126            27             -78.57%
Benchmark/TIFF/YCbCr/100-8         10026          27             -99.73%
Benchmark/TIFF/YCbCr/1000-8        1000026        27             -100.00%
Benchmark/TIFF/NYCbCrA/10-8        126            27             -78.57%
Benchmark/TIFF/NYCbCrA/100-8       10026          27             -99.73%
Benchmark/TIFF/NYCbCrA/1000-8      1000026        27             -100.00%
Benchmark/TIFF/CMYK/10-8           126            27             -78.57%
Benchmark/TIFF/CMYK/100-8          10026          27             -99.73%
Benchmark/TIFF/CMYK/1000-8         1000026        27             -100.00%

benchmark                          old bytes     new bytes     delta
Benchmark/JPEG/RGBA/10-8           4400          4416          +0.36%
Benchmark/JPEG/RGBA/100-8          4400          4416          +0.36%
Benchmark/JPEG/RGBA/1000-8         4400          4416          +0.36%
Benchmark/JPEG/RGBA64/10-8         6448          4416          -31.51%
Benchmark/JPEG/RGBA64/100-8        104752        4416          -95.78%
Benchmark/JPEG/RGBA64/1000-8       8132924       4416          -99.95%
Benchmark/JPEG/NRGBA/10-8          5424          4416          -18.58%
Benchmark/JPEG/NRGBA/100-8         54576         4416          -91.91%
Benchmark/JPEG/NRGBA/1000-8        4068676       4416          -99.89%
Benchmark/JPEG/NRGBA64/10-8        6448          4416          -31.51%
Benchmark/JPEG/NRGBA64/100-8       104752        4416          -95.78%
Benchmark/JPEG/NRGBA64/1000-8      8132924       4416          -99.95%
Benchmark/JPEG/Alpha/10-8          4656          4416          -5.15%
Benchmark/JPEG/Alpha/100-8         16944         4416          -73.94%
Benchmark/JPEG/Alpha/1000-8        1020471       4416          -99.57%
Benchmark/JPEG/Alpha16/10-8        4912          4416          -10.10%
Benchmark/JPEG/Alpha16/100-8       29488         4416          -85.02%
Benchmark/JPEG/Alpha16/1000-8      2036550       4416          -99.78%
Benchmark/JPEG/Gray/10-8           4400          4400          +0.00%
Benchmark/JPEG/Gray/100-8          4400          4400          +0.00%
Benchmark/JPEG/Gray/1000-8         4400          4400          +0.00%
Benchmark/JPEG/Gray16/10-8         4912          4416          -10.10%
Benchmark/JPEG/Gray16/100-8        29488         4416          -85.02%
Benchmark/JPEG/Gray16/1000-8       2036550       4416          -99.78%
Benchmark/JPEG/Paletted/10-8       4400          4512          +2.55%
Benchmark/JPEG/Paletted/100-8      4400          4512          +2.55%
Benchmark/JPEG/Paletted/1000-8     4400          4512          +2.55%
Benchmark/JPEG/YCbCr/10-8          5219          4416          -15.39%
Benchmark/JPEG/YCbCr/100-8         44541         4416          -90.09%
Benchmark/JPEG/YCbCr/1000-8        3255826       4416          -99.86%
Benchmark/JPEG/NYCbCrA/10-8        5424          4416          -18.58%
Benchmark/JPEG/NYCbCrA/100-8       54576         4416          -91.91%
Benchmark/JPEG/NYCbCrA/1000-8      4068676       4416          -99.89%
Benchmark/JPEG/CMYK/10-8           5424          4416          -18.58%
Benchmark/JPEG/CMYK/100-8          54576         4416          -91.91%
Benchmark/JPEG/CMYK/1000-8         4068674       4416          -99.89%
Benchmark/PNG/RGBA/10-8            848947        848963        +0.00%
Benchmark/PNG/RGBA/100-8           930357        930373        +0.00%
Benchmark/PNG/RGBA/1000-8          8872468       8872480       +0.00%
Benchmark/PNG/RGBA64/10-8          850035        850051        +0.00%
Benchmark/PNG/RGBA64/100-8         1013234       1013249       +0.00%
Benchmark/PNG/RGBA64/1000-8        16897030      16897052      +0.00%
Benchmark/PNG/NRGBA/10-8           848147        848163        +0.00%
Benchmark/PNG/NRGBA/100-8          850356        850372        +0.00%
Benchmark/PNG/NRGBA/1000-8         872433        872450        +0.00%
Benchmark/PNG/NRGBA64/10-8         849235        849251        +0.00%
Benchmark/PNG/NRGBA64/100-8        933237        933253        +0.00%
Benchmark/PNG/NRGBA64/1000-8       8897022       8897035       +0.00%
Benchmark/PNG/Alpha/10-8           848946        848963        +0.00%
Benchmark/PNG/Alpha/100-8          930357        930372        +0.00%
Benchmark/PNG/Alpha/1000-8         8872497       8872518       +0.00%
Benchmark/PNG/Alpha16/10-8         850027        850043        +0.00%
Benchmark/PNG/Alpha16/100-8        1013228       1013245       +0.00%
Benchmark/PNG/Alpha16/1000-8       16897088      16897084      -0.00%
Benchmark/PNG/Gray/10-8            847955        847971        +0.00%
Benchmark/PNG/Gray/100-8           848531        848548        +0.00%
Benchmark/PNG/Gray/1000-8          854008        854023        +0.00%
Benchmark/PNG/Gray16/10-8          848251        848267        +0.00%
Benchmark/PNG/Gray16/100-8         869107        869123        +0.00%
Benchmark/PNG/Gray16/1000-8        2860163       2860184       +0.00%
Benchmark/PNG/Paletted/10-8        848019        848131        +0.01%
Benchmark/PNG/Paletted/100-8       848595        848708        +0.01%
Benchmark/PNG/Paletted/1000-8      854069        854183        +0.01%
Benchmark/PNG/YCbCr/10-8           848563        848259        -0.04%
Benchmark/PNG/YCbCr/100-8          883701        851716        -3.62%
Benchmark/PNG/YCbCr/1000-8         4084742       884739        -78.34%
Benchmark/PNG/NYCbCrA/10-8         850027        850043        +0.00%
Benchmark/PNG/NYCbCrA/100-8        1013226       1013242       +0.00%
Benchmark/PNG/NYCbCrA/1000-8       16897044      16897067      +0.00%
Benchmark/PNG/CMYK/10-8            848643        848259        -0.05%
Benchmark/PNG/CMYK/100-8           891701        851717        -4.48%
Benchmark/PNG/CMYK/1000-8          4884737       884741        -81.89%
Benchmark/BMP/RGBA/10-8            400           400           +0.00%
Benchmark/BMP/RGBA/100-8           688           688           +0.00%
Benchmark/BMP/RGBA/1000-8          3440          3440          +0.00%
Benchmark/BMP/RGBA64/10-8          1200          416           -65.33%
Benchmark/BMP/RGBA64/100-8         80688         704           -99.13%
Benchmark/BMP/RGBA64/1000-8        8003450       3456          -99.96%
Benchmark/BMP/NRGBA/10-8           800           416           -48.00%
Benchmark/BMP/NRGBA/100-8          40688         704           -98.27%
Benchmark/BMP/NRGBA/1000-8         4003453       3456          -99.91%
Benchmark/BMP/NRGBA64/10-8         1200          416           -65.33%
Benchmark/BMP/NRGBA64/100-8        80688         704           -99.13%
Benchmark/BMP/NRGBA64/1000-8       8003451       3456          -99.96%
Benchmark/BMP/Alpha/10-8           504           416           -17.46%
Benchmark/BMP/Alpha/100-8          10688         704           -93.41%
Benchmark/BMP/Alpha/1000-8         1003446       3456          -99.66%
Benchmark/BMP/Alpha16/10-8         600           416           -30.67%
Benchmark/BMP/Alpha16/100-8        20688         704           -96.60%
Benchmark/BMP/Alpha16/1000-8       2003451       3456          -99.83%
Benchmark/BMP/Gray/10-8            2464          2464          +0.00%
Benchmark/BMP/Gray/100-8           2456          2456          +0.00%
Benchmark/BMP/Gray/1000-8          2456          2456          +0.00%
Benchmark/BMP/Gray16/10-8          600           416           -30.67%
Benchmark/BMP/Gray16/100-8         20688         704           -96.60%
Benchmark/BMP/Gray16/1000-8        2003450       3456          -99.83%
Benchmark/BMP/Paletted/10-8        2464          2464          +0.00%
Benchmark/BMP/Paletted/100-8       2456          2456          +0.00%
Benchmark/BMP/Paletted/1000-8      2456          2456          +0.00%
Benchmark/BMP/YCbCr/10-8           720           416           -42.22%
Benchmark/BMP/YCbCr/100-8          32688         704           -97.85%
Benchmark/BMP/YCbCr/1000-8         3203455       3456          -99.89%
Benchmark/BMP/NYCbCrA/10-8         800           416           -48.00%
Benchmark/BMP/NYCbCrA/100-8        40688         704           -98.27%
Benchmark/BMP/NYCbCrA/1000-8       4003454       3456          -99.91%
Benchmark/BMP/CMYK/10-8            800           416           -48.00%
Benchmark/BMP/CMYK/100-8           40688         704           -98.27%
Benchmark/BMP/CMYK/1000-8          4003453       3456          -99.91%
Benchmark/TIFF/RGBA/10-8           2800          2800          +0.00%
Benchmark/TIFF/RGBA/100-8          2800          2800          +0.00%
Benchmark/TIFF/RGBA/1000-8         2800          2800          +0.00%
Benchmark/TIFF/RGBA64/10-8         2896          2896          +0.00%
Benchmark/TIFF/RGBA64/100-8        3712          3712          +0.00%
Benchmark/TIFF/RGBA64/1000-8       11008         11008         +0.00%
Benchmark/TIFF/NRGBA/10-8          2800          2800          +0.00%
Benchmark/TIFF/NRGBA/100-8         2800          2800          +0.00%
Benchmark/TIFF/NRGBA/1000-8        2800          2800          +0.00%
Benchmark/TIFF/NRGBA64/10-8        2896          2896          +0.00%
Benchmark/TIFF/NRGBA64/100-8       3712          3712          +0.00%
Benchmark/TIFF/NRGBA64/1000-8      11008         11008         +0.00%
Benchmark/TIFF/Alpha/10-8          2960          2864          -3.24%
Benchmark/TIFF/Alpha/100-8         13216         3232          -75.54%
Benchmark/TIFF/Alpha/1000-8        1006898       6912          -99.31%
Benchmark/TIFF/Alpha16/10-8        3056          2864          -6.28%
Benchmark/TIFF/Alpha16/100-8       23216         3232          -86.08%
Benchmark/TIFF/Alpha16/1000-8      2006901       6912          -99.66%
Benchmark/TIFF/Gray/10-8           1784          1784          +0.00%
Benchmark/TIFF/Gray/100-8          1784          1784          +0.00%
Benchmark/TIFF/Gray/1000-8         1784          1784          +0.00%
Benchmark/TIFF/Gray16/10-8         1816          1816          +0.00%
Benchmark/TIFF/Gray16/100-8        1992          1992          +0.00%
Benchmark/TIFF/Gray16/1000-8       3832          3832          +0.00%
Benchmark/TIFF/Paletted/10-8       7928          7928          +0.00%
Benchmark/TIFF/Paletted/100-8      7928          7928          +0.00%
Benchmark/TIFF/Paletted/1000-8     7928          7928          +0.00%
Benchmark/TIFF/YCbCr/10-8          3184          2864          -10.05%
Benchmark/TIFF/YCbCr/100-8         35232         3232          -90.83%
Benchmark/TIFF/YCbCr/1000-8        3206914       6912          -99.78%
Benchmark/TIFF/NYCbCrA/10-8        3248          2864          -11.82%
Benchmark/TIFF/NYCbCrA/100-8       43216         3232          -92.52%
Benchmark/TIFF/NYCbCrA/1000-8      4006906       6912          -99.83%
Benchmark/TIFF/CMYK/10-8           3248          2864          -11.82%
Benchmark/TIFF/CMYK/100-8          43216         3232          -92.52%
Benchmark/TIFF/CMYK/1000-8         4006903       6912          -99.83%
```

My library should also speed up "copy" function (from an image type to another).

The modifications in the standard library and x/image are really straightforward:
- replace all `\.At\(.*\)\.RGBA\(\)` to a call to a `AtFunc`
- call `NewAtFunc()` before a "y/x" loop

The `image/jpeg.toYCbCr()` is tricky.
You need to call `NewAtFunc` in `image/jpeg.encoder.writeSOS()` and pass the `AtFunc` to `toYCbCr()`.

I also had to move my library to the standard library, because the go tool complained about bad imports...

As you can see: https://github.com/pierrre/imageutil
my code is tested and it returns the same results as the standard library.