func()

in draw/impl.go [2709:2837]


func (ablInterpolator) scale_Image_Image_Src(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
	sw := int32(sr.Dx())
	sh := int32(sr.Dy())
	yscale := float64(sh) / float64(dr.Dy())
	xscale := float64(sw) / float64(dr.Dx())
	swMinus1, shMinus1 := sw-1, sh-1
	srcMask, smp := opts.SrcMask, opts.SrcMaskP
	dstMask, dmp := opts.DstMask, opts.DstMaskP
	dstColorRGBA64 := &color.RGBA64{}
	dstColor := color.Color(dstColorRGBA64)

	for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
		sy := (float64(dy)+0.5)*yscale - 0.5
		// If sy < 0, we will clamp sy0 to 0 anyway, so it doesn't matter if
		// we say int32(sy) instead of int32(math.Floor(sy)). Similarly for
		// sx, below.
		sy0 := int32(sy)
		yFrac0 := sy - float64(sy0)
		yFrac1 := 1 - yFrac0
		sy1 := sy0 + 1
		if sy < 0 {
			sy0, sy1 = 0, 0
			yFrac0, yFrac1 = 0, 1
		} else if sy1 > shMinus1 {
			sy0, sy1 = shMinus1, shMinus1
			yFrac0, yFrac1 = 1, 0
		}

		for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
			sx := (float64(dx)+0.5)*xscale - 0.5
			sx0 := int32(sx)
			xFrac0 := sx - float64(sx0)
			xFrac1 := 1 - xFrac0
			sx1 := sx0 + 1
			if sx < 0 {
				sx0, sx1 = 0, 0
				xFrac0, xFrac1 = 0, 1
			} else if sx1 > swMinus1 {
				sx0, sx1 = swMinus1, swMinus1
				xFrac0, xFrac1 = 1, 0
			}

			s00ru, s00gu, s00bu, s00au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0)).RGBA()
			if srcMask != nil {
				_, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy0)).RGBA()
				s00ru = s00ru * ma / 0xffff
				s00gu = s00gu * ma / 0xffff
				s00bu = s00bu * ma / 0xffff
				s00au = s00au * ma / 0xffff
			}
			s00r := float64(s00ru)
			s00g := float64(s00gu)
			s00b := float64(s00bu)
			s00a := float64(s00au)
			s10ru, s10gu, s10bu, s10au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0)).RGBA()
			if srcMask != nil {
				_, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy0)).RGBA()
				s10ru = s10ru * ma / 0xffff
				s10gu = s10gu * ma / 0xffff
				s10bu = s10bu * ma / 0xffff
				s10au = s10au * ma / 0xffff
			}
			s10r := float64(s10ru)
			s10g := float64(s10gu)
			s10b := float64(s10bu)
			s10a := float64(s10au)
			s10r = xFrac1*s00r + xFrac0*s10r
			s10g = xFrac1*s00g + xFrac0*s10g
			s10b = xFrac1*s00b + xFrac0*s10b
			s10a = xFrac1*s00a + xFrac0*s10a
			s01ru, s01gu, s01bu, s01au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1)).RGBA()
			if srcMask != nil {
				_, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy1)).RGBA()
				s01ru = s01ru * ma / 0xffff
				s01gu = s01gu * ma / 0xffff
				s01bu = s01bu * ma / 0xffff
				s01au = s01au * ma / 0xffff
			}
			s01r := float64(s01ru)
			s01g := float64(s01gu)
			s01b := float64(s01bu)
			s01a := float64(s01au)
			s11ru, s11gu, s11bu, s11au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1)).RGBA()
			if srcMask != nil {
				_, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy1)).RGBA()
				s11ru = s11ru * ma / 0xffff
				s11gu = s11gu * ma / 0xffff
				s11bu = s11bu * ma / 0xffff
				s11au = s11au * ma / 0xffff
			}
			s11r := float64(s11ru)
			s11g := float64(s11gu)
			s11b := float64(s11bu)
			s11a := float64(s11au)
			s11r = xFrac1*s01r + xFrac0*s11r
			s11g = xFrac1*s01g + xFrac0*s11g
			s11b = xFrac1*s01b + xFrac0*s11b
			s11a = xFrac1*s01a + xFrac0*s11a
			s11r = yFrac1*s10r + yFrac0*s11r
			s11g = yFrac1*s10g + yFrac0*s11g
			s11b = yFrac1*s10b + yFrac0*s11b
			s11a = yFrac1*s10a + yFrac0*s11a
			pr := uint32(s11r)
			pg := uint32(s11g)
			pb := uint32(s11b)
			pa := uint32(s11a)
			if dstMask != nil {
				qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
				_, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
				pr = pr * ma / 0xffff
				pg = pg * ma / 0xffff
				pb = pb * ma / 0xffff
				pa = pa * ma / 0xffff
				pa1 := 0xffff - ma
				dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
				dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
				dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
				dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
				dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
			} else {
				dstColorRGBA64.R = uint16(pr)
				dstColorRGBA64.G = uint16(pg)
				dstColorRGBA64.B = uint16(pb)
				dstColorRGBA64.A = uint16(pa)
				dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
			}
		}
	}
}