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;
}
});
}
}