public static void CopyTo()

in Sources/Imaging/Microsoft.Psi.Imaging/ImageExtensions.cs [1623:1803]


        public static void CopyTo(this Image srcImage, Rectangle srcRect, Image destImage, Point destTopLeftCorner, Image maskImage)
        {
            if (destImage.PixelFormat != srcImage.PixelFormat)
            {
                throw new ArgumentOutOfRangeException("destImage.PixelFormat", "destination image pixel format doesn't match source image pixel format");
            }

            if (maskImage != null)
            {
                if (srcImage.Width != maskImage.Width || srcImage.Height != maskImage.Height)
                {
                    throw new ArgumentException("Mask image size must match source image size");
                }

                if (maskImage.PixelFormat != PixelFormat.Gray_8bpp)
                {
                    throw new ArgumentException("Mask image must be of type PixelFormat.Gray_8bpp");
                }
            }

            // Clip source rectangle against source image size
            int srcX = (srcRect.X < 0) ? 0 : srcRect.X;
            int srcY = (srcRect.Y < 0) ? 0 : srcRect.Y;
            int srcW = (srcRect.X + srcRect.Width > srcImage.Width) ? (srcImage.Width - srcRect.X) : srcRect.Width;
            int srcH = (srcRect.Y + srcRect.Height > srcImage.Height) ? (srcImage.Height - srcRect.Y) : srcRect.Height;

            // Clip destination point against destination image
            int dstX = (destTopLeftCorner.X < 0) ? 0 : destTopLeftCorner.X;
            int dstY = (destTopLeftCorner.Y < 0) ? 0 : destTopLeftCorner.Y;
            dstX = (dstX >= destImage.Width) ? destImage.Width - 1 : dstX;
            dstY = (dstY >= destImage.Height) ? destImage.Height - 1 : dstY;

            // Next clip further if rect of that size would lie outside the destination image
            srcW = (dstX + srcW > destImage.Width) ? (destImage.Width - dstX) : srcW;
            srcH = (dstY + srcH > destImage.Height) ? (destImage.Height - dstY) : srcH;

            PixelFormat srcFormat = srcImage.PixelFormat;
            PixelFormat dstFormat = destImage.PixelFormat;
            System.IntPtr sourceBuffer = srcImage.ImageData;
            System.IntPtr destBuffer = destImage.ImageData;
            System.IntPtr maskBuffer = (maskImage != null) ? maskImage.ImageData : System.IntPtr.Zero;
            unsafe
            {
                int srcBytesPerPixel = srcFormat.GetBytesPerPixel();
                int dstBytesPerPixel = dstFormat.GetBytesPerPixel();
                int maskBytesPerPixel = PixelFormat.Gray_8bpp.GetBytesPerPixel();
                byte* srcRow = (byte*)sourceBuffer.ToPointer() + (srcY * srcImage.Stride) + (srcX * srcBytesPerPixel);
                byte* dstRow = (byte*)destBuffer.ToPointer() + (dstY * destImage.Stride) + (dstX * dstBytesPerPixel);
                byte* maskRow = null;
                if (maskImage != null)
                {
                    maskRow = (byte*)maskBuffer.ToPointer() + (srcY * maskImage.Stride) + (srcX * maskBytesPerPixel);
                }

                for (int i = 0; i < srcH; i++)
                {
                    byte* srcCol = srcRow;
                    byte* dstCol = dstRow;
                    byte* maskCol = maskRow;
                    for (int j = 0; j < srcW; 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.RGB_24bpp:
                                    red = srcCol[0];
                                    green = srcCol[1];
                                    blue = srcCol[2];
                                    break;

                                case PixelFormat.RGBA_64bpp:
                                    red = ((ushort*)srcCol)[0];
                                    green = ((ushort*)srcCol)[1];
                                    blue = ((ushort*)srcCol)[2];
                                    alpha = ((ushort*)srcCol)[3];
                                    break;

                                case PixelFormat.Undefined:
                                default:
                                    throw new ArgumentException(Image.ExceptionDescriptionUnexpectedPixelFormat);
                            }

                            switch (dstFormat)
                            {
                                case PixelFormat.Gray_8bpp:
                                    dstCol[0] = Operators.Rgb2Gray((byte)red, (byte)green, (byte)blue);
                                    break;

                                case PixelFormat.Gray_16bpp:
                                    ((ushort*)dstCol)[0] = Operators.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;
                                    dstCol[3] = 255;
                                    break;

                                case PixelFormat.BGRA_32bpp:
                                    dstCol[0] = (byte)blue;
                                    dstCol[1] = (byte)green;
                                    dstCol[2] = (byte)red;
                                    dstCol[3] = (byte)alpha;
                                    break;

                                case PixelFormat.RGB_24bpp:
                                    dstCol[0] = (byte)red;
                                    dstCol[1] = (byte)green;
                                    dstCol[2] = (byte)blue;
                                    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;

                                case PixelFormat.Undefined:
                                default:
                                    throw new ArgumentException(Image.ExceptionDescriptionUnexpectedPixelFormat);
                            }
                        }

                        srcCol += srcBytesPerPixel;
                        dstCol += dstBytesPerPixel;
                        maskCol += maskBytesPerPixel;
                    }

                    srcRow += srcImage.Stride;
                    dstRow += destImage.Stride;
                    if (maskImage != null)
                    {
                        maskRow += maskImage.Stride;
                    }
                }
            }
        }