draw: distinguish YCbCr fast paths by their chroma subsample ratios.
These code paths aren't actually fast yet. That will be a follow-up change. Change-Id: I814992573cc6af422e49d0ddf336003e662897a5 Reviewed-on: https://go-review.googlesource.com/7791 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
5afc4bbba5
commit
ad68cd9759
64
draw/gen.go
64
draw/gen.go
|
@ -64,8 +64,14 @@ var (
|
||||||
{"*image.RGBA", "image.Image"},
|
{"*image.RGBA", "image.Image"},
|
||||||
{"Image", "image.Image"},
|
{"Image", "image.Image"},
|
||||||
}
|
}
|
||||||
dTypes, sTypes []string
|
dTypes, sTypes []string
|
||||||
sTypesForDType = map[string][]string{}
|
sTypesForDType = map[string][]string{}
|
||||||
|
subsampleRatios = []string{
|
||||||
|
"444",
|
||||||
|
"422",
|
||||||
|
"420",
|
||||||
|
"440",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -88,6 +94,7 @@ func init() {
|
||||||
type data struct {
|
type data struct {
|
||||||
dType string
|
dType string
|
||||||
sType string
|
sType string
|
||||||
|
sratio string
|
||||||
receiver string
|
receiver string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +132,15 @@ func genKernel(w *bytes.Buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 == "" {
|
||||||
|
for _, sratio := range subsampleRatios {
|
||||||
|
e := *d
|
||||||
|
e.sratio = sratio
|
||||||
|
expn(w, code, &e)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, line := range strings.Split(code, "\n") {
|
for _, line := range strings.Split(code, "\n") {
|
||||||
line = expnLine(line, d)
|
line = expnLine(line, d)
|
||||||
if line == ";" {
|
if line == ";" {
|
||||||
|
@ -169,6 +185,8 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
|
||||||
return prefix + d.dType + suffix
|
return prefix + d.dType + suffix
|
||||||
case "dTypeRN":
|
case "dTypeRN":
|
||||||
return prefix + relName(d.dType) + suffix
|
return prefix + relName(d.dType) + suffix
|
||||||
|
case "sratio":
|
||||||
|
return prefix + d.sratio + suffix
|
||||||
case "sType":
|
case "sType":
|
||||||
return prefix + d.sType + suffix
|
return prefix + d.sType + suffix
|
||||||
case "sTypeRN":
|
case "sTypeRN":
|
||||||
|
@ -482,7 +500,11 @@ func expnSwitch(dType string, expandBoth bool, template string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if dType != "" {
|
if dType != "" {
|
||||||
lines = append(lines, expnLine(template, &data{dType: dType, sType: v}))
|
if v == "*image.YCbCr" {
|
||||||
|
lines = append(lines, expnSwitchYCbCr(dType, template))
|
||||||
|
} else {
|
||||||
|
lines = append(lines, expnLine(template, &data{dType: dType, sType: v}))
|
||||||
|
}
|
||||||
} else if !expandBoth {
|
} else if !expandBoth {
|
||||||
lines = append(lines, expnLine(template, &data{dType: v}))
|
lines = append(lines, expnLine(template, &data{dType: v}))
|
||||||
} else {
|
} else {
|
||||||
|
@ -494,6 +516,22 @@ 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 {
|
||||||
|
lines := []string{
|
||||||
|
"switch src.SubsampleRatio {",
|
||||||
|
"default:",
|
||||||
|
expnLine(template, &data{dType: dType, sType: "image.Image"}),
|
||||||
|
}
|
||||||
|
for _, sratio := range subsampleRatios {
|
||||||
|
lines = append(lines,
|
||||||
|
fmt.Sprintf("case image.YCbCrSubsampleRatio%s:", sratio),
|
||||||
|
expnLine(template, &data{dType: dType, sType: "*image.YCbCr", sratio: sratio}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
lines = append(lines, "}")
|
||||||
|
return strings.Join(lines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
func split(s, sep string) (string, string) {
|
func split(s, sep string) (string, string) {
|
||||||
if i := strings.Index(s, sep); i >= 0 {
|
if i := strings.Index(s, sep); i >= 0 {
|
||||||
return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+len(sep):])
|
return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+len(sep):])
|
||||||
|
@ -551,7 +589,7 @@ const (
|
||||||
if !sr.In(src.Bounds()) {
|
if !sr.In(src.Bounds()) {
|
||||||
z.scale_Image_Image(dst, dr, adr, src, sr)
|
z.scale_Image_Image(dst, dr, adr, src, sr)
|
||||||
} else {
|
} else {
|
||||||
$switch z.scale_$dTypeRN_$sTypeRN(dst, dr, adr, src, sr)
|
$switch z.scale_$dTypeRN_$sTypeRN$sratio(dst, dr, adr, src, sr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,13 +607,13 @@ const (
|
||||||
if !sr.In(src.Bounds()) {
|
if !sr.In(src.Bounds()) {
|
||||||
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr)
|
z.transform_Image_Image(dst, dr, adr, &d2s, src, sr)
|
||||||
} else {
|
} else {
|
||||||
$switch z.transform_$dTypeRN_$sTypeRN(dst, dr, adr, &d2s, src, sr)
|
$switch z.transform_$dTypeRN_$sTypeRN$sratio(dst, dr, adr, &d2s, src, sr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
codeNNScaleLeaf = `
|
codeNNScaleLeaf = `
|
||||||
func (nnInterpolator) scale_$dTypeRN_$sTypeRN(dst $dType, dr, adr image.Rectangle, src $sType, sr image.Rectangle) {
|
func (nnInterpolator) scale_$dTypeRN_$sTypeRN$sratio(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())
|
||||||
|
@ -594,7 +632,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeNNTransformLeaf = `
|
codeNNTransformLeaf = `
|
||||||
func (nnInterpolator) transform_$dTypeRN_$sTypeRN(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle) {
|
func (nnInterpolator) transform_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle) {
|
||||||
$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
|
||||||
|
@ -615,7 +653,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeABLScaleLeaf = `
|
codeABLScaleLeaf = `
|
||||||
func (ablInterpolator) scale_$dTypeRN_$sTypeRN(dst $dType, dr, adr image.Rectangle, src $sType, sr image.Rectangle) {
|
func (ablInterpolator) scale_$dTypeRN_$sTypeRN$sratio(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())
|
||||||
|
@ -669,7 +707,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeABLTransformLeaf = `
|
codeABLTransformLeaf = `
|
||||||
func (ablInterpolator) transform_$dTypeRN_$sTypeRN(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle) {
|
func (ablInterpolator) transform_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle) {
|
||||||
$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
|
||||||
|
@ -747,7 +785,7 @@ const (
|
||||||
if !sr.In(src.Bounds()) {
|
if !sr.In(src.Bounds()) {
|
||||||
z.scaleX_Image(tmp, src, sr)
|
z.scaleX_Image(tmp, src, sr)
|
||||||
} else {
|
} else {
|
||||||
$switchS z.scaleX_$sTypeRN(tmp, src, sr)
|
$switchS z.scaleX_$sTypeRN$sratio(tmp, src, sr)
|
||||||
}
|
}
|
||||||
|
|
||||||
$switchD z.scaleY_$dTypeRN(dst, dr, adr, tmp)
|
$switchD z.scaleY_$dTypeRN(dst, dr, adr, tmp)
|
||||||
|
@ -777,13 +815,13 @@ const (
|
||||||
if !sr.In(src.Bounds()) {
|
if !sr.In(src.Bounds()) {
|
||||||
q.transform_Image_Image(dst, dr, adr, &d2s, src, sr, xscale, yscale)
|
q.transform_Image_Image(dst, dr, adr, &d2s, src, sr, xscale, yscale)
|
||||||
} else {
|
} else {
|
||||||
$switch q.transform_$dTypeRN_$sTypeRN(dst, dr, adr, &d2s, src, sr, xscale, yscale)
|
$switch q.transform_$dTypeRN_$sTypeRN$sratio(dst, dr, adr, &d2s, src, sr, xscale, yscale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
codeKernelScaleLeafX = `
|
codeKernelScaleLeafX = `
|
||||||
func (z *kernelScaler) scaleX_$sTypeRN(tmp [][4]float64, src $sType, sr image.Rectangle) {
|
func (z *kernelScaler) scaleX_$sTypeRN$sratio(tmp [][4]float64, src $sType, sr image.Rectangle) {
|
||||||
t := 0
|
t := 0
|
||||||
for y := int32(0); y < z.sh; y++ {
|
for y := int32(0); y < z.sh; y++ {
|
||||||
for _, s := range z.horizontal.sources {
|
for _, s := range z.horizontal.sources {
|
||||||
|
@ -826,7 +864,7 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
codeKernelTransformLeaf = `
|
codeKernelTransformLeaf = `
|
||||||
func (q *Kernel) transform_$dTypeRN_$sTypeRN(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, xscale, yscale float64) {
|
func (q *Kernel) transform_$dTypeRN_$sTypeRN$sratio(dst $dType, dr, adr image.Rectangle, d2s *f64.Aff3, src $sType, sr image.Rectangle, 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
|
||||||
|
|
1041
draw/impl.go
1041
draw/impl.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user