protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
int pixelSize = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
// processing start and stop X,Y positions
int width = sourceData.Width;
int height = sourceData.Height;
int srcStride = sourceData.Stride;
int dstStride = destinationData.Stride;
int dstOffset = dstStride - width * pixelSize;
// coordinates of source points
double ox, oy, dx1, dy1, dx2, dy2;
int ox1, oy1, ox2, oy2;
// width and height decreased by 1
int ymax = height - 1;
int xmax = width - 1;
byte* src = (byte*)sourceData.ImageData.ToPointer();
byte* dst = (byte*)destinationData.ImageData.ToPointer();
byte* p1, p2, p3, p4;
double xFactor = 2 * Math.PI * xWavesCount / width;
double yFactor = 2 * Math.PI * yWavesCount / height;
// for each line
for (int y = 0; y < height; y++)
{
double yPart = Math.Sin(yFactor * y) * yWavesAmplitude;
// for each pixel
for (int x = 0; x < width; x++)
{
ox = x + yPart;
oy = y + Math.Cos(xFactor * x) * xWavesAmplitude;
// check if the source pixel is inside of image
if ((ox >= 0) && (oy >= 0) && (ox < width) && (oy < height))
{
// perform bilinear interpolation
oy1 = (int)oy;
oy2 = (oy1 == ymax) ? oy1 : oy1 + 1;
dy1 = oy - (double)oy1;
dy2 = 1.0 - dy1;
ox1 = (int)ox;
ox2 = (ox1 == xmax) ? ox1 : ox1 + 1;
dx1 = ox - (double)ox1;
dx2 = 1.0 - dx1;
p1 = src + oy1 * srcStride + ox1 * pixelSize;
p2 = src + oy1 * srcStride + ox2 * pixelSize;
p3 = src + oy2 * srcStride + ox1 * pixelSize;
p4 = src + oy2 * srcStride + ox2 * pixelSize;
for (int i = 0; i < pixelSize; i++, dst++, p1++, p2++, p3++, p4++)
{
*dst = (byte)(
dy2 * (dx2 * (*p1) + dx1 * (*p2)) +
dy1 * (dx2 * (*p3) + dx1 * (*p4)));
}
}
else
{
for (int i = 0; i < pixelSize; i++, dst++)
{
*dst = 0;
}
}
}
dst += dstOffset;
}
}
}