2011-01-22 7 views
3

안녕하십니까, 저는 8bpp .BMP 이미지를 수평/반전시키기위한 코드를 개발했습니다. 4의 배수뿐만 아니라 모든 너비를 적절히 처리합니다. 이제는 1 bpp에 대해서도이 코드를 변환해야합니다. x86을 사용하는 bmp 이미지 (회색조). 어려운 부분은 개인 비트를 초과 할 수있는 방법을 모른다는 것입니다.x86에서 수평으로 "1bpp .bmp image"를 뒤집기 위해 코드를 "8bpp .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 

도움이 되겠습니다. 사전 :

난 다음이 버전을 나는 또한,이 점에서 어떤 힌트도 도움이 될 것입니다 - 64 버전에 대한 전체 코드를 변환해야 할 수있을 것입니다 경우

PS ..

+0

코드가 가로로가 아니라 이미지를 세로로 넘기는 것처럼 보입니다. 내가 놓친 게 있니? – interjay

+0

이것은 수평이 아닌 수직으로 뒤집기위한 것입니다. – DinMan

답변

0

에서 감사합니다 비트 맵은 스캔 라인 당 픽셀의 한 라인으로 스캔 라인에 저장됩니다. 당신이 정말로해야 할 일은이 줄들의 순서를 바꾸는 것뿐입니다. 전 단계는 비트 맵의 ​​헤더를 다른 파일에 복사하는 것입니다. 그런 다음 각 스캔 라인의 길이를 계산해야합니다. ,

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

다음 새 파일로 이전 파일에서 scanlineLength 바이트를 복사 : 각 주사선은 항상 32 비트 패딩이기 때문에, 당신은 몇 가지 계산을해야합니다. 하나의 주사선 위로 이동하고 모두 복사 될 때까지 프로세스를 반복하십시오.

편집 : 질문을 다시 읽은 후에도 이미지를 뒤집을 방법이 아직 확실하지 않으므로 확신 할 수 없습니다.

+0

저는 이미지를 수평으로 뒤집을 수 있습니다. x86 레지스터에 액세스 할 수 없기 때문에 1 bpp 이미지에 대해 어떻게하는지 알고 싶습니다. 가장 작은 레지스터로서의 단일 비트는 8 비트이다. – DinMan

+0

제 다른 대답을 참조하십시오. – Sparafusile

1

위에서 아래로가 아니라 왼쪽에서 오른쪽으로 이미지를 뒤집는 방법을 알고 싶다면 다음과 같이하십시오.

먼저 비트 맵의 ​​헤더를 다른 파일로 복사하십시오. orphanedBits 19. 일반 둘로 주사선의 끝에서 마지막 두 개의 dword를 판독되고, 아래의 예에서

orphanBits = imageWidth % 32 

: 다음 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 만있었습니다.

관련 문제