Pixeln aus 1bit BMP auslesen - vertikal (Scanlines emulieren)

  • Hallo,

    ich möchte gern aus eine BMP (1bit) die Pixeln auslesen, und zwar so das ich für alle 8 pixel 1 Byte erstelle.
    Mein bild hat immer 32*x , 32*y pixel, und ich werde mein Bild von ObenLinks nach UntenRechts lesen.

    Also: wenn die ersten Pixel Oben links so aussehen:

    Spoiler anzeigen
    Code
    o...
    o...
    o...
    o...
    o...
    o...
    X...
    X...


    werde ich (irgendwie) in Binär 0b11000000 haben (möchten!) oder 0xC0 in mein Endergebnis haben.

    Ich versuche eine Procedure in Delphi nachzumachen. In Delphi wird Scanlines verwendet. Leider hat AutoIT3 kein Scanline, so weit ich das sehe.

    So weit bin ich gekommen: es geht, aber ist relativ langsam: 11-14 Sekunden. Problem ist warscheinlich, ich lese 32 Bit obwohl min Bild nur 8 Bit ist.

    Spoiler anzeigen
    [autoit]


    #include <Constants.au3>
    #include <GUIConstantsEx.au3>
    #include <GDIPlus.au3>

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

    Example()

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

    Func Example()

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

    Local $sFile = @ScriptDir & "\template.bmp"

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

    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_ImageLoadFromFile($sFile) ;create an image object based on a file

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

    Local $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) ;get width and height of the image

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

    ; what is difference between bitmap and image ?
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile)

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

    Local $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;locks a portion of a bitmap for reading and writing. More infor at http://msdn.microsoft.com/en-us/library/…8(v=vs.85).aspx

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

    Local $iScan0 = DllStructGetData($tBitmapData, "Scan0") ;get scan0 (pixel data) from locked bitmap

    ; the struct must match the format of pixel data...
    Local $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0)

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

    Local $iPixel, $iRowOffset
    Local $out = ""

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

    $t = TimerInit()

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

    ConsoleWrite("Struct size " & DllStructGetSize($tPixel) & @LF)
    ; Read vertically...
    ; go over each column
    For $myColumn = 1 To $iH
    ; then for each row
    For $myRow = 1 To $iW
    ; index starts at 1
    ; pixel at col 1, row 2 is at 1 + iW
    $pixelIndex = ($myRow - 1) * $iW + $myColumn
    ;~ ConsoleWrite("col =" & $myColumn & ", row = " & $myrow & " : " & $pixelIndex & @LF)
    ; USE: DllStructGetData ( Struct, Element [, index = Default]

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

    $iPixel = DllStructGetData($tPixel, 1, $pixelIndex) ;get pixel color
    $out &=hex($iPixel)& @CRLF
    Next
    Next

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

    ConsoleWrite("Reading vertically ==> " & TimerDiff($t) & @LF)

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

    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData) ;unlocks a portion of a bitmap that was locked by _GDIPlus_BitmapLockBits
    FileDelete(@ScriptDir & "\pixels.txt")
    FileWrite(@ScriptDir & "\pixels.txt", $out)

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

    ;cleanup resources
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

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

    EndFunc ;==>Example

    [/autoit]

    Ich habe Beispiel "template.bmp" im Anhang.

    Bei Delphi dauert dieser Procedur nur wenige Sekunden.

    PS: Deutsch ist nicht meine Muttersprache, entschuldige Sprachfehler... :S

  • Schaue mal in der Hilfe unter _GDIPlus_BitmapLockBits() nach. Dort ist ein Beispiel, wie man an die Pixel Informationen kommt.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ja, genau dieses Beispiel habe ich auch benutzt. Es geht auch, aber ist aus meiner sicht sehr langsam.

    Ich habe anderswo eine trick gesehen mit fileread() und StringMid(), immerhin ist die 1-Bit BMP sehr einfach. Leider kriege ich es nicht hin. :cursing:

  • Hi,
    habe gerade im "blauen" Forum dein crossposting gesehen...

    Verstehen kann man das aber nicht!
    Pixel auslesen und in ein "1-Bit"-Array übertragen ist eine Sache von einigen Millisekunden, egal wie groß deine Bitmap ist, das ist nicht das Problem!

    Für mich unverständlich ist, wieso du die in Zeilen angeordneten Pixel später Spaltenweise in Bytes "umdrehen" willst?!
    Ist das wirklich so gemeint? 90° Drehung und dann RGBA nach Bit konvertieren?

    Oder soll die Bitmap in eine einfache 1-Bit per Pixel Bitmap transferiert werden?

    //EDIT Ich vermute, du hast mit den "Scanlines" etwas missverstanden. "Scan lines" bedeutet die ZEILENWEISE Abtastung des Bildes, wie sie normalerweise auch durchgeführt wird. Du möchtest aber SPALTENWEISE das Bild abtasten? Ist das wirklich so gemeint?

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (4. Februar 2014 um 19:30)

  • Ich entschuldige, meine Erklärung war (von Anfang an) zu schlecht... :wacko:

    Also..
    Sehe Dateien im Anhang.

    Ausgangspunkt ist eine 1 bpp BMP, dort sind die Pixel in Bytes gespeichert, von unten Links, nach Oben Rechts. So weit klar.
    Eine 16 x 32 pixel Bild hat 32 Reien á 2 Bytes = 16 bit. Erste Reihe wird dann 0b1000000 = 0x80 (oder, in einige Fälle 0b01111111 = 0x7F).

    Ich möchte gern das Bild SPALTENWEISE lesen, so das ich 16 x 4 Bytes (16 x 32 pixel) im Enddatei habe. Note: Im Enddatei ist auch Metadata, das habe ich im Griff.

    Bitrotation und BitAnd/Or ist mir klar, wenn nötig. Ich kann auch schon die Pixel einzeln auslesen, GetPixel ist aber viel zu langsam.

    Es ist warscheinlich sehr einfach, und ich habe irgendwas verpasst. Aber dann werde ich hoffenlich zulernen.

    Die Delphi-code dafür habe ich, auch im Anhang.

    Ist es möglich - ohne GetPixel ?

  • Probiere es mal damit:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <GDIPlus.au3>

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

    _GDIPlus_Startup()
    Global $hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\Monochrom 16x32.bmp")
    If _GDIPlus_ImageGetWidth($hBitmap) <> 16 Or _GDIPlus_ImageGetHeight($hBitmap) <> 32 Then Exit MsgBox(0, "Fehler", "Bild ist nicht 16x32 Pixel groß!") * _GDIPlus_Shutdown()
    $iTimer = TimerInit()
    $aResult = BitmapToBinary($hBitmap)
    ConsoleWrite(TimerDiff($iTimer) & @LF)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    _ArrayDisplay($aResult)

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

    Func BitmapToBinary($hImage)
    Local $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) ;get width and height of the image
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsDrawImageRect($hContext, $hImage, 0, 0, $iW, $iH)

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

    Local $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, BitOR($GDIP_ILMWRITE, $GDIP_ILMREAD), $GDIP_PXF32ARGB) ;locks a portion of a bitmap for reading and writing. More infor at http://msdn.microsoft.com/en-us/library/…8(v=vs.85).aspx
    Local $iScan0 = DllStructGetData($tBitmapData, "Scan0") ;get scan0 (pixel data) from locked bitmap
    Local $iSearchPixel = Int(0xFF000080), $iReplaceColor = 0x00000000 ;color format 0xAARRGGBB
    Local $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0)
    Local $iPixel, $iRowOffset, $iX, $iY, $iVal, $iBits, $y = 0, $z = 0, $aBytes[16*4]

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

    For $iX = 0 To $iW - 1
    For $iY = 0 To $iH - 1 ;get each pixel in each line and row
    $iPixel = BitAND(DllStructGetData($tPixel, 1, 1 + $iX + ($iY * $iW)), 1) ;get pixel color
    $iBits &= $iPixel
    $iVal += $iPixel * 2 ^ (7 - $z)
    $z += 1
    If $z = 8 Then
    $aBytes[$y] = $iVal
    $y += 1
    $iVal = 0
    $iBits = ""
    $z = 0
    EndIf
    Next
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData) ;unlocks a portion of a bitmap that was locked by _GDIPlus_BitmapLockBits
    Return $aBytes
    EndFunc

    [/autoit]

    Bei mit benötigt die Operation für ein 16x32 ca. 3.5 Millisekunden.

    Das Resultat landet in einem Array, so dass Viererblöcke eine Spalte abbilden (0-3, 4-7, etc.).

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • UEZ,

    Fast korrekt. Ich habe dein Beispiel ein Bisschen geändert - die Reihenfolge der Pixel war umgekehrt. Jetzt geht es, und Erbebnis scheint korrekt zu sein.

    Leider dauert eine Bild von 1152 * 3680 etwa 18 Sekunden. Das gleiche in PHP oder Delphi ugf. 3-4 Sekunden.

    Meine gedanken ab hier um das ganze schneller zu machen:

    • DLL wie zB FreeImage zu nutzen (wird das Schneller sein ?)
    • Lesen mit LockBits und $GDIP_PXF01INDEXED - die Struktur ist wohl jetzt 32 Bit ? Aber das kriege ich mit DllStrukt nicht hin

    Wenn es überhaupt nicht möglich ist, muss ich mit 18 Sek leben.

    Mein Code so weit:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <GDIPlus.au3>

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

    Opt('ExpandVarStrings', 1) ; can put vars in strings...for debugging

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

    _GDIPlus_Startup()
    Global $hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\template.bmp")

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

    If _
    (mod(_GDIPlus_ImageGetWidth($hBitmap), 8)>0) Or _
    (mod(_GDIPlus_ImageGetHeight($hBitmap), 8)>0) Then Exit MsgBox(0, "Fehler", "Bild ist nicht Interger von 8 groß!") * _GDIPlus_Shutdown()
    $iTimer = TimerInit()
    $aResult = BitmapToBinary($hBitmap)
    ConsoleWrite(TimerDiff($iTimer) & @LF)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

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

    ; ===========================================================
    ; write output
    ;
    FileDelete(@ScriptDir & "\out.log")
    $of = FileOpen(@ScriptDir & "\out.log", 2 + 16)
    For $i = 0 To UBound($aResult) - 1
    FileWrite($of, Chr($aResult[$i]))
    Next
    FileClose($of)

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

    ; ==================================================================
    ; BipmapToBinary
    ;
    ; macht aus PixelData eine Array
    ; Pixel werden per Column gelesen
    ; pixel 8,7,...1 ; 16,15,...9 etc
    ;
    Func BitmapToBinary($hImage)
    Local $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) ;get width and height of the image
    ConsoleWrite("BMP size: Width = $iW$ and Height = $iH$ " & @LF)

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

    Local $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;locks a portion of a bitmap for reading and writing. More infor at http://msdn.microsoft.com/en-us/library/…8(v=vs.85).aspx
    Local $iScan0 = DllStructGetData($tBitmapData, "Scan0") ;get scan0 (pixel data) from locked bitmap

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

    Local $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0)
    Local $iPixel, $iRowOffset, $iX, $iY, $iVal, $iBits, $y = 0, $z = 0
    $rowsize_bytes = Floor((1 * $iW + 31) / 32) * 4
    $pixel_size = $rowsize_bytes * $iH
    ConsoleWrite("Pixelsize = $pixel_size$" & @LF)
    local $aBytes[$pixel_size]

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

    $repeats = $iH / 8 ; read each column by block of 1 byte = 8 pixel/bit

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

    For $iX = 0 To $iW - 1 ; first take each COLUMN...
    For $byteblock = 0 To $repeats-1
    ; byteblock = 0
    ; 8 7 6 ... 1 ==>> 8 * 0 + 8 ... 8 * 0 +1
    ; byteblock = 1
    ; 16 15 .. 9
    ; etc

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

    $bb_start = (8*$byteblock )+7 ; ==> pixel data 0-based
    $bb_end = (8*$byteblock)

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

    for $iY = $bb_start to $bb_end step -1
    $iPixel = BitAND(DllStructGetData($tPixel, 1, 1 + $iX + ($iY * $iW)), 1) ;get pixel color
    $iBits &= $iPixel
    $iVal += $iPixel * 2 ^ (7 - $z) ; THIS little trick converts it to a number... NICE touch...
    $z += 1
    If $z = 8 Then
    $aBytes[$y] = 255-$iVal ; final output needs to be reversed in color
    $y += 1
    $iVal = 0
    $iBits = ""
    $z = 0
    EndIf
    Next ; height
    Next ; byteblock
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData) ;unlocks a portion of a bitmap that was locked by _GDIPlus_BitmapLockBits
    Return $aBytes
    EndFunc ;==>BitmapToBinary

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Update: versuch mit _FreeImage_GetPixelIndex($ImageHandle, $iX, $iY, $i) :
    Funktion von UEZ (GDI+): etwa 18 Sek
    FreeImage _FreeImage_GetPixelIndex() : über 80 Sekunden (!)

    ScanLines() mit FreeImage währe evtl eine Lösung.

  • Du sagtest was von 32x16 großen Bildern, aber jetzt ist von großen Bildern die Rede.

    Da AutoIt ab einer bestimmten Größe für solche Zwecke nicht mehr geeignet ist, müsstest du auf Alternativen zurück greifen.
    Die beste Lösung wäre Inline ASM, aber darin bin ich nicht fit genug, um eine Lösung zu basteln.

    Vielleicht können dir die ASM Cracks hierbei weiter helfen.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • UEZ.. ich schrieb "32 x n".. aber korrekt, es hätte deutlicher sein können.

    DANKE trotzdem für die Hilfe, jetzt bin ich über 2 Tage viel schlauer geworden, über BMPs etc.

  • Man muss nicht gezwungenermaßen ASM verwenden, möglicherweise reicht GDI+

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>

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

    _GDIPlus_Startup()
    Global $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\template.bmp")
    Global $iImgW = _GDIPlus_ImageGetWidth($hImage)
    Global $iImgH = _GDIPlus_ImageGetHeight($hImage)

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

    Global $iBmpW = $iImgH
    Global $iBmpH = $iImgW
    Global $iBmpStride = Int($iBmpW / 8)
    If Mod($iBmpStride, 4) Then $iBmpStride += 4 - Mod($iBmpStride, 4) ;BMP format requires that each row begins on a four-byte boundary

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

    Global $tPixel = DllStructCreate("byte[" & $iBmpStride * $iBmpH & "];")
    Global $hBitmap = _GDIPlus_BitmapCreateFromScan0($iBmpW, $iBmpH, $GDIP_PXF01INDEXED, $iBmpStride, DllStructGetPtr($tPixel))
    Global $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)

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

    _GDIPlus_GraphicsRotateTransform($hContext, 90)
    _GDIPlus_GraphicsTranslateTransform($hContext, $iBmpW, 0, True)

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

    Global $hIA = _GDIPlus_ImageAttributesCreate()
    Global $tCM = _GDIPlus_ColorMatrixCreateNegative()
    _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $tCM)
    _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $iImgW, $iImgH, 0, $iBmpW, $iBmpH, -$iBmpW, $hIA)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_GraphicsDispose($hContext)

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

    Global $bPixel = StringTrimLeft(DllStructGetData($tPixel, 1), 2)

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

    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

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

    Global $iByteChars = $iBmpW / 4
    Global $iByteCharStride = $iBmpStride * 2 - $iByteChars

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

    If $iByteCharStride <> 0 Then $bPixel = StringRegExpReplace($bPixel, "(.{" & $iByteChars & "}).{" & $iByteCharStride & "}", "$1")

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

    Global $hFile = FileOpen(@ScriptDir & "\Out.log", 18)
    FileWrite($hFile, "0x" & $bPixel)
    FileClose($hFile)

    [/autoit]

    Ich hab aber auch noch nicht ganz verstanden, was eigentlich der Sinn und Zweck dieses Scriptes sein soll...

    E

  • Hi,
    zuerst dachte ich auch an eine Drehung, das stimmt aber leider nicht
    Die obersten 8 Bit in der ersten Spalte sollen in umgekehrter Bitfolge als erstes Byte in der Zeile stehen!
    Aus dem jeweils ersten Bit (MSB) in der ersten Spalte
    1
    0
    0
    1
    1
    1
    1
    1
    soll das erste Byte 11111001 werden.

    Zitat

    Ich hab aber auch noch nicht ganz verstanden, was eigentlich der Sinn und Zweck dieses Scriptes sein soll...

    Ich vermute, irgendein esoterisches Programm liest diese seltsamen Dateien ein...
    Irgendwo habe ich etwas mit Barcodes gelesen, das erklärt manches ;(

    //EDIT
    Die Drehung ist aber schon einmal ein guter Anfang! Dann muss man nur noch die Bytes in der Zeile von vorne nach hinten XCHGen und innerhalb der Bytes die Bitfolge ändern 8| ich glaube, die Bitmap direkt umzuwandeln geht dann in ASM 5x schneller als die GDI-Drehung alleine^^

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (6. Februar 2014 um 17:47)

  • Was ist eigentlich der Zweck, Bitmaps in dieses Format umzuwandeln?

    Gruß,
    UEZ

    Ja, sollte ich vielleicht auch erklären :)

    Zweck ist die Bitmaps auf eine industrieller Controller zu nutzen. Es ist möglich die Bitmaps mittels einer Designprogramm umzuwandeln, aber diese Programm ist recht schwierig zu nutzen. Ich möchte gern 1) eine 1-Click Lösung bauen, und 2) für Automatisierung eine UDF (für meine nutzen, hat wohl nicht generell Interesse). Arh, und ich werde dazu auch viel über BMPs, byte/bit-umwandlung etc erfahren. Dank an Euch.

  • Zitat

    Ich möchte gern 1) eine 1-Click Lösung bauen, und 2) für Automatisierung eine UDF (für meine nutzen, hat wohl nicht generell Interesse). Arh,

    Hah 8o , "kein generelles Interesse", das ist genau der Ansporn, die "brotlose Kunst" (Insiderwitz) umzusetzen.
    Ich hoffe am Wochenende etwas Zeit zu haben, die ASM-Lösung, die schon in Papierform vorliegt, in Code umzusetzen.
    Die Idee ist, das aktuelle Bit aus dem Quellbyte ins Carryflag zu schieben und von dort direkt ins Zielbyte. Dazu braucht man nicht einmal eine komplizierte Schleife, die Quellbytes werden in einer Reihe nacheinander abgearbeitet, lediglich die "Zieladresse" muss angepasst werden.

  • Andy.. du hast recht, eine UDF hat im grunde immer Interesse.

    Die Lösung von Eukalyptus ist im Grunde nicht weit vom Ziel, allerdings liegen die Bits falsch rum.. 01000000 statt 00000010. Wie kann ich diese Bitrotation im griff hätte..

    Aber ich bin voller neugier von diene ASM-Lösung. Wie kann ich dir danken ?

    - myicq