#include <Array.au3>

#include <GDIPlus.au3>
;aligncomment=80
_GDIPlus_Startup()

; Globale Konstanten für FF5 (damit sie nicht als Parameter in der Rekursion sind da sie eh immer gleich bleiben)
Global $__FF_iColArea = 0
Global $__FF_iColFill = 0

; Einstellungen zum Ausprobieren
Global $n = 1                                                                    ; Anzahl Runden deren mittlere Zeit gemessen wird
Global $aPos = [2, 2]                                                            ; Startposition fürs FloodFill
Global $bArrayDisplay = False                                                    ; Will man die Arrays sehen
Global $bRandomize = False                                                       ; Zufällige Startadressen ?
Global $bInfoReadWrite = False                                                   ; Will man einen Plot in die Konsole mit den Reads/Writes?
Global $bInfoReadWriteSmall = False                                              ; Nur R/W ohne Tabelle
Global $iFill = 123                                                              ; Was wird ins Array geschrieben





If $bInfoReadWriteSmall Then
    $bInfoReadWrite = False
    $n = 1
EndIf
If $bInfoReadWrite Then $n = 1                                                   ; Macht nur sinn 1x durchlaufen zu lassen wenn man diese Information will.
If $bArrayDisplay Then $n = 1

; Die "Bitmap" wird hier erstellt. Es wird angenommen, dass die FloodFill Algorithmen iW und iH kennen (global)
Global Const $iW = 800
Global Const $iH = 800
Global $aBitmap[$iH][$iW], $aReads[$iH][$iW], $aWrites[$iH][$iW], $iPixel = 0
SRandom(@MIN * 60 * 1000 + @SEC * 1000 + @MSEC)


Global $ptr1, $hbmp1
$gui = GUICreate("bitmap", $iW, $iH)
WinSetTitle($gui, "", "Bitmap erstellen...bitte warten....")
GUISetState()
$DC_gui = _WinAPI_GetDC($gui)                                                    ;DeviceContext GUI holen

Global $DC_bmp = _CreateNewBmp32($iW, $iH, $ptr1, $hbmp1)                        ;leere Bitmap
Global $bitmap_struct = DllStructCreate("uint [" & $iW * $iH & "]", $ptr1)       ;wir wollen in die Bitmap schreiben



Func Reset()                                                                     ; Hier kann sich jeder eine "bitmap" basteln mit 2 Farben
    $iPixel = 0


    For $y = 0 To $iW - 1 Step 1
        For $x = 0 To $iH - 1 Step 1
            $aBitmap[$y][$x] = ($x - 8) ^ 2 + ($y - 8) ^ 2 < 6 ^ 2 ? 2 : 1
            $aBitmap[$y][$x] = ($x - 16) ^ 2 + ($y - 16) ^ 2 < 6 ^ 2 ? 2 : $aBitmap[$y][$x]
            If $aBitmap[$y][$x] = 2 Then $iPixel += 1
            $aReads[$y][$x] = 0
            $aWrites[$y][$x] = 0
        Next
    Next

    ; Bereiche in der mitte
    $aBitmap[5][5] = 1
    $aBitmap[5][6] = 1
    $aBitmap[5][7] = 1
    $aBitmap[8][5] = 1
    $aBitmap[8][6] = 1
    $aBitmap[8][7] = 1
    $aBitmap[10][14] = 1
    $aBitmap[11][14] = 1
    $aBitmap[12][14] = 1
    $aBitmap[10][12] = 1
    $aBitmap[11][12] = 1
    $aBitmap[12][12] = 1

    ; 4 bereiche am Rand die man nur diagonal erreichen kann
    $aBitmap[15][0] = 2
    $aBitmap[16][1] = 2
    $aBitmap[17][0] = 2
    $aBitmap[0][3] = 2
    $aBitmap[1][4] = 2
    $aBitmap[0][5] = 2
    $aBitmap[1][23] = 2
    $aBitmap[2][22] = 2
    $aBitmap[3][23] = 2
    $aBitmap[23][7] = 2
    $aBitmap[22][8] = 2
    $aBitmap[23][9] = 2


    $aBitmap[19][2] = 2
    $aBitmap[18][2] = 2
    $aBitmap[17][2] = 2
    $aBitmap[15][2] = 2
    $aBitmap[15][3] = 2
    $aBitmap[16][4] = 2
    $aBitmap[17][5] = 2
    $aBitmap[18][4] = 2
    $aBitmap[19][4] = 2
    $aBitmap[16][1] = 2
    $aBitmap[15][0] = 2
    $aBitmap[17][0] = 2
    $aBitmap[19][3] = 2
    $aBitmap[7][7] = 1


;~ for $x=0 to $iW-2 step 2;Kamm
;~ for $y=30 to $iH-1
;~          $aBitmap[$y][$x] = 2
;~     Next
;~ next



    For $x = 0 To $iW - 1
        For $y = 0 To $iH - 1
            $col = $aBitmap[$y][$x]
            If $col = 2 Then $col = 0xFF00FF
            DllStructSetData($bitmap_struct, 1, $col, $x + $y * $iH)
        Next
    Next

;~     _WinAPI_BitBlt($DC_gui, 0, 0, $iW,$iH, $DC_bmp, 0, 0, 0xCC0020);$srccopy
    ;GUISetState()




EndFunc                                                                          ;==>Reset
; ################################################################################

Global $iTimer
Reset()


If $bArrayDisplay Then _ArrayDisplay($aBitmap, 'Original')

;   OBACHT die Zahl muss der Anzahl Funktionen entsprechen
;           \ /
Local $aAlgo[2][4] = [[FF_Andy3_realebitmap], [FF5x]], $iUBound = UBound($aAlgo)

For $i = 1 To $n Step 1
    For $ii = 0 To $iUBound - 1 Step 1
        If $bRandomize Then $aPos = rnd()
        Reset()                                                                  ; "Bitmap" zurücksetzen
        $iTimer = TimerInit()
        $aAlgo[$ii][0]($aPos[0], $aPos[1], $iFill)
        $aAlgo[$ii][1] += TimerDiff($iTimer)
        If $n = 1 Then
            ConsoleWrite(StringLeft(FuncName($aAlgo[$ii][0]) & ':           ', 11) & StringFormat('%.3f', $aAlgo[$ii][1]) & ' ms' & @CRLF)
            Info()
            ConsoleWrite(@CRLF)
            If $bArrayDisplay Then _ArrayDisplay($aBitmap, FuncName($aAlgo[$ii][0]))
        EndIf
    Next
Next

If $n > 1 Then
    ConsoleWrite('Mittelwert aus ' & $n & ' Durchläufen' & @CRLF)
    For $ii = 0 To $iUBound - 1 Step 1
        ConsoleWrite(StringLeft(FuncName($aAlgo[$ii][0]) & ':           ', 11) & StringFormat('%.3f', $aAlgo[$ii][1] / $n) & ' ms' & @CRLF)
    Next
EndIf


While 1
    $idMsg = GUIGetMsg()
    If $idMsg = -3 Then ExitLoop
WEnd




Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp)                 ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    $hcdc = _WinAPI_CreateCompatibleDC(0)                                        ;Desktop-Kompatiblen DeviceContext erstellen lassen
    $tBMI = DllStructCreate($tagBITMAPINFO)                                      ;Struktur der Bitmapinfo erstellen und Daten eintragen
    DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4)                      ;Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, 2, $iwidth)
    DllStructSetData($tBMI, 3, -$iheight)                                        ;minus =standard = bottomup
    DllStructSetData($tBMI, 4, 1)
    DllStructSetData($tBMI, 5, 32)                                               ;32 Bit = 4 Bytes => AABBGGRR
    $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0]                                                             ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4]                                                              ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    _WinAPI_SelectObject($hcdc, $hbmp)                                           ;objekt hbitmap in DC
    Return $hcdc                                                                 ;DC der Bitmap zurückgeben
EndFunc                                                                          ;==>_CreateNewBmp32

Func _DeleteBitmap32($DC, $ptr, $hbmp)
    _WinAPI_DeleteDC($DC)
    _WinAPI_DeleteObject($hbmp)
    $ptr = 0
EndFunc                                                                          ;==>_DeleteBitmap32


Func FF_Andy3_realebitmap($x, $y, $iColFill)
    WinSetTitle($gui, "", "Bitmap vorher")
    _WinAPI_BitBlt($DC_gui, 0, 0, $iW, $iH, $DC_bmp, 0, 0, 0xCC0020)             ;$srccopy
    $iColFill = 0x0000FF00                                                       ;grün
    Dim $liste[$iW * $iH]                                                        ;maximaler Füllbereich, normalerweise eine "leere" Bitmap
    Dim $bitmap_marker[$iW * $iH]
    Local $iColRead = DllStructGetData($bitmap_struct, 1, $x + $y * $iH)
    $counter = 0                                                                 ;für Listenelement
    $listcounter = 0                                                             ;anzahl elemente in liste
    $liste[$listcounter] = BitShift($x, -16) + $y                                ;position pixel in bitmap mit x- und y-koordinate
    DllStructSetData($bitmap_struct, 1, $iColFill, $x + $y * $iH)                ;pixel färben

    While 1                                                                      ;$listende_nicht_erreicht
        $y = BitAND($liste[$counter], 0xFFFF)                                    ;16 LSB             2
        $x = BitShift($liste[$counter], 16)                                      ;16 MSB                4
        $xL = $x - 1                                                             ;linker pixel        5
        $xR = $x + 1                                                             ;rechter pixel        6
        $yO = $y - 1                                                             ;                    7
        $yU = $y + 1                                                             ;                    8


        $pos = $y * $iW + $xL                                                    ;11
        If $xL >= 0 And $bitmap_marker[$pos] = 0 Then                            ;wenn im bereich und noch nicht in der Liste        15
            If DllStructGetData($bitmap_struct, 1, $pos) = $iColRead Then        ;Pixel mit $iColRead gefunden    18 ggf 30cachemiss
                DllStructSetData($bitmap_struct, 1, $iColFill, $pos)             ;23 ggf 35
                $listcounter += 1                                                ;36
                $liste[$listcounter] = BitShift($xL, -16) + $y                   ;position pixel in bitmap                40
                $bitmap_marker[$pos] = 1                                         ;41
            EndIf
        EndIf
        $pos = $y * $iW + $xR
        If $xR < $iW And $bitmap_marker[$pos] = 0 Then
            If DllStructGetData($bitmap_struct, 1, $pos) = $iColRead Then        ;Pixel mit $iColRead gefunden
                DllStructSetData($bitmap_struct, 1, $iColFill, $pos)
                $listcounter += 1
                $liste[$listcounter] = BitShift($xR, -16) + $y                   ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf                                                                    ;70
        $pos = $yO * $iW + $x
        If $yO >= 0 And $bitmap_marker[$pos] = 0 Then
            If DllStructGetData($bitmap_struct, 1, $pos) = $iColRead Then        ;Pixel mit $iColRead gefunden
                DllStructSetData($bitmap_struct, 1, $iColFill, $pos)
                $listcounter += 1
                $liste[$listcounter] = BitShift($x, -16) + $yO                   ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf                                                                    ;100
        $pos = $yU * $iW + $x
        If $yU < $iH And $bitmap_marker[$pos] = 0 Then
            If DllStructGetData($bitmap_struct, 1, $pos) = $iColRead Then        ;Pixel mit $iColRead gefunden
                DllStructSetData($bitmap_struct, 1, $iColFill, $pos)
                $listcounter += 1
                $liste[$listcounter] = BitShift($x, -16) + $yU                   ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf                                                                    ;130
        If $listcounter = $counter Then ExitLoop
        $counter = $counter + 1                                                  ;800*800*150*2*1e-9  ;800x800Pixel * 150 Takte * 2ghz =0,2sec floodfill
    WEnd

    _WinAPI_BitBlt($DC_gui, 0, 0, $iW, $iH, $DC_bmp, 0, 0, 0xCC0020)             ;$srccopy

    WinSetTitle($gui, "", "Bitmap nachher")

EndFunc                                                                          ;==>FF_Andy3_realebitmap

Func FF5x($x, $y, $iColFill)                                                     ; Initialisierung
    $__FF_iColArea = Read($x, $y)
    $__FF_iColFill = $iColFill
    Write($x, $y, $iColFill)
    For $xMax = $x + 1 To $iW - 1 Step 1
        If Read($xMax, $y) <> $__FF_iColArea Then ExitLoop
        Write($xMax, $y, $__FF_iColFill)
    Next
    For $xMin = $x - 1 To 0 Step -1
        If Read($xMin, $y) <> $__FF_iColArea Then ExitLoop
        Write($xMin, $y, $__FF_iColFill)
    Next
    If $y > 0 Then
        For $i = $xMin + 1 To $xMax - 1 Step 1
            If Read($i, $y - 1) = $__FF_iColArea Then $i = FF5($i, $y - 1, 1, $xMin, $xMax)
        Next
    EndIf
    If $y < $iH - 1 Then
        For $i = $xMin + 1 To $xMax - 1 Step 1
            If Read($i, $y + 1) = $__FF_iColArea Then $i = FF5($i, $y + 1, 2, $xMin, $xMax)
        Next
    EndIf
EndFunc                                                                          ;==>FF5x

Func FF5($x, $y, $iDirection, $xMinOffset, $xMaxOffset)                          ; Rekursiver Teil
    Write($x, $y, $__FF_iColFill)
    For $xMax = $x + 1 To $iW - 1 Step 1
        If Read($xMax, $y) <> $__FF_iColArea Then ExitLoop
        Write($xMax, $y, $__FF_iColFill)
    Next
    For $xMin = $x - 1 To 0 Step -1
        If Read($xMin, $y) <> $__FF_iColArea Then ExitLoop
        Write($xMin, $y, $__FF_iColFill)
    Next
    If $y > 0 Then
        For $i = $xMin + 1 To $xMinOffset - 1 Step 1
            If Read($i, $y - 1) = $__FF_iColArea Then
                Write($i, $y - 1, $__FF_iColFill)
                For $xMax2 = $i + 1 To $iW - 1 Step 1
                    If Read($xMax2, $y - 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMax2, $y - 1, $__FF_iColFill)
                Next
                For $xMin2 = $i - 1 To 0 Step -1
                    If Read($xMin2, $y - 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMin2, $y - 1, $__FF_iColFill)
                Next
                If $y > 1 Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                    Next
                    For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
                        If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                    Next
                EndIf
                If $y < $iH Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
                    Next
                EndIf
                $i = $xMax2 + 1                                                  ; Wir wissen, dass man bis xMax2 laufen kann -> $i Abfrage überflüssig
            EndIf
        Next
        If $iDirection = 1 Then
            For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 1 > $xMax ? $xMax - 1 : $xMaxOffset - 2) Step 1
                If Read($i, $y - 1) = $__FF_iColArea Then
                    Write($i, $y - 1, $__FF_iColFill)
                    For $xMax2 = $i + 1 To $iW - 1 Step 1
                        If Read($xMax2, $y - 1) <> $__FF_iColArea Then ExitLoop
                        Write($xMax2, $y - 1, $__FF_iColFill)
                    Next
                    For $xMin2 = $i - 1 To 0 Step -1
                        If Read($xMin2, $y - 1) <> $__FF_iColArea Then ExitLoop
                        Write($xMin2, $y - 1, $__FF_iColFill)
                    Next
                    If $y > 1 Then
                        For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                            If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                        Next
                        For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
                            If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                        Next
                        For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                            If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                        Next
                    EndIf
                    If $y < $iH Then
                        For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                            If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
                        Next
                        For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                            If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
                        Next
                    EndIf
                    $i = $xMax2 + 1                                              ; Wir wissen, dass man bis xMax2 laufen kann -> $i Abfrage überflüssig
                EndIf
            Next
        EndIf
        For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
            If Read($i, $y - 1) = $__FF_iColArea Then
                Write($i, $y - 1, $__FF_iColFill)
                For $xMax2 = $i + 1 To $iW - 1 Step 1
                    If Read($xMax2, $y - 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMax2, $y - 1, $__FF_iColFill)
                Next
                For $xMin2 = $i - 1 To 0 Step -1
                    If Read($xMin2, $y - 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMin2, $y - 1, $__FF_iColFill)
                Next
                If $y > 1 Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                    Next
                    For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
                        If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
                    Next
                EndIf
                If $y < $iH Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
                    Next
                EndIf
                $i = $xMax2 + 1                                                  ; Wir wissen, dass man bis xMax2 laufen kann -> $i Abfrage überflüssig
            EndIf
        Next
    EndIf
    If $y < $iH - 1 Then
        For $i = $xMin + 1 To $xMinOffset - 1 Step 1
            If Read($i, $y + 1) = $__FF_iColArea Then
                Write($i, $y + 1, $__FF_iColFill)
                For $xMax2 = $i + 1 To $iW - 1 Step 1
                    If Read($xMax2, $y + 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMax2, $y + 1, $__FF_iColFill)
                Next
                For $xMin2 = $i - 1 To 0 Step -1
                    If Read($xMin2, $y + 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMin2, $y + 1, $__FF_iColFill)
                Next
                If $y >= 0 Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
                    Next
                EndIf
                If $y < $iH - 2 Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                    Next
                    For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
                        If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                    Next
                EndIf
                $i = $xMax2 + 1
            EndIf
        Next
        If $iDirection = 2 Then
            For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 1 > $xMax ? $xMax - 1 : $xMaxOffset - 2) Step 1
                If Read($i, $y + 1) = $__FF_iColArea Then
                    Write($i, $y + 1, $__FF_iColFill)
                    For $xMax2 = $i + 1 To $iW - 1 Step 1
                        If Read($xMax2, $y + 1) <> $__FF_iColArea Then ExitLoop
                        Write($xMax2, $y + 1, $__FF_iColFill)
                    Next
                    For $xMin2 = $i - 1 To 0 Step -1
                        If Read($xMin2, $y + 1) <> $__FF_iColArea Then ExitLoop
                        Write($xMin2, $y + 1, $__FF_iColFill)
                    Next
                    If $y >= 0 Then
                        For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                            If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
                        Next
                        For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                            If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
                        Next
                    EndIf
                    If $y < $iH - 2 Then
                        For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                            If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                        Next
                        For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
                            If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                        Next
                        For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                            If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                        Next
                    EndIf
                    $i = $xMax2 + 1
                EndIf
            Next
        EndIf
        For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
            If Read($i, $y + 1) = $__FF_iColArea Then
                Write($i, $y + 1, $__FF_iColFill)
                For $xMax2 = $i + 1 To $iW - 1 Step 1
                    If Read($xMax2, $y + 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMax2, $y + 1, $__FF_iColFill)
                Next
                For $xMin2 = $i - 1 To 0 Step -1
                    If Read($xMin2, $y + 1) <> $__FF_iColArea Then ExitLoop
                    Write($xMin2, $y + 1, $__FF_iColFill)
                Next
                If $y >= 0 Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
                    Next
                EndIf
                If $y < $iH - 2 Then
                    For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
                        If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                    Next
                    For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
                        If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                    Next
                    For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
                        If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
                    Next
                EndIf
                $i = $xMax2 + 1
            EndIf
        Next
    EndIf
    Return $xMax + 1
EndFunc                                                                          ;==>FF5

Func FF4x($x, $y, $iColFill)                                                     ; Initialisierung
    Local $iColArea = Read($x, $y)
    Write($x, $y, $iColFill)
    For $xMax = $x + 1 To $iW - 1 Step 1
        If Read($xMax, $y) <> $iColArea Then ExitLoop
        Write($xMax, $y, $iColFill)
    Next
    For $xMin = $x - 1 To 0 Step -1
        If Read($xMin, $y) <> $iColArea Then ExitLoop
        Write($xMin, $y, $iColFill)
    Next
    If $y > 0 Then
        For $i = $xMin + 1 To $xMax - 1 Step 1
            If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
        Next
    EndIf
    If $y < $iH - 1 Then
        For $i = $xMin + 1 To $xMax - 1 Step 1
            If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
        Next
    EndIf
EndFunc                                                                          ;==>FF4x

Func FF4($x, $y, $iColFill, $iColArea, $iDirection, $xMinOffset, $xMaxOffset)    ; Rekursiver Teil
    Write($x, $y, $iColFill)
    For $xMax = $x + 1 To $iW - 1 Step 1
        If Read($xMax, $y) <> $iColArea Then ExitLoop
        Write($xMax, $y, $iColFill)
    Next
    For $xMin = $x - 1 To 0 Step -1
        If Read($xMin, $y) <> $iColArea Then ExitLoop
        Write($xMin, $y, $iColFill)
    Next
    If $y > 0 Then
        For $i = $xMin + 1 To $xMinOffset - 1 Step 1
            If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
        Next
        If $iDirection = 1 Then
            For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 2 > $xMax - 1 ? $xMax - 1 : $xMaxOffset - 2) Step 1
                If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
            Next
        EndIf
        For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
            If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
        Next
    EndIf
    If $y < $iH - 1 Then
        For $i = $xMin + 1 To $xMinOffset - 1 Step 1
            If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
        Next
        If $iDirection = 2 Then
            For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 2 > $xMax - 1 ? $xMax - 1 : $xMaxOffset - 2) Step 1
                If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
            Next
        EndIf
        For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
            If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
        Next
    EndIf

EndFunc                                                                          ;==>FF4

Func FF1($x, $y, $iColFill, $iColArea = 0)                                       ; Aus dem Bilderbuch bzw. Wikipedia.
    Local $iColRead = Read($x, $y)                                               ; Tempo    : Bummelbahn mit angezogener Handbremse
    If $iColArea = 0 Then $iColArea = $iColRead                                  ; Rekursion: Sehr schnell sehr viele Rekursionen
    If $iColArea <> $iColRead Then Return                                        ; Reads    : So viel wie möglich (schlecht)
    If $iColFill = $iColRead Then Return
    Write($x, $y, $iColFill)
    If $x > 0 Then FF1($x - 1, $y, $iColFill, $iColArea)
    If $x < $iW - 1 Then FF1($x + 1, $y, $iColFill, $iColArea)
    If $y > 0 Then FF1($x, $y - 1, $iColFill, $iColArea)
    If $y < $iH - 1 Then FF1($x, $y + 1, $iColFill, $iColArea)
EndFunc                                                                          ;==>FF1

Func FF2($x, $y, $iColFill, $iColArea = 0, $iLast = -1)                          ; Genau das gleiche wie FF1 nur, dass man nicht mehr dahingehen kann wo man herkommt.
    Local $iColRead = Read($x, $y)                                               ; Tempo    : Bummelbahn
    If $iColArea = 0 Then $iColArea = $iColRead                                  ; Rekursion: Sehr schnell sehr viele Rekursionen
    If $iColArea <> $iColRead Then Return                                        ; Reads    : Weniger als FF1 und FF3
    If $iColFill = $iColRead Then Return
    Write($x, $y, $iColFill)
    If $iLast <> 0 And $x > 0 Then FF2($x - 1, $y, $iColFill, $iColArea, 2)
    If $iLast <> 2 And $x < $iW - 1 Then FF2($x + 1, $y, $iColFill, $iColArea, 0)
    If $iLast <> 3 And $y > 0 Then FF2($x, $y - 1, $iColFill, $iColArea, 1)
    If $iLast <> 1 And $y < $iH - 1 Then FF2($x, $y + 1, $iColFill, $iColArea, 3)
EndFunc                                                                          ;==>FF2

Func FF3($x, $y, $iColFill, $iColArea = 0)                                       ; Spontan ausgedacht. Nachschlagen ergab, dass eine ähnliche Methode Scanline Flood Fill heißt.
    If $iColArea = 0 Then $iColArea = Read($x, $y)                               ; Tempo    : Mofa mit aufgebohrtem Zylinderkopf und zugepetztem Auspuff.
    Write($x, $y, $iColFill)                                                     ; Rekursion: Eine für jede "Linie" in jeder Zeile. Also irgendwas wie die CONST * AREAHEIGHT (sollte nicht so schnell wachsen)
    For $xMax = $x + 1 To $iW - 1 Step 1                                         ; Reads    : Weniger als FF1 und mehr als FF3
        $iColRead = Read($xMax, $y)
        If $iColRead <> $iColArea Then ExitLoop
        Write($xMax, $y, $iColFill)
    Next
    For $xMin = $x - 1 To 0 Step -1
        $iColRead = Read($xMin, $y)
        If $iColRead <> $iColArea Then ExitLoop
        Write($xMin, $y, $iColFill)
    Next
    $xMin += 1
    $xMax -= 1
    If $y > 0 Then
        For $i = $xMin To $xMax Step 1
            If Read($i, $y - 1) = $iColArea Then FF3($i, $y - 1, $iColFill, $iColArea)
        Next
    EndIf
    If $y < $iH - 1 Then
        For $i = $xMin To $xMax Step 1
            If Read($i, $y + 1) = $iColArea Then FF3($i, $y + 1, $iColFill, $iColArea)
        Next
    EndIf
EndFunc                                                                          ;==>FF3

Func Info()
    Local $iReads, $iWrites
    If $bInfoReadWrite Then ConsoleWrite('##################################### [ Reads | Writes ] ######################################' & @CRLF)
    For $y = 0 To $iH - 1 Step 1
        For $x = 0 To $iW - 1 Step 1
            $iReads += $aReads[$y][$x]
            $iWrites += $aWrites[$y][$x]
            If $bInfoReadWrite Then ConsoleWrite('[' & $aReads[$y][$x] & '|' & $aWrites[$y][$x] & '] ')
        Next
        If $bInfoReadWrite Then ConsoleWrite(@CRLF)
    Next
    ConsoleWrite('Reads:  ' & $iReads & ' (R/Px: ' & StringFormat('%.2f', $iReads / $iPixel) & ')' & @CRLF)
    ConsoleWrite('Writes: ' & $iWrites & @CRLF)
    If $bInfoReadWrite Then ConsoleWrite('###############################################################################################' & @CRLF)
EndFunc                                                                          ;==>Info

Func Read($x, $y)
    $aReads[$y][$x] += 1
    Return $aBitmap[$y][$x]
EndFunc                                                                          ;==>Read

Func Write($x, $y, $iCol)
    $aWrites[$y][$x] += 1
    $aBitmap[$y][$x] = $iCol
EndFunc                                                                          ;==>Write

Func rnd()
    If Not $bRandomize Then Return $aPos
    Local $a = [Random(0, $iW - 1, 1), Random(0, $iH - 1, 1)]
    Return $a
EndFunc                                                                          ;==>rnd




