измените код с переворачивания "8bpp .bmp image" по горизонтали, чтобы перевернуть "1bpp .bmp image" горизонтально в x86 - PullRequest
3 голосов
/ 22 января 2011

Здравствуйте, я разработал код для зеркала / переворачивания изображения размером 8 бит на пиксель .BMP по горизонтали. Правильная обработка любой ширины, не только кратных 4. Теперь я должен преобразовать этот код, чтобы сделать то же самое, но для 1 bpp. Изображение BMP (в оттенках серого) с использованием x86. Сложность в том, что я не знаю, как перебить индивидуальный бит, может быть, кто-то сможет отредактировать этот код ..

        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

Любая помощь будет оценена. Заранее спасибо:)

p.s, если я смогу сделать эту версию, то мне придется также конвертировать весь код для версии x86-64, любые подсказки на этот счет также будут полезны.

Ответы [ 2 ]

1 голос
/ 23 января 2011

Если вы хотите узнать, как перевернуть изображение слева направо, а не сверху вниз, вот как вы это сделаете.

Сначала скопируйте заголовки растрового изображения в другой файл.Затем выясните, сколько битов после imageWidth% 32 находятся в конце каждой строки сканирования:

orphanBits = imageWidth % 32

В приведенном ниже примере orphanedBits равно 19. Считайте последние два DWORDS с концаотсканируйте в два регистра общего назначения:

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, прежде чем я вспомнил, что он поменял местами байты, а не биты.

0 голосов
/ 23 января 2011

Растровые изображения хранятся в строках сканирования по одной строке пикселей на строку сканирования.Все, что вам действительно нужно сделать, это изменить порядок этих строк.Первым шагом будет копирование заголовков растрового изображения в другой файл.Затем вы должны рассчитать длину каждой линии сканирования.Поскольку каждая строка развертки всегда дополняется 32-разрядным, вам понадобится математика:

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

Затем скопируйте scanlineLength байтов из старого файла в новый файл.Переместите одну строку сканирования и повторяйте процесс до тех пор, пока все они не будут скопированы.

Редактировать: После перечитывания вашего вопроса я все еще не уверен, каким образом вы переворачиваете изображения, поэтому я не уверен, применимо ли это.

...