draw: make op a mandatory argument, not optional.

Change-Id: Ic08ce587cf458444b098b752f0fa7ab16d43c914
Reviewed-on: https://go-review.googlesource.com/9468
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Nigel Tao 2015-04-29 17:05:36 +10:00
parent 6af46c2009
commit 70cb8023e6
5 changed files with 104 additions and 117 deletions

View File

@ -30,7 +30,7 @@ func ExampleDraw() {
dst := image.NewRGBA(image.Rect(0, 0, 400, 300))
green := image.NewUniform(color.RGBA{0x00, 0x1f, 0x00, 0xff})
draw.Copy(dst, image.Point{}, green, dst.Bounds(), nil)
draw.Copy(dst, image.Point{}, green, dst.Bounds(), draw.Src, nil)
qs := []draw.Interpolator{
draw.NearestNeighbor,
draw.ApproxBiLinear,
@ -42,11 +42,11 @@ func ExampleDraw() {
+2 * sin60, +2 * cos60, 100,
}
draw.Copy(dst, image.Point{20, 30}, src, src.Bounds(), nil)
draw.Copy(dst, image.Point{20, 30}, src, src.Bounds(), draw.Over, nil)
for i, q := range qs {
q.Scale(dst, image.Rect(200+10*i, 100*i, 600+10*i, 150+100*i), src, src.Bounds(), nil)
q.Scale(dst, image.Rect(200+10*i, 100*i, 600+10*i, 150+100*i), src, src.Bounds(), draw.Over, nil)
}
draw.NearestNeighbor.Transform(dst, t, src, src.Bounds(), nil)
draw.NearestNeighbor.Transform(dst, t, src, src.Bounds(), draw.Over, nil)
red := image.NewNRGBA(image.Rect(0, 0, 16, 16))
for y := 0; y < 16; y++ {
@ -65,14 +65,13 @@ func ExampleDraw() {
draw.Src,
}
for i, op := range ops {
q, opts := draw.NearestNeighbor, &draw.Options{Op: op}
dr := image.Rect(120+10*i, 150+60*i, 170+10*i, 200+60*i)
q.Scale(dst, dr, red, red.Bounds(), opts)
draw.NearestNeighbor.Scale(dst, dr, red, red.Bounds(), op, nil)
t := &f64.Aff3{
+cos60, -sin60, float64(190 + 10*i),
+sin60, +cos60, float64(140 + 50*i),
}
q.Transform(dst, t, red, red.Bounds(), opts)
draw.NearestNeighbor.Transform(dst, t, red, red.Bounds(), op, nil)
}
dr := image.Rect(0, 0, 128, 128)
@ -95,7 +94,7 @@ func ExampleDraw() {
}
}
cyan := image.NewUniform(color.RGBA{0x00, 0xff, 0xff, 0xff})
draw.NearestNeighbor.Scale(dst, dr, cyan, sr, &draw.Options{
draw.NearestNeighbor.Scale(dst, dr, cyan, sr, draw.Over, &draw.Options{
DstMask: checkerboard,
SrcMask: circle,
})

View File

@ -703,7 +703,7 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
func expnSwitch(op, dType string, expandBoth bool, template string) string {
if op == "" && dType != "anyDType" {
lines := []string{"switch o.Op {"}
lines := []string{"switch op {"}
for _, op = range ops {
lines = append(lines,
fmt.Sprintf("case %s:", op),
@ -876,7 +876,7 @@ func relName(s string) string {
const (
codeRoot = `
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -890,8 +890,8 @@ const (
}
// Make adr relative to dr.Min.
adr = adr.Sub(dr.Min)
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
// sr is the source pixels. If it extends beyond the src bounds,
@ -900,20 +900,20 @@ const (
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
case Src:
z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
}
} else if _, ok := src.(*image.Uniform); ok {
Draw(dst, dr, src, src.Bounds().Min, o.Op)
Draw(dst, dr, src, src.Bounds().Min, op)
} else {
$switch z.scale_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, src, sr, &o)
}
}
func (z $receiver) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
func (z $receiver) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -926,8 +926,8 @@ const (
if adr.Empty() || sr.Empty() {
return
}
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
d2s := invert(s2d)
@ -951,14 +951,14 @@ const (
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
case Src:
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
}
} else if u, ok := src.(*image.Uniform); ok {
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
} else {
$switch z.transform_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, &d2s, src, sr, bias, &o)
}
@ -1116,9 +1116,9 @@ const (
`
codeKernelRoot = `
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
if z.dw != int32(dr.Dx()) || z.dh != int32(dr.Dy()) || z.sw != int32(sr.Dx()) || z.sh != int32(sr.Dy()) {
z.kernel.Scale(dst, dr, src, sr, opts)
z.kernel.Scale(dst, dr, src, sr, op, opts)
return
}
@ -1135,12 +1135,12 @@ const (
}
// Make adr relative to dr.Min.
adr = adr.Sub(dr.Min)
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
if _, ok := src.(*image.Uniform); ok && o.DstMask == nil && o.SrcMask == nil && sr.In(src.Bounds()) {
Draw(dst, dr, src, src.Bounds().Min, o.Op)
Draw(dst, dr, src, src.Bounds().Min, op)
return
}
@ -1168,7 +1168,7 @@ const (
}
if o.DstMask != nil {
switch o.Op {
switch op {
case Over:
z.scaleY_Image_Over(dst, dr, adr, tmp, &o)
case Src:
@ -1179,7 +1179,7 @@ const (
}
}
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -1192,8 +1192,8 @@ const (
if adr.Empty() || sr.Empty() {
return
}
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
d2s := invert(s2d)
// bias is a translation of the mapping from dst coordinates to src
@ -1212,7 +1212,7 @@ const (
adr = adr.Sub(dr.Min)
if u, ok := src.(*image.Uniform); ok && o.DstMask != nil && o.SrcMask != nil && sr.In(src.Bounds()) {
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
return
}
@ -1231,7 +1231,7 @@ const (
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
case Src:

View File

@ -10,7 +10,7 @@ import (
"golang.org/x/image/math/f64"
)
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -24,8 +24,8 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
}
// Make adr relative to dr.Min.
adr = adr.Sub(dr.Min)
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
// sr is the source pixels. If it extends beyond the src bounds,
@ -34,16 +34,16 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
case Src:
z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
}
} else if _, ok := src.(*image.Uniform); ok {
Draw(dst, dr, src, src.Bounds().Min, o.Op)
Draw(dst, dr, src, src.Bounds().Min, op)
} else {
switch o.Op {
switch op {
case Over:
switch dst := dst.(type) {
case *image.RGBA:
@ -97,7 +97,7 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
}
}
func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -110,8 +110,8 @@ func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
if adr.Empty() || sr.Empty() {
return
}
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
d2s := invert(s2d)
@ -135,16 +135,16 @@ func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
case Src:
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
}
} else if u, ok := src.(*image.Uniform); ok {
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
} else {
switch o.Op {
switch op {
case Over:
switch dst := dst.(type) {
case *image.RGBA:
@ -1031,7 +1031,7 @@ func (nnInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectang
}
}
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -1045,8 +1045,8 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
}
// Make adr relative to dr.Min.
adr = adr.Sub(dr.Min)
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
// sr is the source pixels. If it extends beyond the src bounds,
@ -1055,16 +1055,16 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
case Src:
z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
}
} else if _, ok := src.(*image.Uniform); ok {
Draw(dst, dr, src, src.Bounds().Min, o.Op)
Draw(dst, dr, src, src.Bounds().Min, op)
} else {
switch o.Op {
switch op {
case Over:
switch dst := dst.(type) {
case *image.RGBA:
@ -1118,7 +1118,7 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
}
}
func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -1131,8 +1131,8 @@ func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
if adr.Empty() || sr.Empty() {
return
}
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
d2s := invert(s2d)
@ -1156,16 +1156,16 @@ func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
case Src:
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
}
} else if u, ok := src.(*image.Uniform); ok {
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
} else {
switch o.Op {
switch op {
case Over:
switch dst := dst.(type) {
case *image.RGBA:
@ -4398,9 +4398,9 @@ func (ablInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectan
}
}
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
if z.dw != int32(dr.Dx()) || z.dh != int32(dr.Dy()) || z.sw != int32(sr.Dx()) || z.sh != int32(sr.Dy()) {
z.kernel.Scale(dst, dr, src, sr, opts)
z.kernel.Scale(dst, dr, src, sr, op, opts)
return
}
@ -4417,12 +4417,12 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
}
// Make adr relative to dr.Min.
adr = adr.Sub(dr.Min)
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
if _, ok := src.(*image.Uniform); ok && o.DstMask == nil && o.SrcMask == nil && sr.In(src.Bounds()) {
Draw(dst, dr, src, src.Bounds().Min, o.Op)
Draw(dst, dr, src, src.Bounds().Min, op)
return
}
@ -4472,14 +4472,14 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
}
if o.DstMask != nil {
switch o.Op {
switch op {
case Over:
z.scaleY_Image_Over(dst, dr, adr, tmp, &o)
case Src:
z.scaleY_Image_Src(dst, dr, adr, tmp, &o)
}
} else {
switch o.Op {
switch op {
case Over:
switch dst := dst.(type) {
case *image.RGBA:
@ -4498,7 +4498,7 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
}
}
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
@ -4511,8 +4511,8 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
if adr.Empty() || sr.Empty() {
return
}
if o.Op == Over && o.SrcMask == nil && opaque(src) {
o.Op = Src
if op == Over && o.SrcMask == nil && opaque(src) {
op = Src
}
d2s := invert(s2d)
// bias is a translation of the mapping from dst coordinates to src
@ -4531,7 +4531,7 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
adr = adr.Sub(dr.Min)
if u, ok := src.(*image.Uniform); ok && o.DstMask != nil && o.SrcMask != nil && sr.In(src.Bounds()) {
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
return
}
@ -4550,14 +4550,14 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
//
// Similarly, the fast paths assume that the masks are nil.
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
switch o.Op {
switch op {
case Over:
q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
case Src:
q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
}
} else {
switch o.Op {
switch op {
case Over:
switch dst := dst.(type) {
case *image.RGBA:

View File

@ -15,33 +15,34 @@ import (
"golang.org/x/image/math/f64"
)
// Copy copies the part of the source image defined by src and sr and writes to
// the part of the destination image defined by dst and the translation of sr
// so that sr.Min translates to dp.
func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, opts *Options) {
// Copy copies the part of the source image defined by src and sr and writes
// the result of a Porter-Duff composition to the part of the destination image
// defined by dst and the translation of sr so that sr.Min translates to dp.
func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options
if opts != nil {
o = *opts
}
dr := sr.Add(dp.Sub(sr.Min))
if o.DstMask == nil {
DrawMask(dst, dr, src, sr.Min, o.SrcMask, o.SrcMaskP.Add(sr.Min), o.Op)
DrawMask(dst, dr, src, sr.Min, o.SrcMask, o.SrcMaskP.Add(sr.Min), op)
} else {
NearestNeighbor.Scale(dst, dr, src, sr, opts)
NearestNeighbor.Scale(dst, dr, src, sr, op, opts)
}
}
// Scaler scales the part of the source image defined by src and sr and writes
// to the part of the destination image defined by dst and dr.
// the result of a Porter-Duff composition to the part of the destination image
// defined by dst and dr.
//
// A Scaler is safe to use concurrently.
type Scaler interface {
Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options)
Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options)
}
// Transformer transforms the part of the source image defined by src and sr
// and writes to the part of the destination image defined by dst and the
// affine transform m applied to sr.
// and writes the result of a Porter-Duff composition to the part of the
// destination image defined by dst and the affine transform m applied to sr.
//
// For example, if m is the matrix
//
@ -53,16 +54,13 @@ type Scaler interface {
//
// A Transformer is safe to use concurrently.
type Transformer interface {
Transform(dst Image, m *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options)
Transform(dst Image, m *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options)
}
// Options are optional parameters to Copy, Scale and Transform.
//
// A nil *Options means to use the default (zero) values of each field.
type Options struct {
// Op is the compositing operator. The default value is Over.
Op Op
// Masks limit what parts of the dst image are drawn to and what parts of
// the src image are drawn from.
//
@ -124,8 +122,8 @@ type Kernel struct {
}
// Scale implements the Scaler interface.
func (q *Kernel) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
q.newScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy(), false).Scale(dst, dr, src, sr, opts)
func (q *Kernel) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
q.newScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy(), false).Scale(dst, dr, src, sr, op, opts)
}
// NewScaler returns a Scaler that is optimized for scaling multiple times with

View File

@ -64,9 +64,6 @@ func testInterp(t *testing.T, w int, h int, direction, prefix, suffix string) {
if prefix == "tux" {
op, scale = Over, 0.125
}
opts := &Options{
Op: op,
}
green := image.NewUniform(color.RGBA{0x00, 0x22, 0x11, 0xff})
testCases := map[string]Interpolator{
@ -79,11 +76,11 @@ func testInterp(t *testing.T, w int, h int, direction, prefix, suffix string) {
goldenFilename := fmt.Sprintf("../testdata/%s-%s-%s.png", prefix, direction, name)
got := image.NewRGBA(image.Rect(0, 0, w, h))
Copy(got, image.Point{}, green, got.Bounds(), nil)
Copy(got, image.Point{}, green, got.Bounds(), Src, nil)
if direction == "rotate" {
q.Transform(got, transformMatrix(scale, 40, 10), src, src.Bounds(), opts)
q.Transform(got, transformMatrix(scale, 40, 10), src, src.Bounds(), op, nil)
} else {
q.Scale(got, got.Bounds(), src, src.Bounds(), opts)
q.Scale(got, got.Bounds(), src, src.Bounds(), op, nil)
}
if *genGoldenFiles {
@ -132,12 +129,12 @@ func TestOps(t *testing.T) {
}
for op, want := range testCases {
dst := image.NewRGBA(image.Rect(0, 0, 2, 2))
Copy(dst, image.Point{}, blue, dst.Bounds(), nil)
Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil)
src := image.NewRGBA(image.Rect(0, 0, 1, 1))
src.SetRGBA(0, 0, color.RGBA{0x7f, 0x00, 0x00, 0x7f})
NearestNeighbor.Scale(dst, dst.Bounds(), src, src.Bounds(), &Options{Op: op})
NearestNeighbor.Scale(dst, dst.Bounds(), src, src.Bounds(), op, nil)
if got := dst.RGBAAt(0, 0); got != want {
t.Errorf("op=%v: got %v, want %v", op, got, want)
@ -176,7 +173,7 @@ func TestNegativeWeights(t *testing.T) {
}
dst := image.NewRGBA(image.Rect(0, 0, 32, 32))
CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), nil)
CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), Over, nil)
if err := check(dst); err != nil {
t.Fatalf("dst image: %v", err)
}
@ -213,11 +210,11 @@ func TestInterpClipCommute(t *testing.T) {
var interp func(dst *image.RGBA)
if transform {
interp = func(dst *image.RGBA) {
q.Transform(dst, transformMatrix(3.75, 2, 1), src, src.Bounds(), nil)
q.Transform(dst, transformMatrix(3.75, 2, 1), src, src.Bounds(), Over, nil)
}
} else {
interp = func(dst *image.RGBA) {
q.Scale(dst, outer, src, src.Bounds(), nil)
q.Scale(dst, outer, src, src.Bounds(), Over, nil)
}
}
@ -292,9 +289,9 @@ func TestSrcTranslationInvariance(t *testing.T) {
for _, q := range qs {
want := image.NewRGBA(image.Rect(0, 0, 20, 20))
if transform {
q.Transform(want, m00, src, sr, nil)
q.Transform(want, m00, src, sr, Over, nil)
} else {
q.Scale(want, want.Bounds(), src, sr, nil)
q.Scale(want, want.Bounds(), src, sr, Over, nil)
}
for _, delta := range deltas {
tsrc := &translatedImage{src, delta}
@ -304,9 +301,9 @@ func TestSrcTranslationInvariance(t *testing.T) {
1, 0, -float64(delta.X),
0, 1, -float64(delta.Y),
})
q.Transform(got, &m, tsrc, sr.Add(delta), nil)
q.Transform(got, &m, tsrc, sr.Add(delta), Over, nil)
} else {
q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), nil)
q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), Over, nil)
}
if !bytes.Equal(got.Pix, want.Pix) {
t.Errorf("pix differ for delta=%v, transform=%t, q=%T", delta, transform, q)
@ -325,8 +322,8 @@ func TestSrcMask(t *testing.T) {
red := image.NewUniform(color.RGBA{0xff, 0x00, 0x00, 0xff})
blue := image.NewUniform(color.RGBA{0x00, 0x00, 0xff, 0xff})
dst := image.NewRGBA(image.Rect(0, 0, 6, 1))
Copy(dst, image.Point{}, blue, dst.Bounds(), nil)
NearestNeighbor.Scale(dst, dst.Bounds(), red, image.Rect(0, 0, 3, 1), &Options{
Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil)
NearestNeighbor.Scale(dst, dst.Bounds(), red, image.Rect(0, 0, 3, 1), Over, &Options{
SrcMask: srcMask,
SrcMaskP: image.Point{20, 0},
})
@ -367,8 +364,8 @@ func TestDstMask(t *testing.T) {
}
for _, q := range qs {
dst := image.NewRGBA(image.Rect(0, 0, 3, 1))
Copy(dst, image.Point{}, blue, dst.Bounds(), nil)
q.Scale(dst, dst.Bounds(), red, red.Bounds(), &Options{
Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil)
q.Scale(dst, dst.Bounds(), red, red.Bounds(), Over, &Options{
DstMask: dstMask,
DstMaskP: image.Point{20, 0},
})
@ -410,8 +407,8 @@ func TestRectDstMask(t *testing.T) {
mk := func(q Transformer, dstMask image.Image, dstMaskP image.Point) *image.RGBA {
m := image.NewRGBA(bounds)
Copy(m, bounds.Min, dstOutside, bounds, nil)
q.Transform(m, m00, src, src.Bounds(), &Options{
Copy(m, bounds.Min, dstOutside, bounds, Src, nil)
q.Transform(m, m00, src, src.Bounds(), Over, &Options{
DstMask: dstMask,
DstMaskP: dstMaskP,
})
@ -536,7 +533,6 @@ func TestFastPaths(t *testing.T) {
for _, transform := range []bool{false, true} {
for _, q := range qs {
for _, op := range ops {
opts := &Options{Op: op}
dst0 := image.NewRGBA(drs[0])
dst1 := image.NewRGBA(drs[0])
Draw(dst0, dst0.Bounds(), blue, image.Point{}, Src)
@ -544,11 +540,11 @@ func TestFastPaths(t *testing.T) {
if transform {
m := transformMatrix(3.75, 2, 1)
q.Transform(dst0, m, src, sr, opts)
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, opts)
q.Transform(dst0, m, src, sr, op, nil)
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, op, nil)
} else {
q.Scale(dst0, dr, src, sr, opts)
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, opts)
q.Scale(dst0, dr, src, sr, op, nil)
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, op, nil)
}
if !bytes.Equal(dst0.Pix, dst1.Pix) {
@ -631,14 +627,11 @@ func benchScale(b *testing.B, w int, h int, op Op, srcf func(image.Rectangle) (i
}); ok {
scaler = n.NewScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy())
}
opts := &Options{
Op: op,
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
scaler.Scale(dst, dr, src, sr, opts)
scaler.Scale(dst, dr, src, sr, op, nil)
}
}
@ -650,14 +643,11 @@ func benchTform(b *testing.B, w int, h int, op Op, srcf func(image.Rectangle) (i
}
sr := src.Bounds()
m := transformMatrix(3.75, 40, 10)
opts := &Options{
Op: op,
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
q.Transform(dst, m, src, sr, opts)
q.Transform(dst, m, src, sr, op, nil)
}
}