assembly - 将代码从水平翻转“8bpp .bmp图像”更改为在x86中水平翻转“1bpp .bmp图像”

标签 assembly image-processing bitmap x86 x86-64

您好,我在这里开发了用于水平镜像/翻转8 bpp .BMP图像的代码。正确处理任何宽度,不仅是4的倍数。现在我必须转换此代码以执行相同的操作,但要1 bpp。使用x86的bmp图像(灰度)。困难的部分是我不知道如何增加单个位,也许有人可以编辑此代码。

        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


任何帮助将不胜感激。
提前致谢 :)

附言:如果我能够执行此版本,则我还必须将整个代码转换为x86-64版本,这方面的任何提示也将有所帮助。

最佳答案

如果您想知道如何从左到右而不是从上到下翻转图像,请按照以下步骤操作。

首先,将位图的标题复制到另一个文件中。接下来,找出在imageWidth%32之后有多少位在每条扫描线的末尾:

orphanBits = imageWidth % 32


在下面的示例中,orphanedBits为19。从扫描线的末尾将最后两个DWORD读取到两个通用寄存器中:

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


使用SHRD操作数将位从ebx移到ecx,直到填满整个寄存器为止:

shrd eax, ebx, orphanBits

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


然后使用以下代码交换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之前,我记得它交换字节,而不是位。

关于assembly - 将代码从水平翻转“8bpp .bmp图像”更改为在x86中水平翻转“1bpp .bmp图像”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4767761/

相关文章:

linux - 使用自定义引导加载程序创建可引导 ISO 镜像

assembly - ARM中的SP(栈)和LR是什么?

python - 如何更准确地检测带圆角的矩形

c++ - CUDA 并发内核启动不起作用

Android - 加载位图而不改变

ios - 关于 iOS 汇编语言的说明

linux - 用汇编语言访问 errno.h

python - 是否可以转换 4 :3 pictures to 16:9 using Python (2. 7)

java - 如何在Android中的AsyncTask中应用此代码?

windows - HDC 是否使用 alpha channel ?