mirror of
https://github.com/golang/go
synced 2024-11-26 09:28:07 -07:00
image/draw: fast-path for 4:4:0 chroma subsampled sources.
R=r CC=golang-dev https://golang.org/cl/6699049
This commit is contained in:
parent
1e6d9f49da
commit
5abf4bdc27
@ -81,9 +81,10 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
|
|||||||
drawNRGBAOver(dst0, r, src0, sp)
|
drawNRGBAOver(dst0, r, src0, sp)
|
||||||
return
|
return
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
drawYCbCr(dst0, r, src0, sp)
|
if drawYCbCr(dst0, r, src0, sp) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if mask0, ok := mask.(*image.Alpha); ok {
|
} else if mask0, ok := mask.(*image.Alpha); ok {
|
||||||
switch src0 := src.(type) {
|
switch src0 := src.(type) {
|
||||||
case *image.Uniform:
|
case *image.Uniform:
|
||||||
@ -104,11 +105,12 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
|
|||||||
drawNRGBASrc(dst0, r, src0, sp)
|
drawNRGBASrc(dst0, r, src0, sp)
|
||||||
return
|
return
|
||||||
case *image.YCbCr:
|
case *image.YCbCr:
|
||||||
drawYCbCr(dst0, r, src0, sp)
|
if drawYCbCr(dst0, r, src0, sp) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
drawRGBA(dst0, r, src, sp, mask, mp, op)
|
drawRGBA(dst0, r, src, sp, mask, mp, op)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -345,7 +347,7 @@ func drawNRGBASrc(dst *image.RGBA, r image.Rectangle, src *image.NRGBA, sp image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) {
|
func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
|
||||||
// An image.YCbCr is always fully opaque, and so if the mask is implicitly nil
|
// An image.YCbCr is always fully opaque, and so if the mask is implicitly nil
|
||||||
// (i.e. fully opaque) then the op is effectively always Src.
|
// (i.e. fully opaque) then the op is effectively always Src.
|
||||||
x0 := (r.Min.X - dst.Rect.Min.X) * 4
|
x0 := (r.Min.X - dst.Rect.Min.X) * 4
|
||||||
@ -353,6 +355,19 @@ func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Po
|
|||||||
y0 := r.Min.Y - dst.Rect.Min.Y
|
y0 := r.Min.Y - dst.Rect.Min.Y
|
||||||
y1 := r.Max.Y - dst.Rect.Min.Y
|
y1 := r.Max.Y - dst.Rect.Min.Y
|
||||||
switch src.SubsampleRatio {
|
switch src.SubsampleRatio {
|
||||||
|
case image.YCbCrSubsampleRatio444:
|
||||||
|
for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
|
||||||
|
dpix := dst.Pix[y*dst.Stride:]
|
||||||
|
yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
|
||||||
|
ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
|
||||||
|
for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
|
||||||
|
rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
|
||||||
|
dpix[x+0] = rr
|
||||||
|
dpix[x+1] = gg
|
||||||
|
dpix[x+2] = bb
|
||||||
|
dpix[x+3] = 255
|
||||||
|
}
|
||||||
|
}
|
||||||
case image.YCbCrSubsampleRatio422:
|
case image.YCbCrSubsampleRatio422:
|
||||||
for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
|
for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
|
||||||
dpix := dst.Pix[y*dst.Stride:]
|
dpix := dst.Pix[y*dst.Stride:]
|
||||||
@ -381,12 +396,11 @@ func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Po
|
|||||||
dpix[x+3] = 255
|
dpix[x+3] = 255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
case image.YCbCrSubsampleRatio440:
|
||||||
// Default to 4:4:4 subsampling.
|
|
||||||
for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
|
for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
|
||||||
dpix := dst.Pix[y*dst.Stride:]
|
dpix := dst.Pix[y*dst.Stride:]
|
||||||
yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
|
yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
|
||||||
ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
|
ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
|
||||||
for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
|
for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
|
||||||
rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
|
rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
|
||||||
dpix[x+0] = rr
|
dpix[x+0] = rr
|
||||||
@ -395,7 +409,10 @@ func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Po
|
|||||||
dpix[x+3] = 255
|
dpix[x+3] = 255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform, mask *image.Alpha, mp image.Point) {
|
func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform, mask *image.Alpha, mp image.Point) {
|
||||||
|
@ -21,6 +21,7 @@ func TestDecodeProgressive(t *testing.T) {
|
|||||||
"../testdata/video-001",
|
"../testdata/video-001",
|
||||||
"../testdata/video-001.q50.420",
|
"../testdata/video-001.q50.420",
|
||||||
"../testdata/video-001.q50.422",
|
"../testdata/video-001.q50.422",
|
||||||
|
"../testdata/video-001.q50.440",
|
||||||
"../testdata/video-001.q50.444",
|
"../testdata/video-001.q50.444",
|
||||||
"../testdata/video-005.gray.q50",
|
"../testdata/video-005.gray.q50",
|
||||||
}
|
}
|
||||||
|
BIN
src/pkg/image/testdata/video-001.q50.440.jpeg
vendored
Normal file
BIN
src/pkg/image/testdata/video-001.q50.440.jpeg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
src/pkg/image/testdata/video-001.q50.440.progressive.jpeg
vendored
Normal file
BIN
src/pkg/image/testdata/video-001.q50.440.progressive.jpeg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
Loading…
Reference in New Issue
Block a user