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
100
draw/gen.go
100
draw/gen.go
|
@ -71,6 +71,7 @@ var (
|
||||||
"420",
|
"420",
|
||||||
"440",
|
"440",
|
||||||
}
|
}
|
||||||
|
ops = []string{"Src"} // TODO: add "Over".
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -95,20 +96,24 @@ type data struct {
|
||||||
sType string
|
sType string
|
||||||
sratio string
|
sratio string
|
||||||
receiver string
|
receiver string
|
||||||
|
op string
|
||||||
}
|
}
|
||||||
|
|
||||||
func gen(w *bytes.Buffer, receiver string, codes ...string) {
|
func gen(w *bytes.Buffer, receiver string, codes ...string) {
|
||||||
expn(w, codeRoot, &data{receiver: receiver})
|
expn(w, codeRoot, &data{receiver: receiver})
|
||||||
for _, code := range codes {
|
for _, code := range codes {
|
||||||
for _, t := range dsTypes {
|
for _, t := range dsTypes {
|
||||||
|
for _, op := range ops {
|
||||||
expn(w, code, &data{
|
expn(w, code, &data{
|
||||||
dType: t.dType,
|
dType: t.dType,
|
||||||
sType: t.sType,
|
sType: t.sType,
|
||||||
receiver: receiver,
|
receiver: receiver,
|
||||||
|
op: op,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func genKernel(w *bytes.Buffer) {
|
func genKernel(w *bytes.Buffer) {
|
||||||
expn(w, codeKernelRoot, &data{})
|
expn(w, codeKernelRoot, &data{})
|
||||||
|
@ -118,17 +123,23 @@ func genKernel(w *bytes.Buffer) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for _, dType := range dTypes {
|
for _, dType := range dTypes {
|
||||||
|
for _, op := range ops {
|
||||||
expn(w, codeKernelScaleLeafY, &data{
|
expn(w, codeKernelScaleLeafY, &data{
|
||||||
dType: dType,
|
dType: dType,
|
||||||
|
op: op,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for _, t := range dsTypes {
|
for _, t := range dsTypes {
|
||||||
|
for _, op := range ops {
|
||||||
expn(w, codeKernelTransformLeaf, &data{
|
expn(w, codeKernelTransformLeaf, &data{
|
||||||
dType: t.dType,
|
dType: t.dType,
|
||||||
sType: t.sType,
|
sType: t.sType,
|
||||||
|
op: op,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func expn(w *bytes.Buffer, code string, d *data) {
|
func expn(w *bytes.Buffer, code string, d *data) {
|
||||||
if d.sType == "*image.YCbCr" && d.sratio == "" {
|
if d.sType == "*image.YCbCr" && d.sratio == "" {
|
||||||
|
@ -192,13 +203,15 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
|
||||||
return prefix + relName(d.sType) + suffix
|
return prefix + relName(d.sType) + suffix
|
||||||
case "receiver":
|
case "receiver":
|
||||||
return prefix + d.receiver + suffix
|
return prefix + d.receiver + suffix
|
||||||
|
case "op":
|
||||||
|
return prefix + d.op + suffix
|
||||||
|
|
||||||
case "switch":
|
case "switch":
|
||||||
return expnSwitch("", true, suffix)
|
return expnSwitch("", "", true, suffix)
|
||||||
case "switchD":
|
case "switchD":
|
||||||
return expnSwitch("", false, suffix)
|
return expnSwitch("", "", false, suffix)
|
||||||
case "switchS":
|
case "switchS":
|
||||||
return expnSwitch("anyDType", false, suffix)
|
return expnSwitch("", "anyDType", false, suffix)
|
||||||
|
|
||||||
case "preOuter":
|
case "preOuter":
|
||||||
switch d.dType {
|
switch d.dType {
|
||||||
|
@ -568,7 +581,19 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
|
||||||
return ""
|
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"
|
switchVar := "dst"
|
||||||
if dType != "" {
|
if dType != "" {
|
||||||
switchVar = "src"
|
switchVar = "src"
|
||||||
|
@ -588,14 +613,14 @@ func expnSwitch(dType string, expandBoth bool, template string) string {
|
||||||
|
|
||||||
if dType != "" {
|
if dType != "" {
|
||||||
if v == "*image.YCbCr" {
|
if v == "*image.YCbCr" {
|
||||||
lines = append(lines, expnSwitchYCbCr(dType, template))
|
lines = append(lines, expnSwitchYCbCr(op, dType, template))
|
||||||
} else {
|
} 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 {
|
} else if !expandBoth {
|
||||||
lines = append(lines, expnLine(template, &data{dType: v}))
|
lines = append(lines, expnLine(template, &data{dType: v, op: op}))
|
||||||
} else {
|
} 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")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func expnSwitchYCbCr(dType, template string) string {
|
func expnSwitchYCbCr(op, dType, template string) string {
|
||||||
lines := []string{
|
lines := []string{
|
||||||
"switch src.SubsampleRatio {",
|
"switch src.SubsampleRatio {",
|
||||||
"default:",
|
"default:",
|
||||||
expnLine(template, &data{dType: dType, sType: "image.Image"}),
|
expnLine(template, &data{dType: dType, sType: "image.Image", op: op}),
|
||||||
}
|
}
|
||||||
for _, sratio := range subsampleRatios {
|
for _, sratio := range subsampleRatios {
|
||||||
lines = append(lines,
|
lines = append(lines,
|
||||||
fmt.Sprintf("case image.YCbCrSubsampleRatio%s:", sratio),
|
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, "}")
|
lines = append(lines, "}")
|
||||||
|
@ -722,12 +747,16 @@ const (
|
||||||
// we cannot use the type-specific fast paths, as they access
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else if _, ok := src.(*image.Uniform); ok {
|
||||||
// TODO: get the Op from opts.
|
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
|
||||||
} else {
|
} 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
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else if u, ok := src.(*image.Uniform); ok {
|
||||||
// TODO: get the Op from opts.
|
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
|
||||||
} else {
|
} 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 = `
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
sw := uint64(sr.Dx())
|
||||||
|
@ -787,7 +820,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeNNTransformLeaf = `
|
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
|
$preOuter
|
||||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y + int(dy)) + 0.5
|
dyf := float64(dr.Min.Y + int(dy)) + 0.5
|
||||||
|
@ -807,7 +840,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeABLScaleLeaf = `
|
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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.Dy())
|
yscale := float64(sh) / float64(dr.Dy())
|
||||||
|
@ -861,7 +894,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeABLTransformLeaf = `
|
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
|
$preOuter
|
||||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y + int(dy)) + 0.5
|
dyf := float64(dr.Min.Y + int(dy)) + 0.5
|
||||||
|
@ -928,8 +961,7 @@ const (
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
if _, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
||||||
// TODO: get the Op from opts.
|
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +986,7 @@ const (
|
||||||
$switchS z.scaleX_$sTypeRN$sratio(tmp, src, sr)
|
$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) {
|
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)
|
adr = adr.Sub(dr.Min)
|
||||||
|
|
||||||
if u, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
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, opts.op())
|
||||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,9 +1030,14 @@ const (
|
||||||
// we cannot use the type-specific fast paths, as they access
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} 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 = `
|
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
|
$preOuter
|
||||||
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
|
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
|
||||||
$preKernelInner
|
$preKernelInner
|
||||||
|
@ -1050,7 +1086,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeKernelTransformLeaf = `
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
||||||
|
|
269
draw/impl.go
269
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
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else if _, ok := src.(*image.Uniform); ok {
|
||||||
// TODO: get the Op from opts.
|
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
|
||||||
} else {
|
} else {
|
||||||
|
switch opts.op() {
|
||||||
|
case Src:
|
||||||
switch dst := dst.(type) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
case *image.Gray:
|
case *image.Gray:
|
||||||
z.scale_RGBA_Gray(dst, dr, adr, src, sr)
|
z.scale_RGBA_Gray_Src(dst, dr, adr, src, sr)
|
||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
z.scale_RGBA_NRGBA(dst, dr, adr, src, sr)
|
z.scale_RGBA_NRGBA_Src(dst, dr, adr, src, sr)
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
z.scale_RGBA_RGBA(dst, dr, adr, src, sr)
|
z.scale_RGBA_RGBA_Src(dst, dr, adr, src, sr)
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
switch src.SubsampleRatio {
|
switch src.SubsampleRatio {
|
||||||
default:
|
default:
|
||||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio444:
|
case image.YCbCrSubsampleRatio444:
|
||||||
z.scale_RGBA_YCbCr444(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr444_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio422:
|
case image.YCbCrSubsampleRatio422:
|
||||||
z.scale_RGBA_YCbCr422(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr422_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio420:
|
case image.YCbCrSubsampleRatio420:
|
||||||
z.scale_RGBA_YCbCr420(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr420_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio440:
|
case image.YCbCrSubsampleRatio440:
|
||||||
z.scale_RGBA_YCbCr440(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr440_Src(dst, dr, adr, src, sr)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
default:
|
default:
|
||||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
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
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else if u, ok := src.(*image.Uniform); ok {
|
||||||
// TODO: get the Op from opts.
|
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
|
||||||
} else {
|
} else {
|
||||||
|
switch opts.op() {
|
||||||
|
case Src:
|
||||||
switch dst := dst.(type) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
case *image.Gray:
|
case *image.Gray:
|
||||||
z.transform_RGBA_Gray(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
z.transform_RGBA_NRGBA(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
z.transform_RGBA_RGBA(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
switch src.SubsampleRatio {
|
switch src.SubsampleRatio {
|
||||||
default:
|
default:
|
||||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio444:
|
case image.YCbCrSubsampleRatio444:
|
||||||
z.transform_RGBA_YCbCr444(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio422:
|
case image.YCbCrSubsampleRatio422:
|
||||||
z.transform_RGBA_YCbCr422(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio420:
|
case image.YCbCrSubsampleRatio420:
|
||||||
z.transform_RGBA_YCbCr420(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio440:
|
case image.YCbCrSubsampleRatio440:
|
||||||
z.transform_RGBA_YCbCr440(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
default:
|
default:
|
||||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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
|
dw2 := uint64(dr.Dx()) * 2
|
||||||
dh2 := uint64(dr.Dy()) * 2
|
dh2 := uint64(dr.Dy()) * 2
|
||||||
sw := uint64(sr.Dx())
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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{}
|
dstColorRGBA64 := &color.RGBA64{}
|
||||||
dstColor := color.Color(dstColorRGBA64)
|
dstColor := color.Color(dstColorRGBA64)
|
||||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
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
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else if _, ok := src.(*image.Uniform); ok {
|
||||||
// TODO: get the Op from opts.
|
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
|
||||||
} else {
|
} else {
|
||||||
|
switch opts.op() {
|
||||||
|
case Src:
|
||||||
switch dst := dst.(type) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
case *image.Gray:
|
case *image.Gray:
|
||||||
z.scale_RGBA_Gray(dst, dr, adr, src, sr)
|
z.scale_RGBA_Gray_Src(dst, dr, adr, src, sr)
|
||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
z.scale_RGBA_NRGBA(dst, dr, adr, src, sr)
|
z.scale_RGBA_NRGBA_Src(dst, dr, adr, src, sr)
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
z.scale_RGBA_RGBA(dst, dr, adr, src, sr)
|
z.scale_RGBA_RGBA_Src(dst, dr, adr, src, sr)
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
switch src.SubsampleRatio {
|
switch src.SubsampleRatio {
|
||||||
default:
|
default:
|
||||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio444:
|
case image.YCbCrSubsampleRatio444:
|
||||||
z.scale_RGBA_YCbCr444(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr444_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio422:
|
case image.YCbCrSubsampleRatio422:
|
||||||
z.scale_RGBA_YCbCr422(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr422_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio420:
|
case image.YCbCrSubsampleRatio420:
|
||||||
z.scale_RGBA_YCbCr420(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr420_Src(dst, dr, adr, src, sr)
|
||||||
case image.YCbCrSubsampleRatio440:
|
case image.YCbCrSubsampleRatio440:
|
||||||
z.scale_RGBA_YCbCr440(dst, dr, adr, src, sr)
|
z.scale_RGBA_YCbCr440_Src(dst, dr, adr, src, sr)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
z.scale_RGBA_Image(dst, dr, adr, src, sr)
|
z.scale_RGBA_Image_Src(dst, dr, adr, src, sr)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
default:
|
default:
|
||||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
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
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else if u, ok := src.(*image.Uniform); ok {
|
||||||
// TODO: get the Op from opts.
|
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, opts.op())
|
||||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
|
||||||
} else {
|
} else {
|
||||||
|
switch opts.op() {
|
||||||
|
case Src:
|
||||||
switch dst := dst.(type) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
case *image.Gray:
|
case *image.Gray:
|
||||||
z.transform_RGBA_Gray(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
z.transform_RGBA_NRGBA(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
z.transform_RGBA_RGBA(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
switch src.SubsampleRatio {
|
switch src.SubsampleRatio {
|
||||||
default:
|
default:
|
||||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio444:
|
case image.YCbCrSubsampleRatio444:
|
||||||
z.transform_RGBA_YCbCr444(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio422:
|
case image.YCbCrSubsampleRatio422:
|
||||||
z.transform_RGBA_YCbCr422(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio420:
|
case image.YCbCrSubsampleRatio420:
|
||||||
z.transform_RGBA_YCbCr420(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
case image.YCbCrSubsampleRatio440:
|
case image.YCbCrSubsampleRatio440:
|
||||||
z.transform_RGBA_YCbCr440(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
z.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias)
|
z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
default:
|
default:
|
||||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias)
|
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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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())
|
sw := int32(sr.Dx())
|
||||||
sh := int32(sr.Dy())
|
sh := int32(sr.Dy())
|
||||||
yscale := float64(sh) / float64(dr.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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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++ {
|
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
||||||
dyf := float64(dr.Min.Y+int(dy)) + 0.5
|
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
|
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{}
|
dstColorRGBA64 := &color.RGBA64{}
|
||||||
dstColor := color.Color(dstColorRGBA64)
|
dstColor := color.Color(dstColorRGBA64)
|
||||||
for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
|
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()) {
|
if _, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
||||||
// TODO: get the Op from opts.
|
Draw(dst, dr, src, src.Bounds().Min, opts.op())
|
||||||
Draw(dst, dr, src, src.Bounds().Min, Src)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3076,11 +3103,14 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch opts.op() {
|
||||||
|
case Src:
|
||||||
switch dst := dst.(type) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
z.scaleY_RGBA(dst, dr, adr, tmp)
|
z.scaleY_RGBA_Src(dst, dr, adr, tmp)
|
||||||
default:
|
default:
|
||||||
z.scaleY_Image(dst, dr, adr, tmp)
|
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)
|
adr = adr.Sub(dr.Min)
|
||||||
|
|
||||||
if u, ok := src.(*image.Uniform); ok && sr.In(src.Bounds()) {
|
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, opts.op())
|
||||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, Src)
|
|
||||||
return
|
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
|
// we cannot use the type-specific fast paths, as they access
|
||||||
// the Pix fields directly without bounds checking.
|
// the Pix fields directly without bounds checking.
|
||||||
if !sr.In(src.Bounds()) {
|
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 {
|
} else {
|
||||||
|
switch opts.op() {
|
||||||
|
case Src:
|
||||||
switch dst := dst.(type) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
case *image.Gray:
|
case *image.Gray:
|
||||||
q.transform_RGBA_Gray(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
q.transform_RGBA_NRGBA(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
q.transform_RGBA_RGBA(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
switch src.SubsampleRatio {
|
switch src.SubsampleRatio {
|
||||||
default:
|
default:
|
||||||
q.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case image.YCbCrSubsampleRatio444:
|
case image.YCbCrSubsampleRatio444:
|
||||||
q.transform_RGBA_YCbCr444(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case image.YCbCrSubsampleRatio422:
|
case image.YCbCrSubsampleRatio422:
|
||||||
q.transform_RGBA_YCbCr422(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case image.YCbCrSubsampleRatio420:
|
case image.YCbCrSubsampleRatio420:
|
||||||
q.transform_RGBA_YCbCr420(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
case image.YCbCrSubsampleRatio440:
|
case image.YCbCrSubsampleRatio440:
|
||||||
q.transform_RGBA_YCbCr440(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
q.transform_RGBA_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
q.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch src := src.(type) {
|
switch src := src.(type) {
|
||||||
default:
|
default:
|
||||||
q.transform_Image_Image(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale)
|
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++ {
|
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
|
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] {
|
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{}
|
dstColorRGBA64 := &color.RGBA64{}
|
||||||
dstColor := color.Color(dstColorRGBA64)
|
dstColor := color.Color(dstColorRGBA64)
|
||||||
for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// When shrinking, broaden the effective kernel support so that we still
|
||||||
// visit every source pixel.
|
// visit every source pixel.
|
||||||
xHalfWidth, xKernelArgScale := q.Support, 1.0
|
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
|
// the part of the destination image defined by dst and the translation of sr
|
||||||
// so that sr.Min translates to dp.
|
// so that sr.Min translates to dp.
|
||||||
func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, opts *Options) {
|
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 {
|
if opts != nil {
|
||||||
// TODO: set mask, mp and op.
|
// TODO: set mask and mp.
|
||||||
}
|
}
|
||||||
dr := sr.Add(dp.Sub(sr.Min))
|
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
|
// 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.
|
// A nil *Options means to use the default (zero) values of each field.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
// Op is the compositing operator. The default value is Over.
|
||||||
|
Op Op
|
||||||
|
|
||||||
// TODO: add fields a la
|
// TODO: add fields a la
|
||||||
// https://groups.google.com/forum/#!topic/golang-dev/fgn_xM0aeq4
|
// 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
|
// Interpolator is an interpolation algorithm, when dst and src pixels don't
|
||||||
// have a 1:1 correspondence.
|
// 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) {
|
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) {
|
switch dst := dst.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
pr, pg, pb, pa := src.C.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 {
|
if err != nil {
|
||||||
t.Fatalf("Decode: %v", err)
|
t.Fatalf("Decode: %v", err)
|
||||||
}
|
}
|
||||||
|
opts := &Options{
|
||||||
|
Op: Src,
|
||||||
|
}
|
||||||
testCases := map[string]Interpolator{
|
testCases := map[string]Interpolator{
|
||||||
"nn": NearestNeighbor,
|
"nn": NearestNeighbor,
|
||||||
"ab": ApproxBiLinear,
|
"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))
|
got := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
if direction == "rotate" {
|
if direction == "rotate" {
|
||||||
q.Transform(got, transformMatrix(40, 10), src, src.Bounds(), nil)
|
q.Transform(got, transformMatrix(40, 10), src, src.Bounds(), opts)
|
||||||
} else {
|
} else {
|
||||||
q.Scale(got, got.Bounds(), src, src.Bounds(), nil)
|
q.Scale(got, got.Bounds(), src, src.Bounds(), opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *genGoldenFiles {
|
if *genGoldenFiles {
|
||||||
|
@ -276,7 +279,7 @@ func TestFastPaths(t *testing.T) {
|
||||||
srcGray,
|
srcGray,
|
||||||
srcNRGBA,
|
srcNRGBA,
|
||||||
srcRGBA,
|
srcRGBA,
|
||||||
srcUniform,
|
srcUnif,
|
||||||
srcYCbCr,
|
srcYCbCr,
|
||||||
}
|
}
|
||||||
var srcs []image.Image
|
var srcs []image.Image
|
||||||
|
@ -293,6 +296,9 @@ func TestFastPaths(t *testing.T) {
|
||||||
CatmullRom,
|
CatmullRom,
|
||||||
}
|
}
|
||||||
blue := image.NewUniform(color.RGBA{0x11, 0x22, 0x44, 0x7f})
|
blue := image.NewUniform(color.RGBA{0x11, 0x22, 0x44, 0x7f})
|
||||||
|
opts := &Options{
|
||||||
|
Op: Src,
|
||||||
|
}
|
||||||
|
|
||||||
for _, dr := range drs {
|
for _, dr := range drs {
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
|
@ -306,11 +312,11 @@ func TestFastPaths(t *testing.T) {
|
||||||
|
|
||||||
if transform {
|
if transform {
|
||||||
m := transformMatrix(2, 1)
|
m := transformMatrix(2, 1)
|
||||||
q.Transform(dst0, m, src, sr, nil)
|
q.Transform(dst0, m, src, sr, opts)
|
||||||
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, nil)
|
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, opts)
|
||||||
} else {
|
} else {
|
||||||
q.Scale(dst0, dr, src, sr, nil)
|
q.Scale(dst0, dr, src, sr, opts)
|
||||||
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, nil)
|
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(dst0.Pix, dst1.Pix) {
|
if !bytes.Equal(dst0.Pix, dst1.Pix) {
|
||||||
|
@ -349,7 +355,7 @@ func srcRGBA(boundsHint image.Rectangle) (image.Image, error) {
|
||||||
return m, nil
|
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
|
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
|
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
|
// 3072 x 2304 is over 7 million pixels at 4:3, comparable to a
|
||||||
// 2015 smart-phone camera's output.
|
// 2015 smart-phone camera's output.
|
||||||
return srcYCbCr(image.Rect(0, 0, 3072, 2304))
|
return srcYCbCr(image.Rect(0, 0, 3072, 2304))
|
||||||
|
@ -379,7 +385,7 @@ func srcTux(boundsHint image.Rectangle) (image.Image, error) {
|
||||||
return src, nil
|
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))
|
dst := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
src, err := srcf(image.Rect(0, 0, 1024, 768))
|
src, err := srcf(image.Rect(0, 0, 1024, 768))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -392,15 +398,18 @@ func benchScale(b *testing.B, srcf func(image.Rectangle) (image.Image, error), w
|
||||||
}); ok {
|
}); ok {
|
||||||
scaler = n.NewScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy())
|
scaler = n.NewScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy())
|
||||||
}
|
}
|
||||||
|
opts := &Options{
|
||||||
|
Op: op,
|
||||||
|
}
|
||||||
|
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
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))
|
dst := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
src, err := srcf(image.Rect(0, 0, 1024, 768))
|
src, err := srcf(image.Rect(0, 0, 1024, 768))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -408,51 +417,54 @@ func benchTform(b *testing.B, srcf func(image.Rectangle) (image.Image, error), w
|
||||||
}
|
}
|
||||||
sr := src.Bounds()
|
sr := src.Bounds()
|
||||||
m := transformMatrix(40, 10)
|
m := transformMatrix(40, 10)
|
||||||
|
opts := &Options{
|
||||||
|
Op: op,
|
||||||
|
}
|
||||||
|
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
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 BenchmarkScaleNNLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, NearestNeighbor) }
|
||||||
func BenchmarkScaleABLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, ApproxBiLinear) }
|
func BenchmarkScaleABLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, ApproxBiLinear) }
|
||||||
func BenchmarkScaleBLLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, BiLinear) }
|
func BenchmarkScaleBLLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, BiLinear) }
|
||||||
func BenchmarkScaleCRLargeDown(b *testing.B) { benchScale(b, srcYCbCrLarge, 200, 150, CatmullRom) }
|
func BenchmarkScaleCRLargeDown(b *testing.B) { benchScale(b, 200, 150, Src, srcLarge, CatmullRom) }
|
||||||
|
|
||||||
func BenchmarkScaleNNDown(b *testing.B) { benchScale(b, srcTux, 120, 80, NearestNeighbor) }
|
func BenchmarkScaleNNDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, NearestNeighbor) }
|
||||||
func BenchmarkScaleABDown(b *testing.B) { benchScale(b, srcTux, 120, 80, ApproxBiLinear) }
|
func BenchmarkScaleABDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, ApproxBiLinear) }
|
||||||
func BenchmarkScaleBLDown(b *testing.B) { benchScale(b, srcTux, 120, 80, BiLinear) }
|
func BenchmarkScaleBLDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, BiLinear) }
|
||||||
func BenchmarkScaleCRDown(b *testing.B) { benchScale(b, srcTux, 120, 80, CatmullRom) }
|
func BenchmarkScaleCRDown(b *testing.B) { benchScale(b, 120, 80, Src, srcTux, CatmullRom) }
|
||||||
|
|
||||||
func BenchmarkScaleNNUp(b *testing.B) { benchScale(b, srcTux, 800, 600, NearestNeighbor) }
|
func BenchmarkScaleNNUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, NearestNeighbor) }
|
||||||
func BenchmarkScaleABUp(b *testing.B) { benchScale(b, srcTux, 800, 600, ApproxBiLinear) }
|
func BenchmarkScaleABUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, ApproxBiLinear) }
|
||||||
func BenchmarkScaleBLUp(b *testing.B) { benchScale(b, srcTux, 800, 600, BiLinear) }
|
func BenchmarkScaleBLUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, BiLinear) }
|
||||||
func BenchmarkScaleCRUp(b *testing.B) { benchScale(b, srcTux, 800, 600, CatmullRom) }
|
func BenchmarkScaleCRUp(b *testing.B) { benchScale(b, 800, 600, Src, srcTux, CatmullRom) }
|
||||||
|
|
||||||
func BenchmarkScaleNNSrcRGBA(b *testing.B) { benchScale(b, srcRGBA, 200, 150, NearestNeighbor) }
|
func BenchmarkScaleNNSrcRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcRGBA, NearestNeighbor) }
|
||||||
func BenchmarkScaleNNSrcUniform(b *testing.B) { benchScale(b, srcUniform, 200, 150, 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 BenchmarkTformNNSrcRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcRGBA, NearestNeighbor) }
|
||||||
func BenchmarkTformNNSrcUniform(b *testing.B) { benchTform(b, srcUniform, 200, 150, 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 BenchmarkScaleABSrcGray(b *testing.B) { benchScale(b, 200, 150, Src, srcGray, ApproxBiLinear) }
|
||||||
func BenchmarkScaleABSrcNRGBA(b *testing.B) { benchScale(b, srcNRGBA, 200, 150, ApproxBiLinear) }
|
func BenchmarkScaleABSrcNRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcNRGBA, ApproxBiLinear) }
|
||||||
func BenchmarkScaleABSrcRGBA(b *testing.B) { benchScale(b, srcRGBA, 200, 150, ApproxBiLinear) }
|
func BenchmarkScaleABSrcRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcRGBA, ApproxBiLinear) }
|
||||||
func BenchmarkScaleABSrcYCbCr(b *testing.B) { benchScale(b, srcYCbCr, 200, 150, 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 BenchmarkTformABSrcGray(b *testing.B) { benchTform(b, 200, 150, Src, srcGray, ApproxBiLinear) }
|
||||||
func BenchmarkTformABSrcNRGBA(b *testing.B) { benchTform(b, srcNRGBA, 200, 150, ApproxBiLinear) }
|
func BenchmarkTformABSrcNRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcNRGBA, ApproxBiLinear) }
|
||||||
func BenchmarkTformABSrcRGBA(b *testing.B) { benchTform(b, srcRGBA, 200, 150, ApproxBiLinear) }
|
func BenchmarkTformABSrcRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcRGBA, ApproxBiLinear) }
|
||||||
func BenchmarkTformABSrcYCbCr(b *testing.B) { benchTform(b, srcYCbCr, 200, 150, 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 BenchmarkScaleCRSrcGray(b *testing.B) { benchScale(b, 200, 150, Src, srcGray, CatmullRom) }
|
||||||
func BenchmarkScaleCRSrcNRGBA(b *testing.B) { benchScale(b, srcNRGBA, 200, 150, CatmullRom) }
|
func BenchmarkScaleCRSrcNRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcNRGBA, CatmullRom) }
|
||||||
func BenchmarkScaleCRSrcRGBA(b *testing.B) { benchScale(b, srcRGBA, 200, 150, CatmullRom) }
|
func BenchmarkScaleCRSrcRGBA(b *testing.B) { benchScale(b, 200, 150, Src, srcRGBA, CatmullRom) }
|
||||||
func BenchmarkScaleCRSrcYCbCr(b *testing.B) { benchScale(b, srcYCbCr, 200, 150, 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 BenchmarkTformCRSrcGray(b *testing.B) { benchTform(b, 200, 150, Src, srcGray, CatmullRom) }
|
||||||
func BenchmarkTformCRSrcNRGBA(b *testing.B) { benchTform(b, srcNRGBA, 200, 150, CatmullRom) }
|
func BenchmarkTformCRSrcNRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcNRGBA, CatmullRom) }
|
||||||
func BenchmarkTformCRSrcRGBA(b *testing.B) { benchTform(b, srcRGBA, 200, 150, CatmullRom) }
|
func BenchmarkTformCRSrcRGBA(b *testing.B) { benchTform(b, 200, 150, Src, srcRGBA, CatmullRom) }
|
||||||
func BenchmarkTformCRSrcYCbCr(b *testing.B) { benchTform(b, srcYCbCr, 200, 150, CatmullRom) }
|
func BenchmarkTformCRSrcYCbCr(b *testing.B) { benchTform(b, 200, 150, Src, srcYCbCr, CatmullRom) }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user