draw: switch on the Op compositing operator.
This change only *prepares* the codegen to handle multiple Ops. The actual generated code still only supports one Op (Src) and not the other (Over). A follow-up change will add Over. This Op switch (an eventual x2 multiplier in the amount of code generated) should be the last of the codegen LoC multipliers. The dst and src mask options will be implemented in the slow path fallback. Change-Id: Iecbcc6fad063e2aac36d78d5380c0a0947c709df Reviewed-on: https://go-review.googlesource.com/8488 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
c53fa16781
commit
b293696c81
124
draw/gen.go
124
draw/gen.go
|
@ -71,6 +71,7 @@ var (
|
|||
"420",
|
||||
"440",
|
||||
}
|
||||
ops = []string{"Src"} // TODO: add "Over".
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -95,17 +96,21 @@ type data struct {
|
|||
sType string
|
||||
sratio string
|
||||
receiver string
|
||||
op string
|
||||
}
|
||||
|
||||
func gen(w *bytes.Buffer, receiver string, codes ...string) {
|
||||
expn(w, codeRoot, &data{receiver: receiver})
|
||||
for _, code := range codes {
|
||||
for _, t := range dsTypes {
|
||||
expn(w, code, &data{
|
||||
dType: t.dType,
|
||||
sType: t.sType,
|
||||
receiver: receiver,
|
||||
})
|
||||
for _, op := range ops {
|
||||
expn(w, code, &data{
|
||||
dType: t.dType,
|
||||
sType: t.sType,
|
||||
receiver: receiver,
|
||||
op: op,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,15 +123,21 @@ func genKernel(w *bytes.Buffer) {
|
|||
})
|
||||
}
|
||||
for _, dType := range dTypes {
|
||||
expn(w, codeKernelScaleLeafY, &data{
|
||||
dType: dType,
|
||||
})
|
||||
for _, op := range ops {
|
||||
expn(w, codeKernelScaleLeafY, &data{
|
||||
dType: dType,
|
||||
op: op,
|
||||
})
|
||||
}
|
||||
}
|
||||
for _, t := range dsTypes {
|
||||
expn(w, codeKernelTransformLeaf, &data{
|
||||
dType: t.dType,
|
||||
sType: t.sType,
|
||||
})
|
||||
for _, op := range ops {
|
||||
expn(w, codeKernelTransformLeaf, &data{
|
||||
dType: t.dType,
|
||||
sType: t.sType,
|
||||
op: op,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,13 +203,15 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
|
|||
return prefix + relName(d.sType) + suffix
|
||||
case "receiver":
|
||||
return prefix + d.receiver + suffix
|
||||
case "op":
|
||||
return prefix + d.op + suffix
|
||||
|
||||
case "switch":
|
||||
return expnSwitch("", true, suffix)
|
||||
return expnSwitch("", "", true, suffix)
|
||||
case "switchD":
|
||||
return expnSwitch("", false, suffix)
|
||||
return expnSwitch("", "", false, suffix)
|
||||
case "switchS":
|
||||
return expnSwitch("anyDType", false, suffix)
|
||||
return expnSwitch("", "anyDType", false, suffix)
|
||||
|
||||
case "preOuter":
|
||||
switch d.dType {
|
||||
|
@ -568,7 +581,19 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func expnSwitch(dType string, expandBoth bool, template string) string {
|
||||
func expnSwitch(op, dType string, expandBoth bool, template string) string {
|
||||
if op == "" && dType != "anyDType" {
|
||||
lines := []string{"switch opts.op() {"}
|
||||
for _, op = range ops {
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("case %s:", op),
|
||||
expnSwitch(op, dType, expandBoth, template),
|
||||
)
|
||||
}
|
||||
lines = append(lines, "}")
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
switchVar := "dst"
|
||||
if dType != "" {
|
||||
switchVar = "src"
|
||||
|
@ -588,14 +613,14 @@ func expnSwitch(dType string, expandBoth bool, template string) string {
|
|||
|
||||
if dType != "" {
|
||||
if v == "*image.YCbCr" {
|
||||
lines = append(lines, expnSwitchYCbCr(dType, template))
|
||||
lines = append(lines, expnSwitchYCbCr(op, dType, template))
|
||||
} else {
|
||||
lines = append(lines, expnLine(template, &data{dType: dType, sType: v}))
|
||||
lines = append(lines, expnLine(template, &data{dType: dType, sType: v, op: op}))
|
||||
}
|
||||
} else if !expandBoth {
|
||||
lines = append(lines, expnLine(template, &data{dType: v}))
|
||||
lines = append(lines, expnLine(template, &data{dType: v, op: op}))
|
||||
} else {
|
||||
lines = append(lines, expnSwitch(v, false, template))
|
||||
lines = append(lines, expnSwitch(op, v, false, template))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -603,16 +628,16 @@ func expnSwitch(dType string, expandBoth bool, template string) string {
|
|||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func expnSwitchYCbCr(dType, template string) string {
|
||||
func expnSwitchYCbCr(op, dType, template string) string {
|
||||
lines := []string{
|
||||
"switch src.SubsampleRatio {",
|
||||
"default:",
|
||||
expnLine(template, &data{dType: dType, sType: "image.Image"}),
|
||||
expnLine(template, &data{dType: dType, sType: "image.Image", op: op}),
|
||||
}
|
||||
for _, sratio := range subsampleRatios {
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("case image.YCbCrSubsampleRatio%s:", sratio),
|
||||
expnLine(template, &data{dType: dType, sType: "*image.YCbCr", sratio: sratio}),
|
||||
expnLine(template, &data{dType: dType, sType: "*image.YCbCr", sratio: sratio, op: op}),
|
||||
)
|
||||
}
|
||||
lines = append(lines, "}")
|
||||
|
@ -722,12 +747,16 @@ const (
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: z.scale_Image_Image_Over(dst, dr, adr, src, sr)
|
||||
case Src:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
} else if _, ok := src.(*image.Uniform); ok {
|
||||
// TODO: get the Op from opts.
|
||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
||||
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||
} else {
|
||||
$switch z.scale_$dTypeRN_$sTypeRN$sratio(dst, dr, adr, src, sr)
|
||||
$switch z.scale_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, src, sr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -757,18 +786,22 @@ const (
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case Src:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
} else if u, ok := src.(*image.Uniform); ok {
|
||||
// TODO: get the Op from opts.
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||
} else {
|
||||
$switch z.transform_$dTypeRN_$sTypeRN$sratio(dst, dr, adr, &d2s, src, sr, bias)
|
||||
$switch z.transform_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
codeNNScaleLeaf = `
|
||||
func (nnInterpolator) scale_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, src $sType, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_$dTypeRN_$sTypeRN$sratio_$op(dst $dType, dr, adr image.Rectangle, src $sType, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -787,7 +820,7 @@ const (
|
|||
`
|
||||
|
||||
codeNNTransformLeaf = `
|
||||
func (nnInterpolator) transform_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_$dTypeRN_$sTypeRN$sratio_$op(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, bias image.Point) {
|
||||
$preOuter
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y + int(dy)) + 0.5
|
||||
|
@ -807,7 +840,7 @@ const (
|
|||
`
|
||||
|
||||
codeABLScaleLeaf = `
|
||||
func (ablInterpolator) scale_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, src $sType, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_$dTypeRN_$sTypeRN$sratio_$op(dst $dType, dr, adr image.Rectangle, src $sType, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -861,7 +894,7 @@ const (
|
|||
`
|
||||
|
||||
codeABLTransformLeaf = `
|
||||
func (ablInterpolator) transform_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_$dTypeRN_$sTypeRN$sratio_$op(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, bias image.Point) {
|
||||
$preOuter
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y + int(dy)) + 0.5
|
||||
|
@ -928,8 +961,7 @@ const (
|
|||
}
|
||||
|
||||
if _, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
||||
// TODO: get the Op from opts.
|
||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
||||
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -954,7 +986,7 @@ const (
|
|||
$switchS z.scaleX_$sTypeRN$sratio(tmp, src, sr)
|
||||
}
|
||||
|
||||
$switchD z.scaleY_$dTypeRN(dst, dr, adr, tmp)
|
||||
$switchD z.scaleY_$dTypeRN_$op(dst, dr, adr, tmp)
|
||||
}
|
||||
|
||||
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
|
@ -981,8 +1013,7 @@ const (
|
|||
adr = adr.Sub(dr.Min)
|
||||
|
||||
if u, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
||||
// TODO: get the Op from opts.
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -999,9 +1030,14 @@ const (
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
q.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case Src:
|
||||
q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
} else {
|
||||
$switch q.transform_$dTypeRN_$sTypeRN$sratio(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
$switch q.transform_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
}
|
||||
`
|
||||
|
@ -1029,7 +1065,7 @@ const (
|
|||
`
|
||||
|
||||
codeKernelScaleLeafY = `
|
||||
func (z *kernelScaler) scaleY_$dTypeRN(dst $dType, dr, adr image.Rectangle, tmp [][4]float64) {
|
||||
func (z *kernelScaler) scaleY_$dTypeRN_$op(dst $dType, dr, adr image.Rectangle, tmp [][4]float64) {
|
||||
$preOuter
|
||||
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
|
||||
$preKernelInner
|
||||
|
@ -1050,7 +1086,7 @@ const (
|
|||
`
|
||||
|
||||
codeKernelTransformLeaf = `
|
||||
func (q *Kernel) transform_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_$dTypeRN_$sTypeRN$sratio_$op(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
|
425
draw/impl.go
425
draw/impl.go
|
@ -20,40 +20,47 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: z.scale_Image_Image_Over(dst, dr, adr, src, sr)
|
||||
case Src:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
} else if _, ok := src.(*image.Uniform); ok {
|
||||
// TODO: get the Op from opts.
|
||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
||||
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||
} else {
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.scale_RGBA_Gray(dst, dr, adr, src, sr)
|
||||
case *image.NRGBA:
|
||||
z.scale_RGBA_NRGBA(dst, dr, adr, src, sr)
|
||||
switch opts.op() {
|
||||
case Src:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
z.scale_RGBA_RGBA(dst, dr, adr, src, sr)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.scale_RGBA_Gray_Src(dst, dr, adr, src, sr)
|
||||
case *image.NRGBA:
|
||||
z.scale_RGBA_NRGBA_Src(dst, dr, adr, src, sr)
|
||||
case *image.RGBA:
|
||||
z.scale_RGBA_RGBA_Src(dst, dr, adr, src, sr)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
default:
|
||||
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.scale_RGBA_YCbCr444_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.scale_RGBA_YCbCr422_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.scale_RGBA_YCbCr420_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.scale_RGBA_YCbCr440_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
default:
|
||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.scale_RGBA_YCbCr444(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.scale_RGBA_YCbCr422(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.scale_RGBA_YCbCr420(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.scale_RGBA_YCbCr440(dst, dr, adr, src, sr)
|
||||
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
default:
|
||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
||||
}
|
||||
default:
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,46 +92,53 @@ func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case Src:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
} else if u, ok := src.(*image.Uniform); ok {
|
||||
// TODO: get the Op from opts.
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||
} else {
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.transform_RGBA_Gray(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.NRGBA:
|
||||
z.transform_RGBA_NRGBA(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch opts.op() {
|
||||
case Src:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
z.transform_RGBA_RGBA(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.NRGBA:
|
||||
z.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.RGBA:
|
||||
z.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
default:
|
||||
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
default:
|
||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.transform_RGBA_YCbCr444(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.transform_RGBA_YCbCr422(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.transform_RGBA_YCbCr420(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.transform_RGBA_YCbCr440(dst, dr, adr, &d2s, src, sr, bias)
|
||||
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
default:
|
||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
default:
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle, src *image.Gray, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.Gray, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -145,7 +159,7 @@ func (nnInterpolator) scale_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -168,7 +182,7 @@ func (nnInterpolator) scale_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -191,7 +205,7 @@ func (nnInterpolator) scale_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -234,7 +248,7 @@ func (nnInterpolator) scale_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -277,7 +291,7 @@ func (nnInterpolator) scale_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -320,7 +334,7 @@ func (nnInterpolator) scale_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -363,7 +377,7 @@ func (nnInterpolator) scale_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -382,7 +396,7 @@ func (nnInterpolator) scale_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) scale_Image_Image(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
func (nnInterpolator) scale_Image_Image_Src(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
dw2 := uint64(dr.Dx()) * 2
|
||||
dh2 := uint64(dr.Dy()) * 2
|
||||
sw := uint64(sr.Dx())
|
||||
|
@ -403,7 +417,7 @@ func (nnInterpolator) scale_Image_Image(dst Image, dr, adr image.Rectangle, src
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -425,7 +439,7 @@ func (nnInterpolator) transform_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -449,7 +463,7 @@ func (nnInterpolator) transform_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -473,7 +487,7 @@ func (nnInterpolator) transform_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -517,7 +531,7 @@ func (nnInterpolator) transform_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rec
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -561,7 +575,7 @@ func (nnInterpolator) transform_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rec
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -605,7 +619,7 @@ func (nnInterpolator) transform_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rec
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -649,7 +663,7 @@ func (nnInterpolator) transform_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rec
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -669,7 +683,7 @@ func (nnInterpolator) transform_RGBA_Image(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (nnInterpolator) transform_Image_Image(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
func (nnInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
dstColorRGBA64 := &color.RGBA64{}
|
||||
dstColor := color.Color(dstColorRGBA64)
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
|
@ -701,40 +715,47 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: z.scale_Image_Image_Over(dst, dr, adr, src, sr)
|
||||
case Src:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
} else if _, ok := src.(*image.Uniform); ok {
|
||||
// TODO: get the Op from opts.
|
||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
||||
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||
} else {
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.scale_RGBA_Gray(dst, dr, adr, src, sr)
|
||||
case *image.NRGBA:
|
||||
z.scale_RGBA_NRGBA(dst, dr, adr, src, sr)
|
||||
switch opts.op() {
|
||||
case Src:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
z.scale_RGBA_RGBA(dst, dr, adr, src, sr)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.scale_RGBA_Gray_Src(dst, dr, adr, src, sr)
|
||||
case *image.NRGBA:
|
||||
z.scale_RGBA_NRGBA_Src(dst, dr, adr, src, sr)
|
||||
case *image.RGBA:
|
||||
z.scale_RGBA_RGBA_Src(dst, dr, adr, src, sr)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
default:
|
||||
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.scale_RGBA_YCbCr444_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.scale_RGBA_YCbCr422_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.scale_RGBA_YCbCr420_Src(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.scale_RGBA_YCbCr440_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
default:
|
||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.scale_RGBA_YCbCr444(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.scale_RGBA_YCbCr422(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.scale_RGBA_YCbCr420(dst, dr, adr, src, sr)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.scale_RGBA_YCbCr440(dst, dr, adr, src, sr)
|
||||
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
default:
|
||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
||||
}
|
||||
default:
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -766,46 +787,53 @@ func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case Src:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
} else if u, ok := src.(*image.Uniform); ok {
|
||||
// TODO: get the Op from opts.
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||
} else {
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.transform_RGBA_Gray(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.NRGBA:
|
||||
z.transform_RGBA_NRGBA(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch opts.op() {
|
||||
case Src:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
z.transform_RGBA_RGBA(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
z.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.NRGBA:
|
||||
z.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.RGBA:
|
||||
z.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
default:
|
||||
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
default:
|
||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
z.transform_RGBA_YCbCr444(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
z.transform_RGBA_YCbCr422(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
z.transform_RGBA_YCbCr420(dst, dr, adr, &d2s, src, sr, bias)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
z.transform_RGBA_YCbCr440(dst, dr, adr, &d2s, src, sr, bias)
|
||||
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
default:
|
||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
default:
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle, src *image.Gray, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.Gray, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -868,7 +896,7 @@ func (ablInterpolator) scale_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -963,7 +991,7 @@ func (ablInterpolator) scale_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1058,7 +1086,7 @@ func (ablInterpolator) scale_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1230,7 +1258,7 @@ func (ablInterpolator) scale_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1402,7 +1430,7 @@ func (ablInterpolator) scale_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1574,7 +1602,7 @@ func (ablInterpolator) scale_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1746,7 +1774,7 @@ func (ablInterpolator) scale_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1825,7 +1853,7 @@ func (ablInterpolator) scale_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) scale_Image_Image(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
func (ablInterpolator) scale_Image_Image_Src(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle) {
|
||||
sw := int32(sr.Dx())
|
||||
sh := int32(sr.Dy())
|
||||
yscale := float64(sh) / float64(dr.Dy())
|
||||
|
@ -1906,7 +1934,7 @@ func (ablInterpolator) scale_Image_Image(dst Image, dr, adr image.Rectangle, src
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -1970,7 +1998,7 @@ func (ablInterpolator) transform_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2066,7 +2094,7 @@ func (ablInterpolator) transform_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Recta
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2162,7 +2190,7 @@ func (ablInterpolator) transform_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2335,7 +2363,7 @@ func (ablInterpolator) transform_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Re
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2508,7 +2536,7 @@ func (ablInterpolator) transform_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Re
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2681,7 +2709,7 @@ func (ablInterpolator) transform_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Re
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2854,7 +2882,7 @@ func (ablInterpolator) transform_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Re
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
||||
d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
|
||||
|
@ -2934,7 +2962,7 @@ func (ablInterpolator) transform_RGBA_Image(dst *image.RGBA, dr, adr image.Recta
|
|||
}
|
||||
}
|
||||
|
||||
func (ablInterpolator) transform_Image_Image(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
func (ablInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point) {
|
||||
dstColorRGBA64 := &color.RGBA64{}
|
||||
dstColor := color.Color(dstColorRGBA64)
|
||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||
|
@ -3028,8 +3056,7 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
|
||||
if _, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
||||
// TODO: get the Op from opts.
|
||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
||||
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3076,11 +3103,14 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
}
|
||||
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
z.scaleY_RGBA(dst, dr, adr, tmp)
|
||||
default:
|
||||
z.scaleY_Image(dst, dr, adr, tmp)
|
||||
switch opts.op() {
|
||||
case Src:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
z.scaleY_RGBA_Src(dst, dr, adr, tmp)
|
||||
default:
|
||||
z.scaleY_Image_Src(dst, dr, adr, tmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3108,8 +3138,7 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
|
|||
adr = adr.Sub(dr.Min)
|
||||
|
||||
if u, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
||||
// TODO: get the Op from opts.
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3126,37 +3155,45 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
|
|||
// we cannot use the type-specific fast paths, as they access
|
||||
// the Pix fields directly without bounds checking.
|
||||
if !sr.In(src.Bounds()) {
|
||||
q.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
switch opts.op() {
|
||||
case Over:
|
||||
// TODO: q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case Src:
|
||||
q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
} else {
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
q.transform_RGBA_Gray(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case *image.NRGBA:
|
||||
q.transform_RGBA_NRGBA(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
switch opts.op() {
|
||||
case Src:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
q.transform_RGBA_RGBA(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
switch src := src.(type) {
|
||||
case *image.Gray:
|
||||
q.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case *image.NRGBA:
|
||||
q.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case *image.RGBA:
|
||||
q.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case *image.YCbCr:
|
||||
switch src.SubsampleRatio {
|
||||
default:
|
||||
q.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
q.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
q.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
q.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
q.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
default:
|
||||
q.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
q.transform_RGBA_YCbCr444(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
q.transform_RGBA_YCbCr422(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
q.transform_RGBA_YCbCr420(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
q.transform_RGBA_YCbCr440(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
q.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
default:
|
||||
q.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
default:
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
q.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
switch src := src.(type) {
|
||||
default:
|
||||
q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3449,7 +3486,7 @@ func (z *kernelScaler) scaleX_Image(tmp [][4]float64, src image.Image, sr image.
|
|||
}
|
||||
}
|
||||
|
||||
func (z *kernelScaler) scaleY_RGBA(dst *image.RGBA, dr, adr image.Rectangle, tmp [][4]float64) {
|
||||
func (z *kernelScaler) scaleY_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, tmp [][4]float64) {
|
||||
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
|
||||
d := (dr.Min.Y+adr.Min.Y-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+int(dx)-dst.Rect.Min.X)*4
|
||||
for _, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
|
||||
|
@ -3470,7 +3507,7 @@ func (z *kernelScaler) scaleY_RGBA(dst *image.RGBA, dr, adr image.Rectangle, tmp
|
|||
}
|
||||
}
|
||||
|
||||
func (z *kernelScaler) scaleY_Image(dst Image, dr, adr image.Rectangle, tmp [][4]float64) {
|
||||
func (z *kernelScaler) scaleY_Image_Src(dst Image, dr, adr image.Rectangle, tmp [][4]float64) {
|
||||
dstColorRGBA64 := &color.RGBA64{}
|
||||
dstColor := color.Color(dstColorRGBA64)
|
||||
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
|
||||
|
@ -3492,7 +3529,7 @@ func (z *kernelScaler) scaleY_Image(dst Image, dr, adr image.Rectangle, tmp [][4
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -3591,7 +3628,7 @@ func (q *Kernel) transform_RGBA_Gray(dst *image.RGBA, dr, adr image.Rectangle, d
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -3695,7 +3732,7 @@ func (q *Kernel) transform_RGBA_NRGBA(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -3799,7 +3836,7 @@ func (q *Kernel) transform_RGBA_RGBA(dst *image.RGBA, dr, adr image.Rectangle, d
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -3923,7 +3960,7 @@ func (q *Kernel) transform_RGBA_YCbCr444(dst *image.RGBA, dr, adr image.Rectangl
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -4047,7 +4084,7 @@ func (q *Kernel) transform_RGBA_YCbCr422(dst *image.RGBA, dr, adr image.Rectangl
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -4171,7 +4208,7 @@ func (q *Kernel) transform_RGBA_YCbCr420(dst *image.RGBA, dr, adr image.Rectangl
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -4295,7 +4332,7 @@ func (q *Kernel) transform_RGBA_YCbCr440(dst *image.RGBA, dr, adr image.Rectangl
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
@ -4395,7 +4432,7 @@ func (q *Kernel) transform_RGBA_Image(dst *image.RGBA, dr, adr image.Rectangle,
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) transform_Image_Image(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
func (q *Kernel) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64) {
|
||||
// When shrinking, broaden the effective kernel support so that we still
|
||||
// visit every source pixel.
|
||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||
|
|
|
@ -19,12 +19,12 @@ import (
|
|||
// the part of the destination image defined by dst and the translation of sr
|
||||
// so that sr.Min translates to dp.
|
||||
func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
mask, mp, op := image.Image(nil), image.Point{}, Over
|
||||
mask, mp := image.Image(nil), image.Point{}
|
||||
if opts != nil {
|
||||
// TODO: set mask, mp and op.
|
||||
// TODO: set mask and mp.
|
||||
}
|
||||
dr := sr.Add(dp.Sub(sr.Min))
|
||||
DrawMask(dst, dr, src, sr.Min, mask, mp, op)
|
||||
DrawMask(dst, dr, src, sr.Min, mask, mp, opts.op())
|
||||
}
|
||||
|
||||
// Scaler scales the part of the source image defined by src and sr and writes
|
||||
|
@ -56,10 +56,20 @@ type Transformer interface {
|
|||
//
|
||||
// A nil *Options means to use the default (zero) values of each field.
|
||||
type Options struct {
|
||||
// Op is the compositing operator. The default value is Over.
|
||||
Op Op
|
||||
|
||||
// TODO: add fields a la
|
||||
// https://groups.google.com/forum/#!topic/golang-dev/fgn_xM0aeq4
|
||||
}
|
||||
|
||||
func (o *Options) op() Op {
|
||||
if o == nil {
|
||||
return Over
|
||||
}
|
||||
return o.Op
|
||||
}
|
||||
|
||||
// Interpolator is an interpolation algorithm, when dst and src pixels don't
|
||||
// have a 1:1 correspondence.
|
||||
//
|
||||
|
@ -371,6 +381,7 @@ func transformRect(s2d *f64.Aff3, sr *image.Rectangle) (dr image.Rectangle) {
|
|||
}
|
||||
|
||||
func transform_Uniform(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Uniform, sr image.Rectangle, bias image.Point, op Op) {
|
||||
// TODO: implement op == Over.
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
pr, pg, pb, pa := src.C.RGBA()
|
||||
|
|
|
@ -59,6 +59,9 @@ func testInterp(t *testing.T, w int, h int, direction, srcFilename string) {
|
|||
if err != nil {
|
||||
t.Fatalf("Decode: %v", err)
|
||||
}
|
||||
opts := &Options{
|
||||
Op: Src,
|
||||
}
|
||||
testCases := map[string]Interpolator{
|
||||
"nn": NearestNeighbor,
|
||||
"ab": ApproxBiLinear,
|
||||
|
@ -70,9 +73,9 @@ func testInterp(t *testing.T, w int, h int, direction, srcFilename string) {
|
|||
|
||||
got := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
if direction == "rotate" {
|
||||
q.Transform(got, transformMatrix(40, 10), src, src.Bounds(), nil)
|
||||
q.Transform(got, transformMatrix(40, 10), src, src.Bounds(), opts)
|
||||
} else {
|
||||
q.Scale(got, got.Bounds(), src, src.Bounds(), nil)
|
||||
q.Scale(got, got.Bounds(), src, src.Bounds(), opts)
|
||||
}
|
||||
|
||||
if *genGoldenFiles {
|
||||
|
@ -276,7 +279,7 @@ func TestFastPaths(t *testing.T) {
|
|||
srcGray,
|
||||
srcNRGBA,
|
||||
srcRGBA,
|
||||
srcUniform,
|
||||
srcUnif,
|
||||
srcYCbCr,
|
||||
}
|
||||
var srcs []image.Image
|
||||
|
@ -293,6 +296,9 @@ func TestFastPaths(t *testing.T) {
|
|||
CatmullRom,
|
||||
}
|
||||
blue := image.NewUniform(color.RGBA{0x11, 0x22, 0x44, 0x7f})
|
||||
opts := &Options{
|
||||
Op: Src,
|
||||
}
|
||||
|
||||
for _, dr := range drs {
|
||||
for _, src := range srcs {
|
||||
|
@ -306,11 +312,11 @@ func TestFastPaths(t *testing.T) {
|
|||
|
||||
if transform {
|
||||
m := transformMatrix(2, 1)
|
||||
q.Transform(dst0, m, src, sr, nil)
|
||||
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, nil)
|
||||
q.Transform(dst0, m, src, sr, opts)
|
||||
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, opts)
|
||||
} else {
|
||||
q.Scale(dst0, dr, src, sr, nil)
|
||||
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, nil)
|
||||
q.Scale(dst0, dr, src, sr, opts)
|
||||
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, opts)
|
||||
}
|
||||
|
||||
if !bytes.Equal(dst0.Pix, dst1.Pix) {
|
||||
|
@ -349,7 +355,7 @@ func srcRGBA(boundsHint image.Rectangle) (image.Image, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
func srcUniform(boundsHint image.Rectangle) (image.Image, error) {
|
||||
func srcUnif(boundsHint image.Rectangle) (image.Image, error) {
|
||||
return image.NewUniform(color.RGBA64{0x1234, 0x5555, 0x9181, 0xbeef}), nil
|
||||
}
|
||||
|
||||
|
@ -359,7 +365,7 @@ func srcYCbCr(boundsHint image.Rectangle) (image.Image, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
func srcYCbCrLarge(boundsHint image.Rectangle) (image.Image, error) {
|
||||
func srcLarge(boundsHint image.Rectangle) (image.Image, error) {
|
||||
// 3072 x 2304 is over 7 million pixels at 4:3, comparable to a
|
||||
// 2015 smart-phone camera's output.
|
||||
return srcYCbCr(image.Rect(0, 0, 3072, 2304))
|
||||
|
@ -379,7 +385,7 @@ func srcTux(boundsHint image.Rectangle) (image.Image, error) {
|
|||
return src, nil
|
||||
}
|
||||
|
||||
func benchScale(b *testing.B, srcf func(image.Rectangle) (image.Image, error), w int, h int, q Interpolator) {
|
||||
func benchScale(b *testing.B, w int, h int, op Op, srcf func(image.Rectangle) (image.Image, error), q Interpolator) {
|
||||
dst := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
src, err := srcf(image.Rect(0, 0, 1024, 768))
|
||||
if err != nil {
|
||||
|
@ -392,15 +398,18 @@ func benchScale(b *testing.B, srcf func(image.Rectangle) (image.Image, error), w
|
|||
}); ok {
|
||||
scaler = n.NewScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy())
|
||||
}
|
||||
opts := &Options{
|
||||
Op: op,
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
scaler.Scale(dst, dr, src, sr, nil)
|
||||
scaler.Scale(dst, dr, src, sr, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func benchTform(b *testing.B, srcf func(image.Rectangle) (image.Image, error), w int, h int, q Interpolator) {
|
||||
func benchTform(b *testing.B, w int, h int, op Op, srcf func(image.Rectangle) (image.Image, error), q Interpolator) {
|
||||
dst := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
src, err := srcf(image.Rect(0, 0, 1024, 768))
|
||||
if err != nil {
|
||||
|
@ -408,51 +417,54 @@ func benchTform(b *testing.B, srcf func(image.Rectangle) (image.Image, error), w
|
|||
}
|
||||
sr := src.Bounds()
|
||||
m := transformMatrix(40, 10)
|
||||
opts := &Options{
|
||||
Op: op,
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
q.Transform(dst, m, src, sr, nil)
|
||||
q.Transform(dst, m, src, sr, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkScaleNNLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, NearestNeighbor) }
|
||||
func BenchmarkScaleABLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkScaleBLLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, BiLinear) }
|
||||
func BenchmarkScaleCRLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, CatmullRom) }
|
||||
func BenchmarkScaleNNLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, NearestNeighbor) }
|
||||
func BenchmarkScaleABLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, ApproxBiLinear) }
|
||||
func BenchmarkScaleBLLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, BiLinear) }
|
||||
func BenchmarkScaleCRLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, CatmullRom) }
|
||||
|
||||
func BenchmarkScaleNNDown(b *testing.B) { benchScale(b, srcTux, 120, 80, NearestNeighbor) }
|
||||
func BenchmarkScaleABDown(b *testing.B) { benchScale(b, srcTux, 120, 80, ApproxBiLinear) }
|
||||
func BenchmarkScaleBLDown(b *testing.B) { benchScale(b, srcTux, 120, 80, BiLinear) }
|
||||
func BenchmarkScaleCRDown(b *testing.B) { benchScale(b, srcTux, 120, 80, CatmullRom) }
|
||||
func BenchmarkScaleNNDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, NearestNeighbor) }
|
||||
func BenchmarkScaleABDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, ApproxBiLinear) }
|
||||
func BenchmarkScaleBLDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, BiLinear) }
|
||||
func BenchmarkScaleCRDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, CatmullRom) }
|
||||
|
||||
func BenchmarkScaleNNUp(b *testing.B) { benchScale(b, srcTux, 800, 600, NearestNeighbor) }
|
||||
func BenchmarkScaleABUp(b *testing.B) { benchScale(b, srcTux, 800, 600, ApproxBiLinear) }
|
||||
func BenchmarkScaleBLUp(b *testing.B) { benchScale(b, srcTux, 800, 600, BiLinear) }
|
||||
func BenchmarkScaleCRUp(b *testing.B) { benchScale(b, srcTux, 800, 600, CatmullRom) }
|
||||
func BenchmarkScaleNNUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, NearestNeighbor) }
|
||||
func BenchmarkScaleABUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, ApproxBiLinear) }
|
||||
func BenchmarkScaleBLUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, BiLinear) }
|
||||
func BenchmarkScaleCRUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, CatmullRom) }
|
||||
|
||||
func BenchmarkScaleNNSrcRGBA(b *testing.B) { benchScale(b, srcRGBA, 200, 150, NearestNeighbor) }
|
||||
func BenchmarkScaleNNSrcUniform(b *testing.B) { benchScale(b, srcUniform, 200, 150, NearestNeighbor) }
|
||||
func BenchmarkScaleNNSrcRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcRGBA, NearestNeighbor) }
|
||||
func BenchmarkScaleNNSrcUniform(b *testing.B) { benchScale(b, 200, 150, Src, srcUnif, NearestNeighbor) }
|
||||
|
||||
func BenchmarkTformNNSrcRGBA(b *testing.B) { benchTform(b, srcRGBA, 200, 150, NearestNeighbor) }
|
||||
func BenchmarkTformNNSrcUniform(b *testing.B) { benchTform(b, srcUniform, 200, 150, NearestNeighbor) }
|
||||
func BenchmarkTformNNSrcRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcRGBA, NearestNeighbor) }
|
||||
func BenchmarkTformNNSrcUniform(b *testing.B) { benchTform(b, 200, 150, Src, srcUnif, NearestNeighbor) }
|
||||
|
||||
func BenchmarkScaleABSrcGray(b *testing.B) { benchScale(b, srcGray, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcNRGBA(b *testing.B) { benchScale(b, srcNRGBA, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcRGBA(b *testing.B) { benchScale(b, srcRGBA, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcYCbCr(b *testing.B) { benchScale(b, srcYCbCr, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcGray(b *testing.B) { benchScale(b, 200, 150, Src, srcGray, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcNRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcNRGBA, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcRGBA, ApproxBiLinear) }
|
||||
func BenchmarkScaleABSrcYCbCr(b *testing.B) { benchScale(b, 200, 150, Src, srcYCbCr, ApproxBiLinear) }
|
||||
|
||||
func BenchmarkTformABSrcGray(b *testing.B) { benchTform(b, srcGray, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcNRGBA(b *testing.B) { benchTform(b, srcNRGBA, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcRGBA(b *testing.B) { benchTform(b, srcRGBA, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcYCbCr(b *testing.B) { benchTform(b, srcYCbCr, 200, 150, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcGray(b *testing.B) { benchTform(b, 200, 150, Src, srcGray, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcNRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcNRGBA, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcRGBA, ApproxBiLinear) }
|
||||
func BenchmarkTformABSrcYCbCr(b *testing.B) { benchTform(b, 200, 150, Src, srcYCbCr, ApproxBiLinear) }
|
||||
|
||||
func BenchmarkScaleCRSrcGray(b *testing.B) { benchScale(b, srcGray, 200, 150, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcNRGBA(b *testing.B) { benchScale(b, srcNRGBA, 200, 150, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcRGBA(b *testing.B) { benchScale(b, srcRGBA, 200, 150, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcYCbCr(b *testing.B) { benchScale(b, srcYCbCr, 200, 150, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcGray(b *testing.B) { benchScale(b, 200, 150, Src, srcGray, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcNRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcNRGBA, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcRGBA, CatmullRom) }
|
||||
func BenchmarkScaleCRSrcYCbCr(b *testing.B) { benchScale(b, 200, 150, Src, srcYCbCr, CatmullRom) }
|
||||
|
||||
func BenchmarkTformCRSrcGray(b *testing.B) { benchTform(b, srcGray, 200, 150, CatmullRom) }
|
||||
func BenchmarkTformCRSrcNRGBA(b *testing.B) { benchTform(b, srcNRGBA, 200, 150, CatmullRom) }
|
||||
func BenchmarkTformCRSrcRGBA(b *testing.B) { benchTform(b, srcRGBA, 200, 150, CatmullRom) }
|
||||
func BenchmarkTformCRSrcYCbCr(b *testing.B) { benchTform(b, srcYCbCr, 200, 150, CatmullRom) }
|
||||
func BenchmarkTformCRSrcGray(b *testing.B) { benchTform(b, 200, 150, Src, srcGray, CatmullRom) }
|
||||
func BenchmarkTformCRSrcNRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcNRGBA, CatmullRom) }
|
||||
func BenchmarkTformCRSrcRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcRGBA, CatmullRom) }
|
||||
func BenchmarkTformCRSrcYCbCr(b *testing.B) { benchTform(b, 200, 150, Src, srcYCbCr, CatmullRom) }
|
||||
|
|
Loading…
Reference in New Issue
Block a user