2011-01-22 6 views
3

こんにちはここでは、8 bppの.BMPイメージを左右反転するコードを開発しました。 4の倍数だけでなく、どのような幅でも適切に扱うことができます。今度は同じコードを1 bppに変換する必要があります。 x86を使用したbmpイメージ(グレースケール)。難しい部分は、私は個々のビットを超過する方法を知っていないかもしれないということです。"8bpp .bmp image"を水平に反転させるコードを変更してx86の水平方向に "1bpp .bmp image"を反転する

 section  .text 
    global  mirrorbmp8 
mirrorbmp8: 
    push  ebp 
    mov  ebp, esp 
    push  ebx 
    push  esi 
    push  edi 

    mov  ebx, [ebp+12]  ;width - without padding 
    and  ebx, 11b 
    je  init   ;checking if there is a padding 
    mov  edi, 4 
    sub  edi, ebx 
    add  [ebp+12], edi  ;width - with padding 

init: 
    mov  ebx, [ebp+16] 
    ;calculating the distance between top&bottom pixel 
    dec  ebx 
    mov  eax, [ebp+12] 
    mul  ebx 
    mov  esi, eax 

    mov  edi, [ebp+8] ;the first bottom pixel 
    mov  edx, edi   ;the first top pixel 
    mov  eax, edi 
    add  eax, esi 
    mov  ecx, [ebp+12] 
      ;register responsible for calc left columns 

loop0: 
    push  esi 
    mov  esi, [ebp+12] 

loop1: 
    mov  bl, [edi]    ;changing pixels 
    xchg  bl, [eax] 
    mov  [edi], bl 

    add  edi, esi  ;next pixel in this column 
    sub  eax, esi 
    cmp  edi, eax 
    jl  loop1 


    inc  edx    ;next bottom pixel 
    mov  edi, edx 

    mov  eax, edi    ;next top pixel 
    pop  esi 
    add  eax, esi 

    dec  ecx   ;decrement number of columns left 
    jnz  loop0   ;was that the last column? 



end: 
    pop  edi 
    pop  esi 
    pop  ebx 

    mov  esp, ebp 
    pop  ebp 
    ret 

助けていただければ幸いです。事前に 感謝:)

psの私は、このバージョンを行うことができるようになります場合は、私は、この点で任意のヒントも参考になります、また、x86-64のバージョンのために全体のコードを変換する必要があります。..

+0

コードが水平にではなく垂直にイメージを反転しているように見えます。何か不足していますか? – interjay

+0

これは垂直反転ではない水平反転のためのものです:) – DinMan

答えて

0

ビットマップは、走査線ごとに1行の画素を有する走査線に格納される。あなたが本当にしなければならないことは、これらの行の順序を逆にすることだけです。最初のステップは、ビットマップのヘッダを別のファイルにコピーすることです。次に、各走査線の長さを計算する必要があります。各走査線は常に32ビットのパディングされているので、あなたには、いくつかの数学をする必要があります:

scanlineLength = imageWidth/8 
IF imageWidth % 32 != 0 
    scanlineLength += 1 
ENDIF 

次に、新しいファイルに古いファイルからscanlineLengthバイトをコピーします。 1つのスキャンラインまで上に移動し、それらがすべてコピーされるまでプロセスを繰り返します。

編集:あなたの質問を再読み込みした後も、イメージを反転させる方法がわからないので、これが当てはまるかどうかわかりません。

+0

私は画像を水平に反転していますが、x86レジスタでは最小のレジスタとしてのシングルビットは8ビットです。 – DinMan

+0

私の他の答えを見てください。 – Sparafusile

1

画像を上下左右に反転させる方法を知りたい場合は、ここで説明します。

まず、ビットマップのヘッダーを別のファイルにコピーします。以下の例で

orphanBits = imageWidth % 32 

orphanedBits 19.一般的な2に走査線の端から最後の二つDWORDS読み出される:次に、imageWidth過ぎ%32は、各走査線の端部にある何ビットを見つけ出します汎用レジスタ:

shrd eax, ebx, orphanBits 

ebx = 00000000 00000000 00010001 01011010 
eax = 10100101 01010101 01001010 10101011 
         END OF SCAN LINE^

は、次のコードを使用する:全体のレジスタが満たされるまで

ebx = 10001010 11010101 00101010 10101010 
eax = 01010101 01011000 00000000 00000000 
    END OF SCAN LINE^

はECXにEBXからのビットを移動するSHRDオペランドを使用しますeaxのビットをスワップする:

mov edx,eax 
shr eax,1 
and edx,055555555h 
and eax,055555555h 
lea eax,[2*edx+eax] 
mov edx,eax 
shr eax,2 
and edx,033333333h 
and eax,033333333h 
lea eax,[4*edx+eax] 
mov edx,eax 
shr eax,4 
and edx,0F0F0F0Fh 
and eax,0F0F0F0Fh 
shl edx,4 
add eax,edx 
bswap eax 

eax = 11010101 01010010 10101010 10100101 
    ^END OF SCAN LINE 

新しいイメージに調整DWORD(現在は逆の順序で)を書きます。スキャンライン全体が読み取られるまで繰り返します。すべてのスキャンラインが読み取られるまで繰り返す。

編集:もともと私はそれがビットではなくビットを交換したことを思い出す前にbswapを持っていました。

関連する問題