protected override unsafe void ProcessFilter( UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect )
{
PixelFormat pixelFormat = sourceData.PixelFormat;
// 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;
// structuring element's radius
int r = size >> 1;
if ( ( pixelFormat == PixelFormat.Format8bppIndexed ) || ( pixelFormat == PixelFormat.Format24bppRgb ) )
{
int pixelSize = ( pixelFormat == PixelFormat.Format8bppIndexed ) ? 1 : 3;
int dstStride = destinationData.Stride;
int srcStride = sourceData.Stride;
// base pointers
byte* baseSrc = (byte*) sourceData.ImageData.ToPointer( );
byte* baseDst = (byte*) destinationData.ImageData.ToPointer( );
// allign pointers by X
baseSrc += ( startX * pixelSize );
baseDst += ( startX * pixelSize );
if ( pixelFormat == PixelFormat.Format8bppIndexed )
{
// grayscale image
// compute each line
for ( int y = startY; y < stopY; y++ )
{
byte* src = baseSrc + y * srcStride;
byte* dst = baseDst + y * dstStride;
byte max, v;
// loop and array indexes
int t, ir, jr, i, j;
// for each pixel
for ( int x = startX; x < stopX; x++, src++, dst++ )
{
max = 0;
// for each structuring element's row
for ( i = 0; i < size; i++ )
{
ir = i - r;
t = y + ir;
// skip row
if ( t < startY )
continue;
// break
if ( t >= stopY )
break;
// for each structuring slement's column
for ( j = 0; j < size; j++ )
{
jr = j - r;
t = x + jr;
// skip column
if ( t < startX )
continue;
if ( t < stopX )
{
if ( se[i, j] == 1 )
{
// get new MAX value
v = src[ir * srcStride + jr];
if ( v > max )
max = v;
}
}
}
}
// result pixel
*dst = max;
}
}
}
else
{
// 24 bpp color image
// compute each line
for ( int y = startY; y < stopY; y++ )
{
byte* src = baseSrc + y * srcStride;
byte* dst = baseDst + y * dstStride;
byte maxR, maxG, maxB, v;
byte* p;
// loop and array indexes
int t, ir, jr, i, j;
// for each pixel
for ( int x = startX; x < stopX; x++, src += 3, dst += 3 )
{
maxR = maxG = maxB = 0;
// for each structuring element's row
for ( i = 0; i < size; i++ )
{
ir = i - r;
t = y + ir;
// skip row
if ( t < startY )
continue;
// break
if ( t >= stopY )
break;
// for each structuring element's column
for ( j = 0; j < size; j++ )
{
jr = j - r;
t = x + jr;
// skip column
if ( t < startX )
continue;
if ( t < stopX )
{
if ( se[i, j] == 1 )
{
// get new MAX values
p = &src[ir * srcStride + jr * 3];
// red
v = p[RGB.R];
if ( v > maxR )
maxR = v;
// green
v = p[RGB.G];
if ( v > maxG )
maxG = v;
// blue
v = p[RGB.B];
if ( v > maxB )
maxB = v;
}
}
}
}
// result pixel
dst[RGB.R] = maxR;
dst[RGB.G] = maxG;
dst[RGB.B] = maxB;
}
}
}
}
else
{
int pixelSize = ( pixelFormat == PixelFormat.Format16bppGrayScale ) ? 1 : 3;
int dstStride = destinationData.Stride / 2;
int srcStride = sourceData.Stride / 2;
// base pointers
ushort* baseSrc = (ushort*) sourceData.ImageData.ToPointer( );
ushort* baseDst = (ushort*) destinationData.ImageData.ToPointer( );
// allign pointers by X
baseSrc += ( startX * pixelSize );
baseDst += ( startX * pixelSize );
if ( pixelFormat == PixelFormat.Format16bppGrayScale )
{
// 16 bpp grayscale image
// compute each line
for( int y = startY; y < stopY; y++ )
{
ushort* src = baseSrc + y * srcStride;
ushort* dst = baseDst + y * dstStride;
ushort max, v;
// loop and array indexes
int t, ir, jr, i, j;
// for each pixel
for ( int x = startX; x < stopX; x++, src++, dst++ )
{
max = 0;
// for each structuring element's row
for ( i = 0; i < size; i++ )
{
ir = i - r;
t = y + ir;
// skip row
if ( t < startY )
continue;
// break
if ( t >= stopY )
break;
// for each structuring slement's column
for ( j = 0; j < size; j++ )
{
jr = j - r;
t = x + jr;
// skip column
if ( t < startX )
continue;
if ( t < stopX )
{
if ( se[i, j] == 1 )
{
// get new MAX value
v = src[ir * srcStride + jr];
if ( v > max )
max = v;
}
}
}
}
// result pixel
*dst = max;
}
}
}
else
{
// 48 bpp color image
// compute each line
for( int y = startY; y < stopY; y++ )
{
ushort* src = baseSrc + y * srcStride;
ushort* dst = baseDst + y * dstStride;
ushort maxR, maxG, maxB, v;
ushort* p;
// loop and array indexes
int t, ir, jr, i, j;
// for each pixel
for ( int x = startX; x < stopX; x++, src += 3, dst += 3 )
{
maxR = maxG = maxB = 0;
// for each structuring element's row
for ( i = 0; i < size; i++ )
{
ir = i - r;
t = y + ir;
// skip row
if ( t < startY )
continue;
// break
if ( t >= stopY )
break;
// for each structuring element's column
for ( j = 0; j < size; j++ )
{
jr = j - r;
t = x + jr;
// skip column
if ( t < startX )
continue;
if ( t < stopX )
{
if ( se[i, j] == 1 )
{
// get new MAX values
p = &src[ir * srcStride + jr * 3];
// red
v = p[RGB.R];
if ( v > maxR )
maxR = v;
// green
v = p[RGB.G];
if ( v > maxG )
maxG = v;
// blue
v = p[RGB.B];
if ( v > maxB )
maxB = v;
}
}
}
}
// result pixel
dst[RGB.R] = maxR;
dst[RGB.G] = maxG;
dst[RGB.B] = maxB;
}
}
}
}
}
}