protected override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
// get source image size
int width = sourceData.Width;
int height = sourceData.Height;
int srcStride = sourceData.Stride;
int srcPixelSize = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
// get destination image size
int newWidth = destinationData.Width;
int newHeight = destinationData.Height;
int dstStride = destinationData.Stride;
int dstOffset = destinationData.Stride - newWidth * srcPixelSize;
// fill values
byte fillR = fillColor.R;
byte fillG = fillColor.G;
byte fillB = fillColor.B;
byte fillA = fillColor.A;
// Retrieve homography matrix as float array
float[,] H = (float[,])homography;
// do the job
unsafe
{
byte* src = (byte*)sourceData.ImageData.ToPointer();
byte* dst = (byte*)destinationData.ImageData.ToPointer();
// Project the second image
for (int y = 0; y < newHeight; y++)
{
for (int x = 0; x < newWidth; x++, dst += srcPixelSize)
{
double cx = x;
double cy = y;
// projection using homogenous coordinates
double hw = (H[2, 0] * cx + H[2, 1] * cy + H[2, 2]);
double hx = (H[0, 0] * cx + H[0, 1] * cy + H[0, 2]) / hw;
double hy = (H[1, 0] * cx + H[1, 1] * cy + H[1, 2]) / hw;
// coordinate of the nearest point
int ox = (int)(hx);
int oy = (int)(hy);
// validate source pixel's coordinates
if ((ox >= 0) && (oy >= 0) && (ox < width) && (oy < height))
{
int c = oy * srcStride + ox * srcPixelSize;
// just copy the source into the destination image
if (srcPixelSize == 3)
{
// 24bpp
dst[0] = src[c + 0];
dst[1] = src[c + 1];
dst[2] = src[c + 2];
}
else if (srcPixelSize == 4)
{
// 32bpp
dst[0] = src[c + 0];
dst[1] = src[c + 1];
dst[2] = src[c + 2];
dst[3] = src[c + 3];
}
else
{
// 8bpp
dst[0] = src[c];
}
}
else
{
// Fill.
// just copy the source into the destination image
if (srcPixelSize == 3)
{
// 24bpp
dst[0] = fillB;
dst[1] = fillG;
dst[2] = fillR;
}
else if (srcPixelSize == 4)
{
// 32bpp
dst[0] = fillA;
dst[1] = fillB;
dst[2] = fillG;
dst[3] = fillR;
}
else
{
// 8bpp
dst[0] = fillR;
}
}
}
dst += dstOffset;
}
}
}