in draw/impl.go [4304:4433]
func (ablInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
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++ {
dyf := float64(dr.Min.Y+int(dy)) + 0.5
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
dxf := float64(dr.Min.X+int(dx)) + 0.5
sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
continue
}
sx -= 0.5
sx0 := int(sx)
xFrac0 := sx - float64(sx0)
xFrac1 := 1 - xFrac0
sx0 += bias.X
sx1 := sx0 + 1
if sx0 < sr.Min.X {
sx0, sx1 = sr.Min.X, sr.Min.X
xFrac0, xFrac1 = 0, 1
} else if sx1 >= sr.Max.X {
sx0, sx1 = sr.Max.X-1, sr.Max.X-1
xFrac0, xFrac1 = 1, 0
}
sy -= 0.5
sy0 := int(sy)
yFrac0 := sy - float64(sy0)
yFrac1 := 1 - yFrac0
sy0 += bias.Y
sy1 := sy0 + 1
if sy0 < sr.Min.Y {
sy0, sy1 = sr.Min.Y, sr.Min.Y
yFrac0, yFrac1 = 0, 1
} else if sy1 >= sr.Max.Y {
sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
yFrac0, yFrac1 = 1, 0
}
s00ru, s00gu, s00bu, s00au := src.At(sx0, sy0).RGBA()
if srcMask != nil {
_, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+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(sx1, sy0).RGBA()
if srcMask != nil {
_, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+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(sx0, sy1).RGBA()
if srcMask != nil {
_, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+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(sx1, sy1).RGBA()
if srcMask != nil {
_, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+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)
}
}
}
}