title: iOS Swift Flood fill algorithm
body: <p>I created this extension for "bucket fill" (flood fill) of touch point:</p>
  
  <pre><code>extension UIImageView {
  
      func bucketFill(startPoint: CGPoint, newColor: UIColor) {
          var newRed, newGreen, newBlue, newAlpha: CUnsignedChar
  
          let pixelsWide = CGImageGetWidth(self.image!.CGImage)
          let pixelsHigh = CGImageGetHeight(self.image!.CGImage)
          let rect = CGRect(x:0, y:0, width:Int(pixelsWide), height:Int(pixelsHigh))
  
          let bitmapBytesPerRow = Int(pixelsWide) * 4
  
  
          var context = self.image!.createARGBBitmapContext()
  
          //Clear the context
          CGContextClearRect(context, rect)
  
          // Draw the image to the bitmap context. Once we draw, the memory
          // allocated for the context for rendering will then contain the
          // raw image data in the specified color space.
          CGContextDrawImage(context, rect, self.image!.CGImage)
  
          var data = CGBitmapContextGetData(context)
          var dataType = UnsafeMutablePointer&lt;UInt8&gt;(data)
  
          let newColorRef = CGColorGetComponents(newColor.CGColor)
          if(CGColorGetNumberOfComponents(newColor.CGColor) == 2) {
              newRed = CUnsignedChar(newColorRef[0] * 255) // CUnsignedChar
              newGreen = CUnsignedChar(newColorRef[0] * 255)
              newBlue = CUnsignedChar(newColorRef[0] * 255)
              newAlpha = CUnsignedChar(newColorRef[1])
          } else {
              newRed = CUnsignedChar(newColorRef[0] * 255)
              newGreen = CUnsignedChar(newColorRef[1] * 255)
              newBlue = CUnsignedChar(newColorRef[2] * 255)
              newAlpha = CUnsignedChar(newColorRef[3])
          }
          let newColorStr = ColorRGB(red: newRed, green: newGreen, blue: newBlue)
  
          var stack = Stack()
  
          let offset = 4*((Int(pixelsWide) * Int(startPoint.y)) + Int(startPoint.x))
          //let alpha = dataType[offset]
          let startRed: UInt8 = dataType[offset+1]
          let startGreen: UInt8 = dataType[offset+2]
          let startBlue: UInt8 = dataType[offset+3]
  
          stack.push(startPoint)
  
          while(!stack.isEmpty()) {
  
              let point: CGPoint = stack.pop() as! CGPoint
  
              let offset = 4*((Int(pixelsWide) * Int(point.y)) + Int(point.x))
              let alpha = dataType[offset]
              let red: UInt8 = dataType[offset+1]
              let green: UInt8 = dataType[offset+2]
              let blue: UInt8 = dataType[offset+3]
  
              if (red == newRed &amp;&amp; green == newGreen &amp;&amp; blue == newBlue) {
                  continue
              }
  
              if (red.absoluteDifference(startRed) &lt; 4 &amp;&amp; green.absoluteDifference(startGreen) &lt; 4 &amp;&amp; blue.absoluteDifference(startBlue) &lt; 4) {
  
                  dataType[offset] = 255
                  dataType[offset + 1] = newRed
                  dataType[offset + 2] = newGreen
                  dataType[offset + 3] = newBlue
  
                  if (point.x &gt; 0) {
                      stack.push(CGPoint(x: point.x - 1, y: point.y))
                  }
  
                  if (point.x &lt; CGFloat(pixelsWide)) {
                      stack.push(CGPoint(x: point.x + 1, y: point.y))
                  }
  
                  if (point.y &gt; 0) {
                      stack.push(CGPoint(x: point.x, y: point.y - 1))
                  }
  
                  if (point.y &lt; CGFloat(pixelsHigh)) {
                      stack.push(CGPoint(x: point.x, y: point.y + 1))
                  }
              } else {
  
              }
          }
  
          let colorSpace = CGColorSpaceCreateDeviceRGB()
          let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
          let finalContext = CGBitmapContextCreate(data, pixelsWide, pixelsHigh, CLong(8), CLong(bitmapBytesPerRow), colorSpace, bitmapInfo)
  
          let imageRef = CGBitmapContextCreateImage(finalContext)
          self.image = UIImage(CGImage: imageRef, scale: self.image!.scale,orientation: self.image!.imageOrientation)
      }
  }
  </code></pre>
  
  <p>Now I would like to improve performance. How can I make this algorithm work faster? UInt8.absoluteDifference extension is my attempt to include almost same colors to flood fill and it's working but this could be really improve and I know it but I don't know how.</p>
  
  <pre><code>extension UInt8 {
  
      func absoluteDifference(subtrahend: UInt8) -&gt; UInt8 {
          if (self &gt; subtrahend) {
              return self - subtrahend;
          } else {
              return subtrahend - self;
          }
      }
  }
  </code></pre>
  
  <p>My Stack class:</p>
  
  <pre><code>class Stack {
      var count: Int = 0
      var head: Node = Node()
  
      init() {
      }
  
      func isEmpty() -&gt; Bool {
          return self.count == 0
      }
  
      func push(value: Any) {
          if isEmpty() {
              self.head = Node()
          }
  
          var node = Node(value: value)
          node.next = self.head
          self.head = node
          self.count++
      }
  
      func pop() -&gt; Any? {
          if isEmpty() {
              return nil
          }
  
          var node = self.head
          self.head = node.next!
          self.count--
  
          return node.value
      }
  }
  </code></pre>
  
  <p>Thanks for help</p>