Jelajahi Sumber

clone: inline YCbCr color conversion

Grigory Dryapak 8 tahun lalu
induk
melakukan
88aca01f3e
1 mengubah file dengan 46 tambahan dan 6 penghapusan
  1. 46 6
      clone.go

+ 46 - 6
clone.go

@@ -203,13 +203,53 @@ func copyYCbCr(dst *image.NRGBA, src *image.YCbCr) {
 			for dstX := 0; dstX < dstW; dstX++ {
 				srcX := srcMinX + dstX
 				srcY := srcMinY + dstY
-				siy := src.YOffset(srcX, srcY)
-				sic := src.COffset(srcX, srcY)
-				r, g, b := color.YCbCrToRGB(src.Y[siy], src.Cb[sic], src.Cr[sic])
-				dst.Pix[di+0] = r
-				dst.Pix[di+1] = g
-				dst.Pix[di+2] = b
+
+				siy := (srcY-src.Rect.Min.Y)*src.YStride + (srcX - src.Rect.Min.X)
+
+				var sic int
+				switch src.SubsampleRatio {
+				case image.YCbCrSubsampleRatio444:
+					sic = (srcY-src.Rect.Min.Y)*src.CStride + (srcX - src.Rect.Min.X)
+				case image.YCbCrSubsampleRatio422:
+					sic = (srcY-src.Rect.Min.Y)*src.CStride + (srcX/2 - src.Rect.Min.X/2)
+				case image.YCbCrSubsampleRatio420:
+					sic = (srcY/2-src.Rect.Min.Y/2)*src.CStride + (srcX/2 - src.Rect.Min.X/2)
+				case image.YCbCrSubsampleRatio440:
+					sic = (srcY/2-src.Rect.Min.Y/2)*src.CStride + (srcX - src.Rect.Min.X)
+				default:
+					sic = src.COffset(srcX, srcY)
+				}
+
+				yy1 := int32(src.Y[siy]) * 0x10101
+				cb1 := int32(src.Cb[sic]) - 128
+				cr1 := int32(src.Cr[sic]) - 128
+
+				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)
+				}
+
+				dst.Pix[di+0] = uint8(r)
+				dst.Pix[di+1] = uint8(g)
+				dst.Pix[di+2] = uint8(b)
 				dst.Pix[di+3] = 0xff
+
 				di += 4
 			}
 		}