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.

def floodFill(image, x, y, newColor) {
  def matchColor := image[x, y]
  def w := image.width()
  def h := image.height()
 
  /** For any given pixel x,y, this algorithm first fills a contiguous 
      horizontal line segment of pixels containing that pixel, then
      recursively scans the two adjacent rows over the same horizontal 
      interval. Let this be invocation 0, and the immediate recursive 
      invocations be 1, 2, 3, ..., # be pixels of the wrong color, and
      * be where each scan starts; the fill ordering is as follows:
 
      --------------##########-------
      -...1111111111*11####*33333...-
      ###########000*000000000000...-
      -...2222222222*22222##*4444...-
      --------------------##---------
 
      Each invocation returns the x coordinate of the rightmost pixel it filled,
      or x0 if none were.
 
      Since it is recursive, this algorithm is unsuitable for large images
      with small stacks.
    */
  def fillScan(var x0, y) {
    if (y >= 0 && y < h && x0 >= 0 && x0 < w) {
      image[x0, y] := newColor
      var x1 := x0
 
      # Fill rightward
      while (x1 < w - 1 && image.test(x1 + 1, y, matchColor)) {
        x1 += 1
        image[x1, y] := newColor # This could be replaced with a horizontal-line drawing operation
      }
 
      # Fill leftward
      while (x0 > 0 && image.test(x0 - 1, y, matchColor)) {
        x0 -= 1
        image[x0, y] := newColor
      }
 
      if (x0 > x1) { return x0 } # Filled at most center
 
      # x0..x1 is now a run of newly-filled pixels.
 
      # println(`Filled $y $x0..$x1`)
      # println(image)
 
      # Scan the lines above and below
      for ynext in [y - 1, y + 1] {
        if (ynext >= 0 && ynext < h) {
          var x := x0
          while (x <= x1) {
            if (image.test(x, ynext, matchColor)) {
              x := fillScan(x, ynext)
            }
            x += 1
          }
        }
      }
 
      return x1
    } else {
      return x0
    }
  }
 
  fillScan(x, y)
}