diff --git a/draw/gen.go b/draw/gen.go index 65a7123..822bb6a 100644 --- a/draw/gen.go +++ b/draw/gen.go @@ -877,8 +877,9 @@ func relName(s string) string { const ( codeRoot = ` func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) { - // Try to simplify a Scale to a Copy. - if dr.Size() == sr.Size() { + // Try to simplify a Scale to a Copy when DstMask is not specified. + // If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow. + if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) { Copy(dst, dr.Min, src, sr, op, opts) return } diff --git a/draw/impl.go b/draw/impl.go index 637887b..75498ad 100644 --- a/draw/impl.go +++ b/draw/impl.go @@ -11,8 +11,9 @@ import ( ) func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) { - // Try to simplify a Scale to a Copy. - if dr.Size() == sr.Size() { + // Try to simplify a Scale to a Copy when DstMask is not specified. + // If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow. + if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) { Copy(dst, dr.Min, src, sr, op, opts) return } @@ -1048,8 +1049,9 @@ 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, op Op, opts *Options) { - // Try to simplify a Scale to a Copy. - if dr.Size() == sr.Size() { + // Try to simplify a Scale to a Copy when DstMask is not specified. + // If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow. + if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) { Copy(dst, dr.Min, src, sr, op, opts) return } diff --git a/draw/scale_test.go b/draw/scale_test.go index 5e184c2..ea41940 100644 --- a/draw/scale_test.go +++ b/draw/scale_test.go @@ -551,6 +551,17 @@ func TestRectDstMask(t *testing.T) { } } +func TestDstMaskSameSizeCopy(t *testing.T) { + bounds := image.Rect(0, 0, 42, 42) + src := image.Opaque + dst := image.NewRGBA(bounds) + mask := image.NewRGBA(bounds) + + Copy(dst, image.ZP, src, bounds, Src, &Options{ + DstMask: mask, + }) +} + // TODO: delete this wrapper type once Go 1.5 is released, where an // image.Rectangle implements image.Image. type rectImage image.Rectangle