func()

in draw/impl.go [2243:2416]


func (ablInterpolator) scale_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, 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

	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
		}
		d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4

		for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
			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
			}

			s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
			s00j := ((sr.Min.Y+int(sy0))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)

			// This is an inline version of image/color/ycbcr.go's YCbCr.RGBA method.
			s00yy1 := int(src.Y[s00i]) * 0x10101
			s00cb1 := int(src.Cb[s00j]) - 128
			s00cr1 := int(src.Cr[s00j]) - 128
			s00ru := (s00yy1 + 91881*s00cr1) >> 8
			s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
			s00bu := (s00yy1 + 116130*s00cb1) >> 8
			if s00ru < 0 {
				s00ru = 0
			} else if s00ru > 0xffff {
				s00ru = 0xffff
			}
			if s00gu < 0 {
				s00gu = 0
			} else if s00gu > 0xffff {
				s00gu = 0xffff
			}
			if s00bu < 0 {
				s00bu = 0
			} else if s00bu > 0xffff {
				s00bu = 0xffff
			}

			s00r := float64(s00ru)
			s00g := float64(s00gu)
			s00b := float64(s00bu)
			s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
			s10j := ((sr.Min.Y+int(sy0))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)

			// This is an inline version of image/color/ycbcr.go's YCbCr.RGBA method.
			s10yy1 := int(src.Y[s10i]) * 0x10101
			s10cb1 := int(src.Cb[s10j]) - 128
			s10cr1 := int(src.Cr[s10j]) - 128
			s10ru := (s10yy1 + 91881*s10cr1) >> 8
			s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
			s10bu := (s10yy1 + 116130*s10cb1) >> 8
			if s10ru < 0 {
				s10ru = 0
			} else if s10ru > 0xffff {
				s10ru = 0xffff
			}
			if s10gu < 0 {
				s10gu = 0
			} else if s10gu > 0xffff {
				s10gu = 0xffff
			}
			if s10bu < 0 {
				s10bu = 0
			} else if s10bu > 0xffff {
				s10bu = 0xffff
			}

			s10r := float64(s10ru)
			s10g := float64(s10gu)
			s10b := float64(s10bu)
			s10r = xFrac1*s00r + xFrac0*s10r
			s10g = xFrac1*s00g + xFrac0*s10g
			s10b = xFrac1*s00b + xFrac0*s10b
			s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
			s01j := ((sr.Min.Y+int(sy1))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)

			// This is an inline version of image/color/ycbcr.go's YCbCr.RGBA method.
			s01yy1 := int(src.Y[s01i]) * 0x10101
			s01cb1 := int(src.Cb[s01j]) - 128
			s01cr1 := int(src.Cr[s01j]) - 128
			s01ru := (s01yy1 + 91881*s01cr1) >> 8
			s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
			s01bu := (s01yy1 + 116130*s01cb1) >> 8
			if s01ru < 0 {
				s01ru = 0
			} else if s01ru > 0xffff {
				s01ru = 0xffff
			}
			if s01gu < 0 {
				s01gu = 0
			} else if s01gu > 0xffff {
				s01gu = 0xffff
			}
			if s01bu < 0 {
				s01bu = 0
			} else if s01bu > 0xffff {
				s01bu = 0xffff
			}

			s01r := float64(s01ru)
			s01g := float64(s01gu)
			s01b := float64(s01bu)
			s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
			s11j := ((sr.Min.Y+int(sy1))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)

			// This is an inline version of image/color/ycbcr.go's YCbCr.RGBA method.
			s11yy1 := int(src.Y[s11i]) * 0x10101
			s11cb1 := int(src.Cb[s11j]) - 128
			s11cr1 := int(src.Cr[s11j]) - 128
			s11ru := (s11yy1 + 91881*s11cr1) >> 8
			s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
			s11bu := (s11yy1 + 116130*s11cb1) >> 8
			if s11ru < 0 {
				s11ru = 0
			} else if s11ru > 0xffff {
				s11ru = 0xffff
			}
			if s11gu < 0 {
				s11gu = 0
			} else if s11gu > 0xffff {
				s11gu = 0xffff
			}
			if s11bu < 0 {
				s11bu = 0
			} else if s11bu > 0xffff {
				s11bu = 0xffff
			}

			s11r := float64(s11ru)
			s11g := float64(s11gu)
			s11b := float64(s11bu)
			s11r = xFrac1*s01r + xFrac0*s11r
			s11g = xFrac1*s01g + xFrac0*s11g
			s11b = xFrac1*s01b + xFrac0*s11b
			s11r = yFrac1*s10r + yFrac0*s11r
			s11g = yFrac1*s10g + yFrac0*s11g
			s11b = yFrac1*s10b + yFrac0*s11b
			pr := uint32(s11r)
			pg := uint32(s11g)
			pb := uint32(s11b)
			dst.Pix[d+0] = uint8(pr >> 8)
			dst.Pix[d+1] = uint8(pg >> 8)
			dst.Pix[d+2] = uint8(pb >> 8)
			dst.Pix[d+3] = 0xff
		}
	}
}