in Sources/Imaging/Microsoft.Psi.Imaging/ImageBase.cs [196:339]
public void CopyTo(IntPtr destination, int width, int height, int stride, PixelFormat pixelFormat)
{
if ((this.width != width) || (this.height != height))
{
throw new InvalidOperationException("Destination image has different size.");
}
// Check if pixel formats are the same. If so, do a straight up copy
if (this.PixelFormat == pixelFormat)
{
if (this.stride == stride)
{
this.image.CopyTo(destination, stride * height);
}
else
{
unsafe
{
int copyLength = (this.stride < stride) ? this.stride : stride;
byte* src = (byte*)this.image.Data.ToPointer();
byte* dst = (byte*)destination.ToPointer();
// copy line by line
for (int i = 0; i < this.height; i++)
{
Buffer.MemoryCopy(src, dst, copyLength, copyLength);
dst += stride;
src += this.stride;
}
}
}
}
else if ((this.pixelFormat == PixelFormat.BGR_24bpp) &&
(pixelFormat == PixelFormat.BGRX_32bpp ||
pixelFormat == PixelFormat.BGRA_32bpp))
{
unsafe
{
byte* src = (byte*)this.image.Data.ToPointer();
byte* dst = (byte*)destination.ToPointer();
Parallel.For(0, this.Height, i =>
{
byte* srcCopy = src + (this.stride * i);
byte* dstCopy = dst + (stride * i);
for (int j = 0; j < this.width; j++)
{
*dstCopy++ = *srcCopy++;
*dstCopy++ = *srcCopy++;
*dstCopy++ = *srcCopy++;
*dstCopy++ = 255;
}
});
}
}
else if ((this.pixelFormat == PixelFormat.BGRX_32bpp) &&
(pixelFormat == PixelFormat.BGR_24bpp))
{
unsafe
{
byte* src = (byte*)this.image.Data.ToPointer();
byte* dst = (byte*)destination.ToPointer();
Parallel.For(0, this.Height, i =>
{
byte* srcCopy = src + (this.stride * i);
byte* dstCopy = dst + (stride * i);
for (int j = 0; j < this.width; j++)
{
*dstCopy++ = *srcCopy++;
*dstCopy++ = *srcCopy++;
*dstCopy++ = *srcCopy++;
srcCopy++;
}
});
}
}
else if ((this.pixelFormat == PixelFormat.BGR_24bpp) &&
(pixelFormat == PixelFormat.Gray_8bpp))
{
unsafe
{
byte* src = (byte*)this.image.Data.ToPointer();
byte* dst = (byte*)destination.ToPointer();
Parallel.For(0, this.Height, i =>
{
byte* srcCopy = src + (this.stride * i);
byte* dstCopy = dst + (stride * i);
for (int j = 0; j < this.width; j++)
{
*dstCopy++ = Operators.Rgb2Gray(srcCopy[2], srcCopy[1], srcCopy[0]);
srcCopy += 3;
}
});
}
}
else if ((this.pixelFormat == PixelFormat.Gray_16bpp) &&
(pixelFormat == PixelFormat.Gray_8bpp))
{
unsafe
{
byte* src = (byte*)this.image.Data.ToPointer();
byte* dst = (byte*)destination.ToPointer();
Parallel.For(0, this.Height, i =>
{
byte* srcCopy = src + (this.stride * i);
byte* dstCopy = dst + (stride * i);
for (int j = 0; j < this.width; j++)
{
// copy msb only
*dstCopy++ = *(srcCopy + 1);
srcCopy += 2;
}
});
}
}
else if ((this.pixelFormat == PixelFormat.Gray_8bpp) &&
(pixelFormat == PixelFormat.Gray_16bpp))
{
unsafe
{
byte* src = (byte*)this.image.Data.ToPointer();
byte* dst = (byte*)destination.ToPointer();
Parallel.For(0, this.Height, i =>
{
byte* srcCopy = src + (this.stride * i);
byte* dstCopy = dst + (stride * i);
for (int j = 0; j < this.width; j++)
{
// dest = (src << 8) | src
*dstCopy++ = *srcCopy;
*dstCopy++ = *srcCopy++;
}
});
}
}
else
{
this.CopyImageSlow(this.image.Data, this.pixelFormat, destination, stride, pixelFormat);
}
}