summaryrefslogtreecommitdiffstats
path: root/src/image/internal/imageutil/impl.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:23:18 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:23:18 +0000
commit43a123c1ae6613b3efeed291fa552ecd909d3acf (patch)
treefd92518b7024bc74031f78a1cf9e454b65e73665 /src/image/internal/imageutil/impl.go
parentInitial commit. (diff)
downloadgolang-1.20-43a123c1ae6613b3efeed291fa552ecd909d3acf.tar.xz
golang-1.20-43a123c1ae6613b3efeed291fa552ecd909d3acf.zip
Adding upstream version 1.20.14.upstream/1.20.14upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/image/internal/imageutil/impl.go')
-rw-r--r--src/image/internal/imageutil/impl.go268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/image/internal/imageutil/impl.go b/src/image/internal/imageutil/impl.go
new file mode 100644
index 0000000..4581dd8
--- /dev/null
+++ b/src/image/internal/imageutil/impl.go
@@ -0,0 +1,268 @@
+// Code generated by go run gen.go; DO NOT EDIT.
+
+package imageutil
+
+import (
+ "image"
+)
+
+// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
+// r.Min in dst aligned with sp in src. It reports whether the draw was
+// successful. If it returns false, no dst pixels were changed.
+//
+// This function assumes that r is entirely within dst's bounds and the
+// translation of r from dst coordinate space to src coordinate space is
+// entirely within src's bounds.
+func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
+ // This function exists in the image/internal/imageutil package because it
+ // is needed by both the image/draw and image/jpeg packages, but it doesn't
+ // seem right for one of those two to depend on the other.
+ //
+ // Another option is to have this code be exported in the image package,
+ // but we'd need to make sure we're totally happy with the API (for the
+ // rest of Go 1 compatibility), and decide if we want to have a more
+ // general purpose DrawToRGBA method for other image types. One possibility
+ // is:
+ //
+ // func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
+ //
+ // in the spirit of the built-in copy function for 1-dimensional slices,
+ // that also allowed a CopyFromRGBA method if needed.
+
+ x0 := (r.Min.X - dst.Rect.Min.X) * 4
+ x1 := (r.Max.X - dst.Rect.Min.X) * 4
+ y0 := r.Min.Y - dst.Rect.Min.Y
+ y1 := r.Max.Y - dst.Rect.Min.Y
+ 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 {
+
+ // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+ yy1 := int32(src.Y[yi]) * 0x10101
+ cb1 := int32(src.Cb[ci]) - 128
+ cr1 := int32(src.Cr[ci]) - 128
+
+ // The bit twiddling below is equivalent to
+ //
+ // r := (yy1 + 91881*cr1) >> 16
+ // if r < 0 {
+ // r = 0
+ // } else if r > 0xff {
+ // r = ^int32(0)
+ // }
+ //
+ // but uses fewer branches and is faster.
+ // Note that the uint8 type conversion in the return
+ // statement will convert ^int32(0) to 0xff.
+ // The code below to compute g and b uses a similar pattern.
+ r := yy1 + 91881*cr1
+ if uint32(r)&0xff000000 == 0 {
+ r >>= 16
+ } else {
+ r = ^(r >> 31)
+ }
+
+ g := yy1 - 22554*cb1 - 46802*cr1
+ if uint32(g)&0xff000000 == 0 {
+ g >>= 16
+ } else {
+ g = ^(g >> 31)
+ }
+
+ b := yy1 + 116130*cb1
+ if uint32(b)&0xff000000 == 0 {
+ b >>= 16
+ } else {
+ b = ^(b >> 31)
+ }
+
+ // use a temp slice to hint to the compiler that a single bounds check suffices
+ rgba := dpix[x : x+4 : len(dpix)]
+ rgba[0] = uint8(r)
+ rgba[1] = uint8(g)
+ rgba[2] = uint8(b)
+ rgba[3] = 255
+ }
+ }
+
+ case image.YCbCrSubsampleRatio422:
+ 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)
+
+ ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
+ for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+ ci := ciBase + sx/2
+
+ // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+ yy1 := int32(src.Y[yi]) * 0x10101
+ cb1 := int32(src.Cb[ci]) - 128
+ cr1 := int32(src.Cr[ci]) - 128
+
+ // The bit twiddling below is equivalent to
+ //
+ // r := (yy1 + 91881*cr1) >> 16
+ // if r < 0 {
+ // r = 0
+ // } else if r > 0xff {
+ // r = ^int32(0)
+ // }
+ //
+ // but uses fewer branches and is faster.
+ // Note that the uint8 type conversion in the return
+ // statement will convert ^int32(0) to 0xff.
+ // The code below to compute g and b uses a similar pattern.
+ r := yy1 + 91881*cr1
+ if uint32(r)&0xff000000 == 0 {
+ r >>= 16
+ } else {
+ r = ^(r >> 31)
+ }
+
+ g := yy1 - 22554*cb1 - 46802*cr1
+ if uint32(g)&0xff000000 == 0 {
+ g >>= 16
+ } else {
+ g = ^(g >> 31)
+ }
+
+ b := yy1 + 116130*cb1
+ if uint32(b)&0xff000000 == 0 {
+ b >>= 16
+ } else {
+ b = ^(b >> 31)
+ }
+
+ // use a temp slice to hint to the compiler that a single bounds check suffices
+ rgba := dpix[x : x+4 : len(dpix)]
+ rgba[0] = uint8(r)
+ rgba[1] = uint8(g)
+ rgba[2] = uint8(b)
+ rgba[3] = 255
+ }
+ }
+
+ case image.YCbCrSubsampleRatio420:
+ 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)
+
+ ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
+ for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+ ci := ciBase + sx/2
+
+ // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+ yy1 := int32(src.Y[yi]) * 0x10101
+ cb1 := int32(src.Cb[ci]) - 128
+ cr1 := int32(src.Cr[ci]) - 128
+
+ // The bit twiddling below is equivalent to
+ //
+ // r := (yy1 + 91881*cr1) >> 16
+ // if r < 0 {
+ // r = 0
+ // } else if r > 0xff {
+ // r = ^int32(0)
+ // }
+ //
+ // but uses fewer branches and is faster.
+ // Note that the uint8 type conversion in the return
+ // statement will convert ^int32(0) to 0xff.
+ // The code below to compute g and b uses a similar pattern.
+ r := yy1 + 91881*cr1
+ if uint32(r)&0xff000000 == 0 {
+ r >>= 16
+ } else {
+ r = ^(r >> 31)
+ }
+
+ g := yy1 - 22554*cb1 - 46802*cr1
+ if uint32(g)&0xff000000 == 0 {
+ g >>= 16
+ } else {
+ g = ^(g >> 31)
+ }
+
+ b := yy1 + 116130*cb1
+ if uint32(b)&0xff000000 == 0 {
+ b >>= 16
+ } else {
+ b = ^(b >> 31)
+ }
+
+ // use a temp slice to hint to the compiler that a single bounds check suffices
+ rgba := dpix[x : x+4 : len(dpix)]
+ rgba[0] = uint8(r)
+ rgba[1] = uint8(g)
+ rgba[2] = uint8(b)
+ rgba[3] = 255
+ }
+ }
+
+ case image.YCbCrSubsampleRatio440:
+ 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/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 {
+
+ // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+ yy1 := int32(src.Y[yi]) * 0x10101
+ cb1 := int32(src.Cb[ci]) - 128
+ cr1 := int32(src.Cr[ci]) - 128
+
+ // The bit twiddling below is equivalent to
+ //
+ // r := (yy1 + 91881*cr1) >> 16
+ // if r < 0 {
+ // r = 0
+ // } else if r > 0xff {
+ // r = ^int32(0)
+ // }
+ //
+ // but uses fewer branches and is faster.
+ // Note that the uint8 type conversion in the return
+ // statement will convert ^int32(0) to 0xff.
+ // The code below to compute g and b uses a similar pattern.
+ r := yy1 + 91881*cr1
+ if uint32(r)&0xff000000 == 0 {
+ r >>= 16
+ } else {
+ r = ^(r >> 31)
+ }
+
+ g := yy1 - 22554*cb1 - 46802*cr1
+ if uint32(g)&0xff000000 == 0 {
+ g >>= 16
+ } else {
+ g = ^(g >> 31)
+ }
+
+ b := yy1 + 116130*cb1
+ if uint32(b)&0xff000000 == 0 {
+ b >>= 16
+ } else {
+ b = ^(b >> 31)
+ }
+
+ // use a temp slice to hint to the compiler that a single bounds check suffices
+ rgba := dpix[x : x+4 : len(dpix)]
+ rgba[0] = uint8(r)
+ rgba[1] = uint8(g)
+ rgba[2] = uint8(b)
+ rgba[3] = 255
+ }
+ }
+
+ default:
+ return false
+ }
+ return true
+}