private void CopyImageSlow()

in Sources/Imaging/Microsoft.Psi.Imaging/ImageBase.cs [474:624]


        private void CopyImageSlow(IntPtr sourceIntPtr, PixelFormat sourceFormat, IntPtr destinationIntPtr, int destinationStride, PixelFormat destinationFormat)
        {
            unsafe
            {
                int srcBytesPerPixel = sourceFormat.GetBytesPerPixel();
                int dstBytesPerPixel = destinationFormat.GetBytesPerPixel();
                Parallel.For(
                    0,
                    this.Height,
                    i =>
                    {
                        byte* srcCol = (byte*)sourceIntPtr.ToPointer() + (i * this.stride);
                        byte* dstCol = (byte*)destinationIntPtr.ToPointer() + (i * destinationStride);
                        for (int j = 0; j < this.width; j++)
                        {
                            int red;
                            int green;
                            int blue;
                            int alpha;
                            int bits;
                            switch (sourceFormat)
                            {
                                case PixelFormat.Gray_8bpp:
                                    red = green = blue = srcCol[0];
                                    alpha = 255;
                                    bits = 8;
                                    break;

                                case PixelFormat.Gray_16bpp:
                                    red = green = blue = ((ushort*)srcCol)[0];
                                    alpha = 65535;
                                    bits = 16;
                                    break;

                                case PixelFormat.BGR_24bpp:
                                case PixelFormat.BGRX_32bpp:
                                    blue = srcCol[0];
                                    green = srcCol[1];
                                    red = srcCol[2];
                                    alpha = 255;
                                    bits = 8;
                                    break;

                                case PixelFormat.BGRA_32bpp:
                                    blue = srcCol[0];
                                    green = srcCol[1];
                                    red = srcCol[2];
                                    alpha = srcCol[3];
                                    bits = 8;
                                    break;

                                case PixelFormat.RGB_24bpp:
                                    red = srcCol[0];
                                    green = srcCol[1];
                                    blue = srcCol[2];
                                    alpha = 255;
                                    bits = 8;
                                    break;

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

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

                            // Convert from 8-bits-per-channel (0-255) to 16-bits-per-channel (0-65535) and visa versa when needed.
                            switch (destinationFormat)
                            {
                                case PixelFormat.Gray_8bpp:
                                case PixelFormat.BGR_24bpp:
                                case PixelFormat.BGRX_32bpp:
                                case PixelFormat.BGRA_32bpp:
                                case PixelFormat.RGB_24bpp:
                                    if (bits == 16)
                                    {
                                        red >>= 8;
                                        green >>= 8;
                                        blue >>= 8;
                                        alpha >>= 8;
                                    }

                                    break;

                                case PixelFormat.Gray_16bpp:
                                case PixelFormat.RGBA_64bpp:
                                    if (bits == 8)
                                    {
                                        red = (red << 8) | red;
                                        green = (green << 8) | green;
                                        blue = (blue << 8) | blue;
                                        alpha = (alpha << 8) | alpha;
                                    }

                                    break;
                            }

                            switch (destinationFormat)
                            {
                                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;
                                    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(ExceptionDescriptionUnexpectedPixelFormat);
                            }

                            srcCol += srcBytesPerPixel;
                            dstCol += dstBytesPerPixel;
                        }
                    });
            }
        }