protected override unsafe void ProcessFilter( UnmanagedImage source, UnmanagedImage destination, Rectangle rect )
{
int pixelSize = Image.GetPixelFormatSize( source.PixelFormat ) / 8;
// processing start and stop X,Y positions
int startX = rect.Left;
int startY = rect.Top;
int stopX = startX + rect.Width;
int stopY = startY + rect.Height;
int srcStride = source.Stride;
int dstStride = destination.Stride;
int dstOffset = dstStride - rect.Width * pixelSize;
// new pixel's position
int ox, oy;
// maximum value for random number generator
int max = radius * 2 + 1;
byte* src = (byte*) source.ImageData.ToPointer( );
byte* dst = (byte*) destination.ImageData.ToPointer( );
byte* p;
// copy source to destination before
if ( srcStride == dstStride )
{
AForge.SystemTools.CopyUnmanagedMemory( dst, src, srcStride * source.Height );
}
else
{
int len = source.Width * pixelSize;
for ( int y = 0, heigh = source.Height; y < heigh; y++ )
{
AForge.SystemTools.CopyUnmanagedMemory(
dst + dstStride * y, src + srcStride * y, len );
}
}
// allign pointer to the first pixel to process
dst += ( startY * dstStride + startX * pixelSize );
// Note:
// It is possible to speed-up this filter creating separate
// loops for RGB and grayscale images.
// for each line
for ( int y = startY; y < stopY; y++ )
{
// for each pixel
for ( int x = startX; x < stopX; x++ )
{
// generate radnom pixel's position
ox = x + rand.Next( max ) - radius;
oy = y + rand.Next( max ) - radius;
// check if the random pixel is inside our image
if ( ( ox >= startX ) && ( oy >= startY ) && ( ox < stopX ) && ( oy < stopY ) )
{
p = src + oy * srcStride + ox * pixelSize;
for ( int i = 0; i < pixelSize; i++, dst++, p++ )
{
*dst = *p;
}
}
else
{
dst += pixelSize;
}
}
dst += dstOffset;
}
}
}