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:
parent
6b7a488d1e
commit
5c9906b535
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
12
draw/gen.go
12
draw/gen.go
|
@ -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
|
||||||
|
|
18
draw/impl.go
18
draw/impl.go
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user