protected override unsafe void ProcessFilter( UnmanagedImage image, Rectangle rect )
{
// skip, if there is nothing to fill
if ( !rect.Contains( startingPoint.X, startingPoint.Y ) || ( tolerance == Color.Black ) )
return;
// save bounding rectangle
startX = rect.Left;
startY = rect.Top;
stopX = rect.Right - 1;
stopY = rect.Bottom - 1;
// save image properties
scan0 = (byte*) image.ImageData.ToPointer( );
stride = image.Stride;
// create map of visited pixels
checkedPixels = new bool[image.Height, image.Width];
pixelsCount = meanR = meanG = meanB = 0;
if ( image.PixelFormat == PixelFormat.Format8bppIndexed )
{
byte startColor= *( (byte*) CoordsToPointerGray( startingPoint.X, startingPoint.Y ) );
minG = (byte) ( Math.Max( 0, startColor - tolerance.G ) );
maxG = (byte) ( Math.Min( 255, startColor + tolerance.G ) );
LinearFloodFill4Gray( startingPoint.X, startingPoint.Y );
// calculate mean value
meanG /= pixelsCount;
byte fillG = (byte) meanG;
// do fill with the mean
byte* src = (byte*) image.ImageData.ToPointer( );
// allign pointer to the first pixel to process
src += ( startY * stride + startX );
int offset = stride - rect.Width;
// for each line
for ( int y = startY; y <= stopY; y++ )
{
// for each pixel
for ( int x = startX; x <= stopX; x++, src++ )
{
if ( checkedPixels[y, x] )
{
*src = fillG;
}
}
src += offset;
}
}
else
{
byte* startColor= (byte*) CoordsToPointerRGB( startingPoint.X, startingPoint.Y );
minR = (byte) ( Math.Max( 0, startColor[RGB.R] - tolerance.R ) );
maxR = (byte) ( Math.Min( 255, startColor[RGB.R] + tolerance.R ) );
minG = (byte) ( Math.Max( 0, startColor[RGB.G] - tolerance.G ) );
maxG = (byte) ( Math.Min( 255, startColor[RGB.G] + tolerance.G ) );
minB = (byte) ( Math.Max( 0, startColor[RGB.B] - tolerance.B ) );
maxB = (byte) ( Math.Min( 255, startColor[RGB.B] + tolerance.B ) );
LinearFloodFill4RGB( startingPoint.X, startingPoint.Y );
// calculate mean value
meanR /= pixelsCount;
meanG /= pixelsCount;
meanB /= pixelsCount;
byte fillR = (byte) meanR;
byte fillG = (byte) meanG;
byte fillB = (byte) meanB;
// do fill with the mean
byte* src = (byte*) image.ImageData.ToPointer( );
// allign pointer to the first pixel to process
src += ( startY * stride + startX * 3);
int offset = stride - rect.Width * 3;
// for each line
for ( int y = startY; y <= stopY; y++ )
{
// for each pixel
for ( int x = startX; x <= stopX; x++, src += 3 )
{
if ( checkedPixels[y, x] )
{
src[RGB.R] = fillR;
src[RGB.G] = fillG;
src[RGB.B] = fillB;
}
}
src += offset;
}
}
}