protected override unsafe void ProcessFilter( UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect )
{
// 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 = sourceData.Stride;
int dstStride = destinationData.Stride;
int srcOffset = srcStride - rect.Width;
int dstOffset = dstStride - rect.Width;
// loop and array indexes
int ir, jr, i, j;
// structuring element's radius
int r = size >> 1;
// pixel value
byte dstValue, v;
// structuring element's value
short sv;
// mode values
byte[] hitValue = new byte[3] { 255, 0, 255 };
byte[] missValue = new byte[3] { 0, 0, 0 };
int modeIndex = (int) mode;
// do the job
byte* src = (byte*) sourceData.ImageData.ToPointer( );
byte* dst = (byte*) destinationData.ImageData.ToPointer( );
// allign pointers to the first pixel to process
src += ( startY * srcStride + startX );
dst += ( startY * dstStride + startX );
// for each line
for ( int y = startY; y < stopY; y++ )
{
// for each pixel
for ( int x = startX; x < stopX; x++, src++, dst++ )
{
missValue[1] = missValue[2] = *src;
dstValue = 255;
// for each structuring element's row
for ( i = 0; i < size; i++ )
{
ir = i - r;
// for each structuring element's column
for ( j = 0; j < size; j++ )
{
jr = j - r;
// get structuring element's value
sv = se[i, j];
// skip "don't care" values
if ( sv == -1 )
continue;
// check, if we outside
if (
( y + ir < startY ) || ( y + ir >= stopY ) ||
( x + jr < startX ) || ( x + jr >= stopX )
)
{
// if it so, the result is zero,
// because it was required pixel
dstValue = 0;
break;
}
// get source image value
v = src[ir * srcStride + jr];
if (
( ( sv != 0 ) || ( v != 0 ) ) &&
( ( sv != 1 ) || ( v != 255 ) )
)
{
// failed structuring element mutch
dstValue = 0;
break;
}
}
if ( dstValue == 0 )
break;
}
// result pixel
*dst = ( dstValue == 255 ) ? hitValue[modeIndex] : missValue[modeIndex];
}
src += srcOffset;
dst += dstOffset;
}
}
}