image/draw: have Transform take a f64.Aff3 instead of a *f64.Aff3.

It's more args (in terms of bytes), but fewer allocations (Transformer
is an interface). Either way, it's not really that big of a deal, but
the value instead of the pointer seems conceptually more correct.

Change-Id: Ibea76da17cbda0d9633110fd56044b4e2c690e81
Reviewed-on: https://go-review.googlesource.com/12669
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Nigel Tao 2015-07-27 15:58:18 +10:00
parent 6b7a488d1e
commit 5c9906b535
5 changed files with 22 additions and 22 deletions

View File

@ -37,7 +37,7 @@ func ExampleDraw() {
draw.CatmullRom, draw.CatmullRom,
} }
const cos60, sin60 = 0.5, 0.866025404 const cos60, sin60 = 0.5, 0.866025404
t := &f64.Aff3{ t := f64.Aff3{
+2 * cos60, -2 * sin60, 100, +2 * cos60, -2 * sin60, 100,
+2 * sin60, +2 * cos60, 100, +2 * sin60, +2 * cos60, 100,
} }
@ -67,7 +67,7 @@ func ExampleDraw() {
for i, op := range ops { for i, op := range ops {
dr := image.Rect(120+10*i, 150+60*i, 170+10*i, 200+60*i) dr := image.Rect(120+10*i, 150+60*i, 170+10*i, 200+60*i)
draw.NearestNeighbor.Scale(dst, dr, red, red.Bounds(), op, nil) draw.NearestNeighbor.Scale(dst, dr, red, red.Bounds(), op, nil)
t := &f64.Aff3{ t := f64.Aff3{
+cos60, -sin60, float64(190 + 10*i), +cos60, -sin60, float64(190 + 10*i),
+sin60, +cos60, float64(140 + 50*i), +sin60, +cos60, float64(140 + 50*i),
} }

View File

@ -913,13 +913,13 @@ const (
} }
} }
func (z $receiver) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) { func (z $receiver) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options var o Options
if opts != nil { if opts != nil {
o = *opts o = *opts
} }
dr := transformRect(s2d, &sr) dr := transformRect(&s2d, &sr)
// adr is the affected destination pixels. // adr is the affected destination pixels.
adr := dst.Bounds().Intersect(dr) adr := dst.Bounds().Intersect(dr)
adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP) adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
@ -930,7 +930,7 @@ const (
op = Src op = Src
} }
d2s := invert(s2d) d2s := invert(&s2d)
// bias is a translation of the mapping from dst coordinates to src // bias is a translation of the mapping from dst coordinates to src
// coordinates such that the latter temporarily have non-negative X // coordinates such that the latter temporarily have non-negative X
// and Y coordinates. This allows us to write int(f) instead of // and Y coordinates. This allows us to write int(f) instead of
@ -1179,13 +1179,13 @@ const (
} }
} }
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) { func (q *Kernel) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options var o Options
if opts != nil { if opts != nil {
o = *opts o = *opts
} }
dr := transformRect(s2d, &sr) dr := transformRect(&s2d, &sr)
// adr is the affected destination pixels. // adr is the affected destination pixels.
adr := dst.Bounds().Intersect(dr) adr := dst.Bounds().Intersect(dr)
adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP) adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
@ -1195,7 +1195,7 @@ const (
if op == Over && o.SrcMask == nil && opaque(src) { if op == Over && o.SrcMask == nil && opaque(src) {
op = Src op = Src
} }
d2s := invert(s2d) d2s := invert(&s2d)
// bias is a translation of the mapping from dst coordinates to src // bias is a translation of the mapping from dst coordinates to src
// coordinates such that the latter temporarily have non-negative X // coordinates such that the latter temporarily have non-negative X
// and Y coordinates. This allows us to write int(f) instead of // and Y coordinates. This allows us to write int(f) instead of

View File

@ -97,13 +97,13 @@ 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, op Op, opts *Options) { func (z nnInterpolator) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options var o Options
if opts != nil { if opts != nil {
o = *opts o = *opts
} }
dr := transformRect(s2d, &sr) dr := transformRect(&s2d, &sr)
// adr is the affected destination pixels. // adr is the affected destination pixels.
adr := dst.Bounds().Intersect(dr) adr := dst.Bounds().Intersect(dr)
adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP) adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
@ -114,7 +114,7 @@ func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
op = Src op = Src
} }
d2s := invert(s2d) d2s := invert(&s2d)
// bias is a translation of the mapping from dst coordinates to src // bias is a translation of the mapping from dst coordinates to src
// coordinates such that the latter temporarily have non-negative X // coordinates such that the latter temporarily have non-negative X
// and Y coordinates. This allows us to write int(f) instead of // and Y coordinates. This allows us to write int(f) instead of
@ -1118,13 +1118,13 @@ 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, op Op, opts *Options) { func (z ablInterpolator) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options var o Options
if opts != nil { if opts != nil {
o = *opts o = *opts
} }
dr := transformRect(s2d, &sr) dr := transformRect(&s2d, &sr)
// adr is the affected destination pixels. // adr is the affected destination pixels.
adr := dst.Bounds().Intersect(dr) adr := dst.Bounds().Intersect(dr)
adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP) adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
@ -1135,7 +1135,7 @@ func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
op = Src op = Src
} }
d2s := invert(s2d) d2s := invert(&s2d)
// bias is a translation of the mapping from dst coordinates to src // bias is a translation of the mapping from dst coordinates to src
// coordinates such that the latter temporarily have non-negative X // coordinates such that the latter temporarily have non-negative X
// and Y coordinates. This allows us to write int(f) instead of // and Y coordinates. This allows us to write int(f) instead of
@ -4498,13 +4498,13 @@ 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, op Op, opts *Options) { func (q *Kernel) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
var o Options var o Options
if opts != nil { if opts != nil {
o = *opts o = *opts
} }
dr := transformRect(s2d, &sr) dr := transformRect(&s2d, &sr)
// adr is the affected destination pixels. // adr is the affected destination pixels.
adr := dst.Bounds().Intersect(dr) adr := dst.Bounds().Intersect(dr)
adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP) adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
@ -4514,7 +4514,7 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
if op == Over && o.SrcMask == nil && opaque(src) { if op == Over && o.SrcMask == nil && opaque(src) {
op = Src op = Src
} }
d2s := invert(s2d) d2s := invert(&s2d)
// bias is a translation of the mapping from dst coordinates to src // bias is a translation of the mapping from dst coordinates to src
// coordinates such that the latter temporarily have non-negative X // coordinates such that the latter temporarily have non-negative X
// and Y coordinates. This allows us to write int(f) instead of // and Y coordinates. This allows us to write int(f) instead of

View File

@ -54,7 +54,7 @@ type Scaler interface {
// //
// A Transformer is safe to use concurrently. // A Transformer is safe to use concurrently.
type Transformer interface { type Transformer interface {
Transform(dst Image, m *f64.Aff3, src image.Image, sr image.Rectangle, op Op, 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. // Options are optional parameters to Copy, Scale and Transform.

View File

@ -23,9 +23,9 @@ import (
var genGoldenFiles = flag.Bool("gen_golden_files", false, "whether to generate the TestXxx golden files.") var genGoldenFiles = flag.Bool("gen_golden_files", false, "whether to generate the TestXxx golden files.")
var transformMatrix = func(scale, tx, ty float64) *f64.Aff3 { var transformMatrix = func(scale, tx, ty float64) f64.Aff3 {
const cos30, sin30 = 0.866025404, 0.5 const cos30, sin30 = 0.866025404, 0.5
return &f64.Aff3{ return f64.Aff3{
+scale * cos30, -scale * sin30, tx, +scale * cos30, -scale * sin30, tx,
+scale * sin30, +scale * cos30, ty, +scale * sin30, +scale * cos30, ty,
} }
@ -297,11 +297,11 @@ func TestSrcTranslationInvariance(t *testing.T) {
tsrc := &translatedImage{src, delta} tsrc := &translatedImage{src, delta}
got := image.NewRGBA(image.Rect(0, 0, 20, 20)) got := image.NewRGBA(image.Rect(0, 0, 20, 20))
if transform { if transform {
m := matMul(m00, &f64.Aff3{ m := matMul(&m00, &f64.Aff3{
1, 0, -float64(delta.X), 1, 0, -float64(delta.X),
0, 1, -float64(delta.Y), 0, 1, -float64(delta.Y),
}) })
q.Transform(got, &m, tsrc, sr.Add(delta), Over, nil) q.Transform(got, m, tsrc, sr.Add(delta), Over, nil)
} else { } else {
q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), Over, nil) q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), Over, nil)
} }