private unsafe void LinearFloodFill4RGB( IntPoint startPoint )
{
Queue<IntPoint> points = new Queue<IntPoint>( );
points.Enqueue( startingPoint );
while ( points.Count > 0 )
{
IntPoint point = points.Dequeue( );
int x = point.X;
int y = point.Y;
// get image pointer for current (X, Y)
byte* p = (byte*) CoordsToPointerRGB( x, y );
// find left end of line to fill
int leftLineEdge = x;
byte* ptr = p;
while ( true )
{
// fill current pixel
ptr[RGB.R] = fillR;
ptr[RGB.G] = fillG;
ptr[RGB.B] = fillB;
// mark the pixel as checked
checkedPixels[y, leftLineEdge] = true;
leftLineEdge--;
ptr -= 3;
// check if we need to stop on the edge of image or color area
if ( ( leftLineEdge < startX ) || ( checkedPixels[y, leftLineEdge] ) || ( !CheckRGBPixel( ptr ) ) )
break;
}
leftLineEdge++;
// find right end of line to fill
int rightLineEdge = x;
ptr = p;
while ( true )
{
// fill current pixel
ptr[RGB.R] = fillR;
ptr[RGB.G] = fillG;
ptr[RGB.B] = fillB;
// mark the pixel as checked
checkedPixels[y, rightLineEdge] = true;
rightLineEdge++;
ptr += 3;
// check if we need to stop on the edge of image or color area
if ( rightLineEdge > stopX || ( checkedPixels[y, rightLineEdge] ) || ( !CheckRGBPixel( ptr ) ) )
break;
}
rightLineEdge--;
// loop to go up and down
ptr = (byte*) CoordsToPointerRGB( leftLineEdge, y );
bool upperPointIsQueued = false;
bool lowerPointIsQueued = false;
int upperY = y - 1;
int lowerY = y + 1;
for ( int i = leftLineEdge; i <= rightLineEdge; i++, ptr += 3 )
{
// go up
if ( ( y > startY ) && ( !checkedPixels[upperY, i] ) && ( CheckRGBPixel( ptr - stride ) ) )
{
if ( !upperPointIsQueued )
{
points.Enqueue( new IntPoint( i, upperY ) );
upperPointIsQueued = true;
}
}
else
{
upperPointIsQueued = false;
}
// go down
if ( ( y < stopY ) && ( !checkedPixels[lowerY, i] ) && ( CheckRGBPixel( ptr + stride ) ) )
{
if ( !lowerPointIsQueued )
{
points.Enqueue( new IntPoint( i, lowerY ) );
lowerPointIsQueued = true;
}
}
else
{
lowerPointIsQueued = false;
}
}
}
}