quantErrorCurr = make([][4]int32, r.Dx()+2)
quantErrorNext = make([][4]int32, r.Dx()+2)
}
+ pxRGBA := func(x, y int) (r, g, b, a uint32) { return src.At(x, y).RGBA() }
+ // Fast paths for special cases to avoid excessive use of the color.Color
+ // interface which escapes to the heap but need to be discovered for
+ // each pixel on r. See also https://golang.org/issues/15759.
+ switch src0 := src.(type) {
+ case *image.RGBA:
+ pxRGBA = func(x, y int) (r, g, b, a uint32) { return src0.RGBAAt(x, y).RGBA() }
+ case *image.NRGBA:
+ pxRGBA = func(x, y int) (r, g, b, a uint32) { return src0.NRGBAAt(x, y).RGBA() }
+ case *image.YCbCr:
+ pxRGBA = func(x, y int) (r, g, b, a uint32) { return src0.YCbCrAt(x, y).RGBA() }
+ }
// Loop over each source pixel.
out := color.RGBA64{A: 0xffff}
for x := 0; x != r.Dx(); x++ {
// er, eg and eb are the pixel's R,G,B values plus the
// optional Floyd-Steinberg error.
- sr, sg, sb, sa := src.At(sp.X+x, sp.Y+y).RGBA()
+ sr, sg, sb, sa := pxRGBA(sp.X+x, sp.Y+y)
er, eg, eb, ea := int32(sr), int32(sg), int32(sb), int32(sa)
if floydSteinberg {
er = clamp(er + quantErrorCurr[x+1][0]/16)