public static unsafe byte[] ABGRA2YUV420Managed(int width, int height, System.IntPtr scan0) { //Parrallel try { int frameSize = width * height; int chromasize = frameSize / 4; int yIndex = 0; int uIndex = frameSize; int vIndex = frameSize + chromasize; byte[] yuv = new byte[frameSize * 3 / 2]; uint *rgbValues = (uint *)scan0.ToPointer(); int index = 0; unchecked { for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { uint B = (rgbValues[index] & 0xff000000) >> 24; uint G = (rgbValues[index] & 0xff0000) >> 16; uint R = (rgbValues[index] & 0xff00) >> 8; uint a = (rgbValues[index] & 0xff) >> 0; //int yuvC = Utility.RgbYuv.GetYuv(Common.Binary.ReverseU32(rgbValues[index])); uint Y = (uint)(((X * R + M * G + Q * B + sbyte.MaxValue) >> E) + S); uint U = (uint)(((B * R - C * G + OT * B + sbyte.MaxValue) >> E) + sbyte.MaxValue); uint V = (uint)(((OT * R - D * G - Z * B + sbyte.MaxValue) >> E) + sbyte.MaxValue); yuv[yIndex++] = Common.Binary.Clamp((byte)Y, (byte)0, byte.MaxValue);// (byte)((yuvC & 0xff0000) >> 16); // // > 0 && IsEven //If Common.Binary.IsPowerOfTwo(j) && Common.Binary.IsPowerOfTwo(index) if (j % 2 == 0 && index % 2 == 0) { yuv[uIndex++] = Common.Binary.Clamp((byte)U, (byte)0, byte.MaxValue); //(byte)((yuvC & 0xff00) >> 8);// yuv[vIndex++] = Common.Binary.Clamp((byte)V, (byte)0, byte.MaxValue); // (byte)((yuvC & 0xff) >> 0);// } index++; } } return(yuv); } } catch { throw; } }
internal static void MemoryCopy(System.IntPtr dst, System.IntPtr src, int count) { Debug.Assert(dst != src, "dst and src are the same"); Debug.Assert(dst.ToInt64() < src.ToInt64() || src.ToInt64() + count <= dst.ToInt64(), "overlapping region dst"); Debug.Assert(src.ToInt64() < dst.ToInt64() || dst.ToInt64() + count <= src.ToInt64(), "overlapping region src"); Debug.Assert(0 <= count, "negative count"); unsafe { var dstSpan = new System.Span <byte>(dst.ToPointer(), count); var srcSpan = new System.Span <byte>(src.ToPointer(), count); srcSpan.CopyTo(dstSpan); } }
internal static bool MemoryCompare(System.IntPtr buf1, System.IntPtr buf2, int count) { Debug.Assert(buf1 != buf2, "buf1 and buf2 are the same"); Debug.Assert(buf1.ToInt64() < buf2.ToInt64() || buf2.ToInt64() + count <= buf1.ToInt64(), "overlapping region buf1"); Debug.Assert(buf2.ToInt64() < buf1.ToInt64() || buf1.ToInt64() + count <= buf2.ToInt64(), "overlapping region buf2"); Debug.Assert(0 <= count, "negative count"); unsafe { ReadOnlySpan <byte> span1 = new ReadOnlySpan <byte>(buf1.ToPointer(), count); ReadOnlySpan <byte> span2 = new ReadOnlySpan <byte>(buf2.ToPointer(), count); return(!MemoryExtensions.SequenceEqual(span1, span2)); //0 if all count bytes of lhs and rhs are equal. // TODO: confirm condition with tests } }
/// <summary> /// Copies a source image into a destination image using the specified masking image. /// Only pixels in the source image whose corresponding mask image pixels are > 0 /// are copied to the destination image. Only pixels from the srcRect are copied /// to the destination rect. /// </summary> /// <param name="srcImage">Source image</param> /// <param name="srcRect">Source rectangle to copy from</param> /// <param name="dstImage">Destination image</param> /// <param name="dstRect">Destination rectangle to copy to</param> /// <param name="maskImage">Masking image</param> public static void CopyTo(this Image srcImage, Rectangle srcRect, Image dstImage, Rectangle dstRect, Image maskImage) { if (srcRect.Width != dstRect.Width || srcRect.Height != dstRect.Height) { throw new System.Exception("Source and destination rectangles sizes must match"); } if (maskImage != null) { if (srcImage.Width != maskImage.Width || srcImage.Height != maskImage.Height) { throw new System.Exception("Mask image size must match source image size"); } if (maskImage.PixelFormat != PixelFormat.Gray_8bpp) { throw new System.Exception("Mask image must be of type PixelFormat.Gray_8bpp"); } } PixelFormat srcFormat = srcImage.PixelFormat; PixelFormat dstFormat = dstImage.PixelFormat; System.IntPtr srcBuffer = srcImage.ImageData; System.IntPtr dstBuffer = dstImage.ImageData; System.IntPtr maskBuffer = (maskImage != null) ? maskImage.ImageData : System.IntPtr.Zero; unsafe { int srcBytesPerPixel = PixelFormatHelper.GetBytesPerPixel(srcFormat); int dstBytesPerPixel = PixelFormatHelper.GetBytesPerPixel(dstFormat); int maskBytesPerPixel = PixelFormatHelper.GetBytesPerPixel(PixelFormat.Gray_8bpp); byte *srcRow = (byte *)srcBuffer.ToPointer() + (srcRect.Y * srcImage.Stride) + (srcRect.X * srcBytesPerPixel); byte *dstRow = (byte *)dstBuffer.ToPointer() + (dstRect.Y * dstImage.Stride) + (dstRect.X * dstBytesPerPixel); byte *maskRow = null; if (maskImage != null) { maskRow = (byte *)maskBuffer.ToPointer() + (srcRect.Y * maskImage.Stride) + (srcRect.X * maskBytesPerPixel); } for (int i = 0; i < srcRect.Height; i++) { byte *srcCol = srcRow; byte *dstCol = dstRow; byte *maskCol = maskRow; for (int j = 0; j < srcRect.Width; j++) { bool copyPixel = true; if (maskImage != null) { if (*maskCol == 0) { copyPixel = false; } } if (copyPixel) { int red = 0; int green = 0; int blue = 0; int alpha = 255; switch (srcFormat) { case PixelFormat.Gray_8bpp: red = green = blue = srcCol[0]; break; case PixelFormat.Gray_16bpp: red = green = blue = ((ushort *)srcCol)[0]; break; case PixelFormat.BGR_24bpp: blue = srcCol[0]; green = srcCol[1]; red = srcCol[2]; break; case PixelFormat.BGRX_32bpp: blue = srcCol[0]; green = srcCol[1]; red = srcCol[2]; break; case PixelFormat.BGRA_32bpp: blue = srcCol[0]; green = srcCol[1]; red = srcCol[2]; alpha = srcCol[3]; break; case PixelFormat.RGBA_64bpp: red = ((ushort *)srcCol)[0]; green = ((ushort *)srcCol)[1]; blue = ((ushort *)srcCol)[2]; alpha = ((ushort *)srcCol)[3]; break; } switch (dstFormat) { case PixelFormat.Gray_8bpp: dstCol[0] = Image.Rgb2Gray((byte)red, (byte)green, (byte)blue); break; case PixelFormat.Gray_16bpp: ((ushort *)dstCol)[0] = Image.Rgb2Gray((ushort)red, (ushort)green, (ushort)blue); break; case PixelFormat.BGR_24bpp: case PixelFormat.BGRX_32bpp: dstCol[0] = (byte)blue; dstCol[1] = (byte)green; dstCol[2] = (byte)red; break; case PixelFormat.BGRA_32bpp: dstCol[0] = (byte)blue; dstCol[1] = (byte)green; dstCol[2] = (byte)red; dstCol[3] = (byte)alpha; break; case PixelFormat.RGBA_64bpp: ((ushort *)dstCol)[0] = (ushort)red; ((ushort *)dstCol)[1] = (ushort)green; ((ushort *)dstCol)[2] = (ushort)blue; ((ushort *)dstCol)[3] = (ushort)alpha; break; } } srcCol += srcBytesPerPixel; dstCol += dstBytesPerPixel; maskCol += maskBytesPerPixel; } srcRow += srcImage.Stride; dstRow += dstImage.Stride; if (maskImage != null) { maskRow += maskImage.Stride; } } } }