BilderVergleich | FASM

  • Nachdem mich mal jemand im Chat auf die Idee gebracht hat, ein Bildervergleichsprogramm zu machen, hab ich mir gedacht, dass es ganz geeignet wäre mich mal ein bisschen mit FASM auseinanderzusetzen. Das sind hier also eine meiner ersten Gehversuche mit FASM, also zerfleischt mich nicht gleich....
    Das Programm vergleicht die einzelnen Farbwerte der Pixel und generiert ein Bild, auf dem die Farbunterschiede deutlich werden:
    [Blockierte Grafik: http://img576.imageshack.us/img576/5130/unbenanntgcy.jpg]
    Ich hab mich jetzt hierbei hauptsächlich auf den ASM Code konzentriert, also nicht wundern wenn die GUI nicht gefällt:)

    Man zieht zwei Bilder, die man vergleichen möchte auf die entsprechenden Bereiche, wählt einen Farbkanal aus und kann mit einem Klick auf das Result-Bild das Bild mit dem Standard-Bildbetrachtungsprogramm öffnen.
    Hier also der Code:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)
    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    #region +++++++++ GUI +++++++++
    Global $hGui = GUICreate("Farbdifferenz | Coded by K4z", 905, 769, 214, 108, Default, $WS_EX_ACCEPTFILES)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GuiEvent")
    GUISetOnEvent($GUI_EVENT_DROPPED, "_GuiEvent")

    [/autoit] [autoit][/autoit] [autoit]

    Global $Bild1 = GUICtrlCreateGroup("Bild1", 5, 8, 435, 361)
    Global $idPic1 = GUICtrlCreatePic("", 12, 20, 420, 340), $sPath1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $Bild2 = GUICtrlCreateGroup("Bild2", 460, 8, 435, 361)
    Global $idPic2 = GUICtrlCreatePic("", 466, 20, 420, 340), $sPath2

    [/autoit] [autoit][/autoit] [autoit]

    Global $Result = GUICtrlCreateGroup("Result", 230, 384, 435, 361)
    Global $idPic3 = GUICtrlCreatePic("", 237, 396, 420, 340), $sPath3
    GUICtrlSetOnEvent(-1, "_GuiEvent")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $idBtnRed = GUICtrlCreateRadio("Rot", 680, 536, 113, 17)
    GUICtrlSetOnEvent(-1, "_GuiEvent")
    Global $idBtnGreen = GUICtrlCreateRadio("Grün", 680, 561, 113, 17)
    GUICtrlSetOnEvent(-1, "_GuiEvent")
    Global $idBtnBlue = GUICtrlCreateRadio("Blau", 680, 587, 113, 17)
    GUICtrlSetOnEvent(-1, "_GuiEvent")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetState($idPic1, $GUI_DROPACCEPTED)
    GUICtrlSetState($idPic2, $GUI_DROPACCEPTED)
    GUISetState(@SW_SHOW)
    #endregion +++++++++ GUI +++++++++

    [/autoit] [autoit][/autoit] [autoit]

    Global $tCodeBuffer = DllStructCreate("byte[100]")
    DllStructSetData($tCodeBuffer, 1,"0x8B7424048B5C24088B038946648B43048946688B530C8B4B088B46648B008B5E688B1B83FA0177107208C1E808C1EB08EB06C1E810C1EB1038D8760286C328C3B0FFC1E00888D8C1E00888D8C1E00888D88B5E648903834664048346680483E90177B6C3")
    Global $tParameters = DllStructCreate("ptr scan1;ptr scan2;int size;int mode")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(50)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _GuiEvent()
    Switch @GUI_CtrlId
    Case $GUI_EVENT_CLOSE
    _GDIPlus_Shutdown()
    Exit
    Case $GUI_EVENT_DROPPED
    GUICtrlSetImage(@GUI_DropId, @GUI_DragFile)
    If StringRegExp(@GUI_DragFile, '(?i)\.jpg$') Then
    If @GUI_DropId = $idPic1 Then $sPath1 = @GUI_DragFile
    If @GUI_DropId = $idPic2 Then $sPath2 = @GUI_DragFile
    EndIf
    Case $idBtnRed
    If $sPath1 <> '' And $sPath2 <> '' Then
    $sPath3 = _GetColorDifference(0, $sPath1, $sPath2)
    GUICtrlSetImage($idPic3, $sPath3)
    EndIf
    Case $idBtnGreen
    If $sPath1 <> '' And $sPath2 <> '' Then
    $sPath3 = _GetColorDifference(1, $sPath1, $sPath2)
    GUICtrlSetImage($idPic3, $sPath3)
    EndIf
    Case $idBtnBlue
    If $sPath1 <> '' And $sPath2 <> '' Then
    $sPath3 = _GetColorDifference(2, $sPath1, $sPath2)
    GUICtrlSetImage($idPic3, $sPath3)
    EndIf
    Case $idPic3
    If $sPath3 <> '' Then ShellExecute($sPath3)
    EndSwitch
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetColorDifference($iColor, $sPath1, $sPath2)
    ; $iColor: --- 0=Rot --- 1=Grün --- 2=Blau ---
    Local $hBitmap1, $hBitmap2, $iWidth1, $iWidth2, $iHeight1, $iHeight2

    [/autoit] [autoit][/autoit] [autoit]

    $hBitmap1 = _GDIPlus_BitmapCreateFromFile($sPath1)
    $iWidth1 = _GDIPlus_ImageGetWidth($hBitmap1)
    $iHeight1 = _GDIPlus_ImageGetHeight($hBitmap1)

    [/autoit] [autoit][/autoit] [autoit]

    $hBitmap2 = _GDIPlus_BitmapCreateFromFile($sPath2)
    $iWidth2 = _GDIPlus_ImageGetWidth($hBitmap2)
    $iHeight2 = _GDIPlus_ImageGetHeight($hBitmap2)

    [/autoit] [autoit][/autoit] [autoit]

    If ($iWidth1 <> $iWidth2) Or ($iHeight1 <> $iHeight2) Then
    MsgBox(48, "Fehler", "Unterschiedliche Größen!")
    Return
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBitmapData1 = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $iWidth1, $iHeight1, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB)
    Local $hBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $iWidth2, $iHeight2, $GDIP_ILMREAD, $GDIP_PXF32RGB)

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($tParameters, "scan1", DllStructGetData($hBitmapData1, "Scan0"))
    DllStructSetData($tParameters, "scan2", DllStructGetData($hBitmapData2, "Scan0"))
    DllStructSetData($tParameters, "size", $iWidth1 * $iHeight1)
    DllStructSetData($tParameters, "mode", $iColor)
    DllCall("user32.dll", "ptr", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"ptr", DllStructGetPtr($tCodeBuffer), "ptr", DllStructGetPtr($tParameters), "int", 0, "int", 0)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BitmapUnlockBits($hBitmap1, $hBitmapData1)
    _GDIPlus_BitmapUnlockBits($hBitmap2, $hBitmapData2)
    If @error Then Return
    _GDIPlus_ImageSaveToFile($hBitmap1, @TempDir & "\321654r3sult.jpg")

    [/autoit] [autoit][/autoit] [autoit]

    Return @TempDir & "\321654r3sult.jpg"
    EndFunc

    [/autoit]

    Und hier der Teil mit dem FASM-Code:

    Spoiler anzeigen
    [autoit]

    $_assembleit_flag=0
    _assembleit("ptr", "_asm","int",FasmGetBasePtr($Fasm))

    [/autoit] [autoit][/autoit] [autoit]

    Func _asm()
    _("use32") ; 32-Bit Assembler
    _("mov esi, dword[esp+4]") ; ESI = BasePointer
    _("mov ebx, dword[esp+8]") ; EBX = Pointer zum ParameterStruct
    _("mov eax, dword[ebx]") ; -\
    _("mov dword[esi+ptrPic1], eax") ; -/ ptrPic1 = Pointer zum ersten Bild
    _("mov eax, dword[ebx+4]") ; -\
    _("mov dword[esi+ptrPic2], eax") ; -/ ptrPic2 = Pointer zum zweiten Bild
    _("mov edx, dword[ebx+12]") ; EDX = $iMode
    _("mov ecx, dword[ebx+8]") ; ECX = PixelCount

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _("_nextPixel:")

    [/autoit] [autoit][/autoit] [autoit]

    _("mov eax, dword[esi+ptrPic1]") ; -\
    _("mov eax, dword[eax]") ; -/ EAX = PixelColor Bild1

    [/autoit] [autoit][/autoit] [autoit]

    _("mov ebx, dword[esi+ptrPic2]") ; -\
    _("mov ebx, dword[ebx]") ; -/ EBX = PixelColor Bild2

    [/autoit] [autoit][/autoit] [autoit]

    _("cmp edx, 1") ; -\
    _("ja _ShiftEnd") ; -\
    _("jb _ShiftRed") ; |
    _("shr eax, 8") ; | If ($iMode=0){
    _("shr ebx, 8") ; | ShiftRight(EAX, 8); ShiftRight(EBX, 8);
    _("jmp _ShiftEnd") ; | } elseif ($iMode=2){
    _("_ShiftRed:") ; | ShiftRight(EAX, 16); ShiftRight(EBX, 16);
    _("shr eax, 16") ; | }
    _("shr ebx, 16") ; |
    _("_ShiftEnd:") ; -/

    [/autoit] [autoit][/autoit] [autoit]

    _("cmp al, bl") ; -\
    _("jbe _IfBE1") ; -\ If (al>=bl){
    _("xchg al, bl") ; AL, BL vertauschen
    _("_IfBE1:") ; -/ }

    [/autoit] [autoit][/autoit] [autoit]

    _("sub bl, al") ; - BL = BL-AL (rDiff)

    [/autoit] [autoit][/autoit] [autoit]

    _("mov al, 0xFF") ; -\
    _("shl eax, 8") ; |
    _("mov al, bl") ; |
    _("shl eax, 8") ; | EAX = 0xFF:BL:BL:BL
    _("mov al, bl") ; |
    _("shl eax, 8") ; |
    _("mov al, bl") ; -/

    [/autoit] [autoit][/autoit] [autoit]

    _("mov ebx, dword[esi+ptrPic1]") ; -\
    _("mov dword[ebx], eax") ; -/ PixelSetColor: EAX
    _("add dword[esi+ptrPic1], 4") ; - ptrPic1 += 4
    _("add dword[esi+ptrPic2], 4") ; - ptrPic2 += 4
    _("sub ecx, 1") ; - ECX -= 1
    _("ja _nextPixel") ;

    [/autoit] [autoit][/autoit] [autoit]

    _("ret")
    ;-------------------------
    _("ptrPic1 dd ?")
    _("ptrPic2 dd ?")
    EndFunc ;==>_asm

    [/autoit]


    Ob das Programm jetzt wirklich sinnvoll ist, kann jeder für sich selbst entscheiden... Für mich war es jedenfalls eine gute Übung und ich wollte euch den Code nicht vorenthalten.

    Zitat

    You just keep on trying 'till you run out of cake. ;)


    [STEAM] Source UDF

    2 Mal editiert, zuletzt von K4z (19. Februar 2012 um 20:52)

  • Hi,
    sehr feine Idee :thumbup:
    Aber um die Bitmap-Fraktion mit ihren Bildern nicht auszuschliessen, könnte man

    [autoit]

    If StringRegExp(@GUI_DragFile, '(?i)\.(jpg|bmp)$') Then

    [/autoit]

    auch Bitmaps zulassen.

    Den asm-code könntest du noch etwas tunen. Gerade um die Grauwerte in ein dword zu schreiben bietet sich statt

    [autoit]

    _("mov al, 0xFF") ; -\
    _("shl eax, 8") ; |
    _("mov al, bl") ; |
    _("shl eax, 8") ; | EAX = 0xFF:BL:BL:BL
    _("mov al, bl") ; |
    _("shl eax, 8") ; |
    _("mov al, bl") ; -/

    [/autoit]


    zum Beispiel an:

    [autoit]

    _("and ebx,0x000000FF") ;es würde auch "movzx ebx,bl" gehen, um 0x00:00:00:BL zu erhalten
    _("imul eax,ebx,0x010101") ; -\EAX = 0x00:BL:BL:BL
    _("or eax,0xFF000000") ; -\EAX = 0xFF:BL:BL:BL

    [/autoit]

    aber das ist Kleinkram^^

    Was du dir aber wirklich überlegen solltest, ist die Pixel-Adressen ptrPic1 und ptrPic2 in ein Register zu packen!
    Die Daten, die am häufigsten geändert werden, gehören in ein Register, das erhöht die "Schwuppdizität" enorm!
    Weiterhin hast du erkannt, dass das Handling mit "Variablen" alles andere als einfach ist.
    Der Zwischenspeicher auf dem Stack (Push und Pop) ist auch eine (schnelle(re)) Alternative.

    Ansonsten: WEITER SO! :thumbup:

  • @Andi: Erstmal vielen Danke:D Zuerst hatte ich das auch alles in die Register gepackt, aber als ich dann gleich alle 3 Kanäle in ein Programm packen wollte sind mir irgendwie die Register ausgegangen:D Ich bin mit den Registern auch noch relativ unbewandert. Welche Register würden sich denn anbieten für die beiden Pointer, oder ist das egal?

  • chip ich hats zuerst auch farbig, aber so, dass dann eben im Rot-Kanal alles rot war usw... Das Problem war aber vor allem Blau, weil man dabei so gut wie nix erkennen konnte:D Deswegen hab ich mich für Grautöne entschieden. Ah aber ich glaub was du meintest war ein neues Bild mit unterschiedlichen Farben zu generieren:D:D Es kann ja jemand mal sowas machen wenn er Lust hat :thumbup:

  • K4z,
    hehe, Registerpressure....von denen kann man nie genug haben, ist eins der dunklen Seiten der x86-Architektur.

    chip,
    feines Beispiel!
    Farbig ist eigendlich ganz einfach, entweder jeden Farbkanal einzeln voneinander abziehen (supersimpel umzusetzen), oder das "Graubild" erstellen und nachher per YUV-Format den U und V-Kanal dazuaddieren....Spielwiese pur 8o

  • Andy:
    das mit imul ist echt raffiniert:D Aber bei mir bringt das eine Zeiteinsparung von 1ms :rolleyes:, aber ist zumindest kürzer.
    Das mit den Registern schau ich mir auf jedenfall noch mal an, da kann man echt Zeit rausholen...

    Edit: Falls es jemand interressiert: Blend Modes

    Zitat

    You just keep on trying 'till you run out of cake. ;)


    [STEAM] Source UDF

    Einmal editiert, zuletzt von K4z (20. Februar 2012 um 12:33)

  • Eins noch, auch problemlos umzusetzen, verschieden große Bilder in die GUI zu ziehen.

    Verknüpfungen simpel und farbig:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>
    #include <array.au3>
    #include <AssembleIt.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)
    ;Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    #region +++++++++ GUI +++++++++
    Global $hGui = GUICreate("Farbdifferenz | Coded by K4z", 905, 750, 214, 108, Default, $WS_EX_ACCEPTFILES)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GuiEvent")
    GUISetOnEvent($GUI_EVENT_DROPPED, "_GuiEvent")

    [/autoit] [autoit][/autoit] [autoit]

    Global $Bild1 = GUICtrlCreateGroup("Bild1", 5, 8, 435, 361)
    Global $idPic1 = GUICtrlCreatePic("", 12, 20, 420, 340), $sPath1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $Bild2 = GUICtrlCreateGroup("Bild2", 460, 8, 435, 361)
    Global $idPic2 = GUICtrlCreatePic("", 466, 20, 420, 340), $sPath2

    [/autoit] [autoit][/autoit] [autoit]

    Global $Result = GUICtrlCreateGroup("Result", 230, 384, 435, 361)
    Global $idPic3 = GUICtrlCreatePic("", 237, 396, 420, 340), $sPath3
    GUICtrlSetOnEvent(-1, "_GuiEvent")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $idBtnRed = GUICtrlCreateRadio("Rot", 680, 536, 113, 17)
    GUICtrlSetOnEvent(-1, "_GuiEvent")
    Global $idBtnGreen = GUICtrlCreateRadio("Grün", 680, 561, 113, 17)
    GUICtrlSetOnEvent(-1, "_GuiEvent")
    Global $idBtnBlue = GUICtrlCreateRadio("Blau", 680, 587, 113, 17)
    GUICtrlSetOnEvent(-1, "_GuiEvent")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetState($idPic1, $GUI_DROPACCEPTED)
    GUICtrlSetState($idPic2, $GUI_DROPACCEPTED)
    GUISetState(@SW_SHOW)
    #endregion +++++++++ GUI +++++++++

    [/autoit] [autoit][/autoit] [autoit]

    Global $tCodeBuffer = DllStructCreate("byte[100]")
    DllStructSetData($tCodeBuffer, 1,"0x8B7424048B5C24088B038946648B43048946688B530C8B4B088B46648B008B5E688B1B83FA0177107208C1E808C1EB08EB06C1E810C1EB1038D8760286C328C3B0FFC1E00888D8C1E00888D8C1E00888D88B5E648903834664048346680483E90177B6C3")
    Global $tParameters = DllStructCreate("ptr scan1;ptr scan2;int size;int mode")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(50)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _GuiEvent()
    Switch @GUI_CtrlId
    Case $GUI_EVENT_CLOSE
    _GDIPlus_Shutdown()
    Exit
    Case $GUI_EVENT_DROPPED
    GUICtrlSetImage(@GUI_DropId, @GUI_DragFile)
    If StringRegExp(@GUI_DragFile, '(?i)\.(jpg|bmp)$') Then
    If @GUI_DropId = $idPic1 Then $sPath1 = @GUI_DragFile
    If @GUI_DropId = $idPic2 Then $sPath2 = @GUI_DragFile
    EndIf
    Case $idBtnRed
    If $sPath1 <> '' And $sPath2 <> '' Then
    $sPath3 = _GetColorDifference(0, $sPath1, $sPath2)
    GUICtrlSetImage($idPic3, $sPath3)
    EndIf
    Case $idBtnGreen
    If $sPath1 <> '' And $sPath2 <> '' Then
    $sPath3 = _GetColorDifference(1, $sPath1, $sPath2)
    GUICtrlSetImage($idPic3, $sPath3)
    EndIf
    Case $idBtnBlue
    If $sPath1 <> '' And $sPath2 <> '' Then
    $sPath3 = _GetColorDifference(2, $sPath1, $sPath2)
    GUICtrlSetImage($idPic3, $sPath3)
    EndIf
    Case $idPic3
    If $sPath3 <> '' Then ShellExecute($sPath3)
    EndSwitch
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetColorDifference($iColor, $sPath1, $sPath2)
    ; $iColor: --- 0=Rot --- 1=Grün --- 2=Blau ---
    Local $hBitmap1, $hBitmap2, $iWidth1, $iWidth2, $iHeight1, $iHeight2

    [/autoit] [autoit][/autoit] [autoit]

    $hBitmap1 = _GDIPlus_BitmapCreateFromFile($sPath1)
    $iWidth1 = _GDIPlus_ImageGetWidth($hBitmap1)
    $iHeight1 = _GDIPlus_ImageGetHeight($hBitmap1)

    [/autoit] [autoit][/autoit] [autoit]

    $hBitmap2 = _GDIPlus_BitmapCreateFromFile($sPath2)
    $iWidth2 = _GDIPlus_ImageGetWidth($hBitmap2)
    $iHeight2 = _GDIPlus_ImageGetHeight($hBitmap2)

    [/autoit] [autoit][/autoit] [autoit]

    If ($iWidth1 <> $iWidth2) Or ($iHeight1 <> $iHeight2) Then
    MsgBox(48, "Fehler", "Unterschiedliche Größen!")
    Return
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBitmapData1 = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $iWidth1, $iHeight1, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB)
    Local $hBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $iWidth2, $iHeight2, $GDIP_ILMREAD, $GDIP_PXF32RGB)

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($tParameters, "scan1", DllStructGetData($hBitmapData1, "Scan0"))
    DllStructSetData($tParameters, "scan2", DllStructGetData($hBitmapData2, "Scan0"))
    DllStructSetData($tParameters, "size", $iWidth1 * $iHeight1)
    DllStructSetData($tParameters, "mode", $iColor)

    [/autoit] [autoit][/autoit] [autoit]

    local $_assembleit_flag=0
    _assembleit("ptr", "_asm2","ptr", FasmGetBasePtr($Fasm), "ptr", DllStructGetPtr($tParameters))

    [/autoit] [autoit][/autoit] [autoit]

    ;~ local $a=DllCall("user32.dll", "ptr", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"ptr", DllStructGetPtr($tCodeBuffer), "ptr", DllStructGetPtr($tParameters), "int", 0, "int", 0)
    ;~ _arraydisplay($a)
    _GDIPlus_BitmapUnlockBits($hBitmap1, $hBitmapData1)
    _GDIPlus_BitmapUnlockBits($hBitmap2, $hBitmapData2)
    If @error Then Return
    _GDIPlus_ImageSaveToFile($hBitmap1, @TempDir & "\321654r3sult.jpg")

    [/autoit] [autoit][/autoit] [autoit]

    Return @TempDir & "\321654r3sult.jpg"
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _asm2()
    _("use32") ; 32-Bit Assembler
    ; _("org " & FasmGetBasePtr($Fasm))
    _("mov esi, dword[esp+4]") ; ESI = BasePointer
    _("mov ebx, dword[esp+8]") ; EBX = Pointer zum ParameterStruct
    _("mov eax, dword[ebx]") ; -\
    _("mov dword[esi+ptrPic1], eax") ; -/ ptrPic1 = Pointer zum ersten Bild
    _("mov eax, dword[ebx+4]") ; -\
    _("mov dword[esi+ptrPic2], eax") ; -/ ptrPic2 = Pointer zum zweiten Bild
    _("mov edx, dword[ebx+12]") ; EDX = $iMode
    _("mov ecx, dword[ebx+8]") ; ECX = PixelCount

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _("_nextPixel:")

    [/autoit] [autoit][/autoit] [autoit]

    _("mov eax, dword[esi+ptrPic1]") ; -\
    _("mov eax, dword[eax]") ; -/ EAX = PixelColor Bild1

    [/autoit] [autoit][/autoit] [autoit]

    _("mov ebx, dword[esi+ptrPic2]") ; -\

    [/autoit] [autoit][/autoit] [autoit]

    ;hier kann man experimentieren, statt dem ADD entweder XOR, SUB, AND, OR oder kombinationen einsetzen
    _("ADD eax, dword[ebx]") ; -/ EBX = PixelColor Bild2

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _("mov ebx, dword[esi+ptrPic1]") ; -\
    _("mov dword[ebx], eax") ; -/ PixelSetColor: EAX
    _("add dword[esi+ptrPic1], 4") ; - ptrPic1 += 4
    _("add dword[esi+ptrPic2], 4") ; - ptrPic2 += 4
    _("sub ecx, 1") ; - ECX -= 1
    _("ja _nextPixel") ;

    [/autoit] [autoit][/autoit] [autoit]

    _("ret")
    ;-------------------------
    _("ptrPic1 dd ?")
    _("ptrPic2 dd ?")
    EndFunc ;==>_asm

    [/autoit] [autoit][/autoit] [autoit][/autoit]

    einfach im ASM-code die Zeile entsprechend mit der Vernüpfung ändern....

  • Sehr schönes ASM Beispiel.
    Mit etwas Übung kann man sich Bitmapmäßig fast alle Geschwindigkeitsprobleme aus dem Weg räumen.
    Jede Millisekunde Zählt ;)
    Vorallem, wenn man z.B. in kleinen Spielchen in Echtzeit Grafikeffekte haben will muss der Käs in <2 ms durch sein, sonst gehen die Frames in die Knie :)

    Weiter so

    lg
    M

  • Um den ASM-Teil etwas zu straffen, hier mal die Minimalversion^^

    Spoiler anzeigen
    [autoit]

    Func _asm()
    _("use32") ; 32-Bit Assembler
    ;_("org " & FasmGetBasePtr($Fasm))
    _("mov ebx, dword[esp+4]") ; EBX = Pointer zum ParameterStruct
    _("mov edi, dword[ebx]") ; -\ Bild1
    ; _("mov edx, dword[ebx+12]") ; EDX = $iMode
    _("mov ecx, dword[ebx+8]") ; ECX = PixelCount
    _("mov esi, dword[ebx+4]") ; -\Bild2

    [/autoit] [autoit][/autoit] [autoit]

    _("_nextPixel:")
    _("lodsd") ; -/ EAX = [ESI]PixelColor Bild1
    _("mov ebx, dword[edi]") ; -/ EBX = PixelColor Bild2
    ;hier die verknüpfung angeben
    _("xor eax,ebx") ; -
    ;_asmdbg_()
    _("stosd") ;[EDI]=eax
    _("loop _nextPixel")
    _("ret")
    ;-------------------------

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_asm

    [/autoit]


    aufzurufen mit

    [autoit]

    _assembleit("ptr", "_asm", "ptr", DllStructGetPtr($tParameters))

    [/autoit]


    Wer lust hat, asssembliert sich den code und macht für alle erdenklichen Verknüpfungen eine Unterfunktion.
    Diese könnte man dann in eine Listview packen und von dort in eine weitere Liste ziehen, um die Bild"bearbeitungen" dann nacheinander anzuwenden. So könnte man sicher schöne "Filter" zusammenstellen.

    Btw, sämtliche asm-Funktionen, also auch DIV, NOT, OR, MUL usw. sind verwendbar, viel Spass beim experimentieren^^