protected override unsafe void ProcessFilter( UnmanagedImage source, UnmanagedImage destination, Rectangle rect )
{
// processing start and stop X,Y positions
int startX = rect.Left + 1;
int startY = rect.Top + 1;
int stopX = startX + rect.Width - 2;
int stopY = startY + rect.Height - 2;
int dstStride = destination.Stride;
int srcStride = source.Stride;
int dstOffset = dstStride - rect.Width + 2;
int srcOffset = srcStride - rect.Width + 2;
// data pointers
byte* src = (byte*) source.ImageData.ToPointer( );
byte* dst = (byte*) destination.ImageData.ToPointer( );
// allign pointers
src += srcStride * startY + startX;
dst += dstStride * startY + startX;
// variables for gradient calculation
double g, max = 0;
// for each line
for ( int y = startY; y < stopY; y++ )
{
// for each pixel
for ( int x = startX; x < stopX; x++, src++, dst++ )
{
g = Math.Min( 255,
Math.Abs( src[-srcStride - 1] + src[-srcStride + 1]
- src[ srcStride - 1] - src[ srcStride + 1]
+ 2 * ( src[-srcStride] - src[srcStride] ) )
+ Math.Abs( src[-srcStride + 1] + src[srcStride + 1]
- src[-srcStride - 1] - src[srcStride - 1]
+ 2 * ( src[1] - src[-1] ) ) );
if ( g > max )
max = g;
*dst = (byte) g;
}
src += srcOffset;
dst += dstOffset;
}
// do we need scaling
if ( ( scaleIntensity ) && ( max != 255 ) )
{
// make the second pass for intensity scaling
double factor = 255.0 / (double) max;
dst = (byte*) destination.ImageData.ToPointer( );
dst += dstStride * startY + startX;
// for each line
for ( int y = startY; y < stopY; y++ )
{
// for each pixel
for ( int x = startX; x < stopX; x++, dst++ )
{
*dst = (byte) ( factor * ( *dst ) );
}
dst += dstOffset;
}
}
// draw black rectangle to remove those pixels, which were not processed
// (this needs to be done for those cases, when filter is applied "in place" -
// source image is modified instead of creating new copy)
Drawing.Rectangle( destination, rect, Color.Black );
}
}