Implement a flood fill.

A flood fill is a way of filling an area using color banks to define the contained area or a target color which "determines" the area (the valley that can be flooded; Wikipedia uses the term target color). It works almost like a water flooding from a point towards the banks (or: inside the valley): if there's a hole in the banks, the flood is not contained and all the image (or all the "connected valleys") get filled.

To accomplish the task, you need to implement just one of the possible algorithms (examples are on Wikipedia). Variations on the theme are allowed (e.g. adding a tolerance parameter or argument for color-matching of the banks or target color).

 
Testing: the basic algorithm is not suitable for truecolor images; a possible test image is the one shown on the right box; you can try to fill the white area, or the black inner circle.

 
PROGRAM MYFILL_DEMO
 
!VAR SP%
 
!$INTEGER
 
CONST IMAGE_WIDTH=320,IMAGE_HEIGHT=200
 
DIM STACK[6000,1]
 
FUNCTION QUEUE_COUNT(X)
   QUEUE_COUNT=SP
END FUNCTION
 
!$INCLUDE="PC.LIB"
 
PROCEDURE QUEUE_INIT
   SP=0
END PROCEDURE
 
PROCEDURE QUEUE_POP(->XX,YY)
    XX=STACK[SP,0]
    YY=STACK[SP,1]
    SP=SP-1
END PROCEDURE
 
PROCEDURE QUEUE_PUSH(XX,YY)
   SP=SP+1
   STACK[SP,0]=XX
   STACK[SP,1]=YY
END PROCEDURE
 
PROCEDURE FLOOD_FILL(XSTART,YSTART,COLORE_PRIMA,COLORE_RIEMP)
  LOCAL XEST,XWEST,YNORD,YSUD,X,Y
  QUEUE_INIT
  QUEUE_PUSH(XSTART,YSTART)
  WHILE (QUEUE_COUNT(0)>0) DO
    QUEUE_POP(->X,Y)
    XWEST=X
    XEST=X
 
    IF Y>0 THEN
      YNORD=Y-1
    ELSE
      YNORD=-1
    END IF
 
    IF Y<IMAGE_HEIGHT-1 THEN
      YSUD=Y+1
    ELSE
      YSUD=-1
    END IF
 
    LOOP
       POINT(XEST+1,Y->ZC%)
       EXIT IF NOT((XEST<IMAGE_WIDTH-1) AND (ZC%=COLORE_PRIMA))
       XEST=XEST+1
    END LOOP
 
    LOOP
       POINT(XWEST-1,Y->ZC%)
       EXIT IF NOT((XWEST>0) AND (ZC%=COLORE_PRIMA))
       XWEST=XWEST-1
    END LOOP
 
    FOR X=XWEST TO XEST DO
      PSET(X,Y,COLORE_RIEMP)
      POINT(X,YNORD->ZC%)
      IF YNORD>=0 AND ZC%=COLORE_PRIMA THEN
          QUEUE_PUSH(X,YNORD)
      END IF
      POINT(X,YSUD->ZC%)
      IF YSUD>=0 AND ZC%=COLORE_PRIMA THEN
          QUEUE_PUSH(X,YSUD)
      END IF
    END FOR
  END WHILE
END PROCEDURE ! Flood_Fill
 
BEGIN
   SCREEN(1)
   CIRCLE(100,100,75,2)
   CIRCLE(120,120,20,2)
   CIRCLE(80,80,15,2)
   CIRCLE(120,80,10,2)
   FLOOD_FILL(100,100,0,1)
END PROGRAM
 