protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
// get width and height
int width = sourceData.Width;
int height = sourceData.Height;
PixelFormat srcPixelFormat = sourceData.PixelFormat;
if (
(srcPixelFormat == PixelFormat.Format24bppRgb) ||
(srcPixelFormat == PixelFormat.Format32bppRgb) ||
(srcPixelFormat == PixelFormat.Format32bppArgb))
{
int pixelSize = (srcPixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
int srcOffset = sourceData.Stride - width * pixelSize;
int dstOffset = destinationData.Stride - width;
int rc = (int)(0x10000 * RedCoefficient);
int gc = (int)(0x10000 * GreenCoefficient);
int bc = (int)(0x10000 * BlueCoefficient);
// make sure sum of coefficients equals to 0x10000
while (rc + gc + bc < 0x10000)
{
bc++;
}
// do the job
byte* src = (byte*)sourceData.ImageData.ToPointer();
byte* dst = (byte*)destinationData.ImageData.ToPointer();
// for each line
for (int y = 0; y < height; y++)
{
// for each pixel
for (int x = 0; x < width; x++, src += pixelSize, dst++)
{
*dst = (byte)((rc * src[RGB.R] + gc * src[RGB.G] + bc * src[RGB.B]) >> 16);
}
src += srcOffset;
dst += dstOffset;
}
}
else
{
int pixelSize = (srcPixelFormat == PixelFormat.Format48bppRgb) ? 3 : 4;
byte* srcBase = (byte*)sourceData.ImageData.ToPointer();
byte* dstBase = (byte*)destinationData.ImageData.ToPointer();
int srcStride = sourceData.Stride;
int dstStride = destinationData.Stride;
// for each line
for (int y = 0; y < height; y++)
{
ushort* src = (ushort*)(srcBase + y * srcStride);
ushort* dst = (ushort*)(dstBase + y * dstStride);
// for each pixel
for (int x = 0; x < width; x++, src += pixelSize, dst++)
{
*dst = (ushort)(RedCoefficient * src[RGB.R] + GreenCoefficient * src[RGB.G] + BlueCoefficient * src[RGB.B]);
}
}
}
}
}