I’m not smart enough to write in a high-level language, but
there are an infinite number of algorithms to handle this. The simplest might be to search backwards from the initial point until the boundary is found. Then you could follow the boundary clockwise, filling in all pixels in each row until the next boundary pixel is found. After each
row is filled, you would jump up one row and search for the boundary one pixel to the left and one to the right. Once you find a row composed solely of boundary pixels, you will have reached the top of that node.
At this point, you must follow the boundary around to the right back down to the initial row to make sure it doesn’t go up again. The bottom half of the fill block should be filled by moving down a row at a time and repeating the same process.
Here are some useful assembly routines:
Assume: EDI points to some pixel
AX = boundary pixel value
DX = fill pixel value
Searching backwards for boundary:
MOV ECX,EDI ;CURRENT LOCATION POINTER TO ECX
SUB ECX,LEFT_ROW_START ;THIS MAY HAVE TO BE CALCULATED
JECXZ ATLEFT ;AT LEFT EDGE
STD ;"DOWN"
SHR ECX,1 ;FORM WORD COUNT
REPNZ SCASW ;BOUNDARY PIXEL FOUND?
CLD ;"UP"
JNZ NOTFND ;NO
INC EDI
INC EDI ;ADJUST TO BOUNDARY PIXEL
The count in ECX may need to be adjusted by 1 to get the correct search count.
Searching forward for boundary:
MOV ECX,RIGHT_ROW_END+2 ;POINT TO ROW END+2
SUB ECX,EDI ;CALCULATE PIXEL COUNT
JECXZ ATRHT ;AT RIGHT EDGE
SHR ECX,1 ;FORM WORD COUNT
REPNZ SCASW ;BOUNDARY PIXEL FOUND?
JNZ NOTFND ;NO
DEC EDI
DEC EDI ;ADJUST TO BOUNDARY PIXEL
Filling a block:
MOV ECX,FILL_COUNT ;THIS WILL BE CALCULATED
MOV EDI,FILL_START ;POINT TO FILL START (CALCULATED)
XCHG EAX,EDX ;FILL VALUE TO AX, BOUNDARY VALUE
TO DX
REP STOSW ;FILL ROW
XCHG EAX,EDX ;FILL VALUE TO DX, BOUNDARY VALUE
TO AX
Adjusting pointer up/down a row:
MOV EBX,PIXELS_PER_ROW
NEG EBX ;IF DOWN
LEA EDI,[EDI+EBX*2] ;ADJUST EDI UP OR DOWN 1 ROW
or
ADD EBX,EBX
ADD EDI,EBX ;DOWN
ADD EBX,EBX
SUB EDI,EBX ;UP