switch scm {
case nil:
src = &image.Uniform{C: color.RGBA{0x11, 0x22, 0x33, 0xff}}
+ case color.CMYKModel:
+ src1 := image.NewCMYK(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetCMYK(x, y, color.CMYK{
+ uint8(13 * x % 0x100),
+ uint8(11 * y % 0x100),
+ uint8((11*x + 13*y) % 0x100),
+ uint8((31*x + 37*y) % 0x100),
+ })
+ }
+ }
+ src = src1
+ case color.GrayModel:
+ src1 := image.NewGray(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetGray(x, y, color.Gray{
+ uint8((11*x + 13*y) % 0x100),
+ })
+ }
+ }
+ src = src1
case color.RGBAModel:
src1 := image.NewRGBA(image.Rect(0, 0, srcw, srch))
for y := 0; y < srch; y++ {
bench(b, color.RGBAModel, color.YCbCrModel, nil, Over)
}
+func BenchmarkGray(b *testing.B) {
+ bench(b, color.RGBAModel, color.GrayModel, nil, Over)
+}
+
+func BenchmarkCMYK(b *testing.B) {
+ bench(b, color.RGBAModel, color.CMYKModel, nil, Over)
+}
+
func BenchmarkGlyphOver(b *testing.B) {
bench(b, color.RGBAModel, nil, color.AlphaModel, Over)
}
if drawYCbCr(dst0, r, src0, sp) {
return
}
+ case *image.Gray:
+ drawGray(dst0, r, src0, sp)
+ return
case *image.CMYK:
drawCMYK(dst0, r, src0, sp)
return
if drawYCbCr(dst0, r, src0, sp) {
return
}
+ case *image.Gray:
+ drawGray(dst0, r, src0, sp)
+ return
case *image.CMYK:
drawCMYK(dst0, r, src0, sp)
return
return true
}
+func drawGray(dst *image.RGBA, r image.Rectangle, src *image.Gray, sp image.Point) {
+ // An image.Gray is always fully opaque, and so if the mask is implicitly nil
+ // (i.e. fully opaque) then the op is effectively always Src.
+ i0 := (r.Min.X - dst.Rect.Min.X) * 4
+ i1 := (r.Max.X - dst.Rect.Min.X) * 4
+ si0 := (sp.X - src.Rect.Min.X) * 1
+ yMax := r.Max.Y - dst.Rect.Min.Y
+
+ y := r.Min.Y - dst.Rect.Min.Y
+ sy := sp.Y - src.Rect.Min.Y
+ for ; y != yMax; y, sy = y+1, sy+1 {
+ dpix := dst.Pix[y*dst.Stride:]
+ spix := src.Pix[sy*src.Stride:]
+
+ for i, si := i0, si0; i < i1; i, si = i+4, si+1 {
+ p := spix[si]
+ dpix[i+0] = p
+ dpix[i+1] = p
+ dpix[i+2] = p
+ dpix[i+3] = 255
+ }
+ }
+}
+
func drawCMYK(dst *image.RGBA, r image.Rectangle, src *image.CMYK, sp image.Point) {
// An image.CMYK is always fully opaque, and so if the mask is implicitly nil
// (i.e. fully opaque) then the op is effectively always Src.
return m
}
+func vgradGray() image.Image {
+ m := image.NewGray(image.Rect(0, 0, 16, 16))
+ for y := 0; y < 16; y++ {
+ for x := 0; x < 16; x++ {
+ m.Set(x, y, color.Gray{uint8(y * 0x11)})
+ }
+ }
+ return m
+}
+
func vgradMagenta() image.Image {
m := image.NewCMYK(image.Rect(0, 0, 16, 16))
for y := 0; y < 16; y++ {
{"ycbcrAlphaSrc", vgradCr(), fillAlpha(192), Src, color.RGBA{8, 28, 0, 192}},
{"ycbcrNil", vgradCr(), nil, Over, color.RGBA{11, 38, 0, 255}},
{"ycbcrNilSrc", vgradCr(), nil, Src, color.RGBA{11, 38, 0, 255}},
+ // Uniform mask (100%, 75%, nil) and variable Gray source.
+ // At (x, y) == (8, 8):
+ // The destination pixel is {136, 0, 0, 255}.
+ // The source pixel is {136} in Gray-space, which is {136, 136, 136, 255} in RGBA-space.
+ {"gray", vgradGray(), fillAlpha(255), Over, color.RGBA{136, 136, 136, 255}},
+ {"graySrc", vgradGray(), fillAlpha(255), Src, color.RGBA{136, 136, 136, 255}},
+ {"grayAlpha", vgradGray(), fillAlpha(192), Over, color.RGBA{136, 102, 102, 255}},
+ {"grayAlphaSrc", vgradGray(), fillAlpha(192), Src, color.RGBA{102, 102, 102, 192}},
+ {"grayNil", vgradGray(), nil, Over, color.RGBA{136, 136, 136, 255}},
+ {"grayNilSrc", vgradGray(), nil, Src, color.RGBA{136, 136, 136, 255}},
// Uniform mask (100%, 75%, nil) and variable CMYK source.
// At (x, y) == (8, 8):
// The destination pixel is {136, 0, 0, 255}.