title mapa.asm page ,132 ?PLM=1 ; PASCAL Calling convention is DEFAULT ?WIN=0 ; Windows calling convention .xlist include cmacro32.inc include windows.inc .list ; ------------------------------------------------------- ; DATA SEGMENT DECLARATIONS ; ------------------------------------------------------- ifndef SEGNAME SEGNAME equ <_TEXT> endif createSeg %SEGNAME, CodeSeg, word, public, CODE sBegin CodeSeg .386 assumes cs,CodeSeg assumes ds,nothing assumes es,nothing ;--------------------------------------------------------------------------; ; ; STOSB32 - store a byte, every four times doing a STOSD ; ;--------------------------------------------------------------------------; STOSB32_N = 0 STOSB32 macro ror eax,8 ; rotate pixel (al) into eax STOSB32_N = STOSB32_N + 1 if (STOSB32_N mod 4) eq 0 ;; stos dword ptr es:[edi] mov dword ptr es:[edi], eax add edi,4 endif endm ;--------------------------------------------------------------------------; ; ; LODSB32 - get a byte, every four times doing a LODSD ; ;--------------------------------------------------------------------------; LODSB32_N = 0 LODSB32 macro if (LODSB32_N mod 4) eq 0 ;; lods dword ptr ds:[esi] mov eax,dword ptr ds:[esi] add esi,4 else ror eax,8 endif LODSB32_N = LODSB32_N + 1 endm ;--------------------------------------------------------------------------; ; ; MAP16 ; ;--------------------------------------------------------------------------; MAP16 macro n if n and 1 shr ebx,16 ; get pel from last time else mov ebx, dword ptr ds:[esi] ; grab two pels add esi,4 endif ; ; BX contains 5:5:5 RGB convert it to a 8:8:8 RGB ; mov al,bl shl al,3 STOSB32 shr bx,2 mov al,bl and al,0F8h STOSB32 mov al,bh shl al,3 STOSB32 endm ;--------------------------------------------------------------------------; ; ; Map16to24() ; ; Entry: ; Stack based parameters as described below. ; ; Returns: ; none ; ; Registers Preserved: ; DS,ES,ESI,EDI,EBP ; ;--------------------------------------------------------------------------; assumes ds,Data assumes es,nothing cProc Map16to24,,<> parmD biDst ;--> BITMAPINFO of dest parmD lpDst ;--> to destination bits parmW DstX ;Destination origin - x coordinate parmW DstY ;Destination origin - y coordinate parmW DstXE ;x extent of the BLT parmW DstYE ;y extent of the BLT parmD biSrc ;--> BITMAPINFO of source parmD lpSrc ;--> to source bits parmW SrcX ;Source origin - x coordinate parmW SrcY ;Source origin - y coordinate parmD lpDitherTable ;not used localD SrcWidth ;width of source in bytes localD DstWidth ;width of dest in bytes localD SrcInc localD DstInc cBegin push esi push edi push ds ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; align everything on four pixel boundries, we realy should ; not do this but should handle the general case instead, ; but hey we are hackers. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; and DstXE, not 011b ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; mov eax,16 ; source 16 mov ebx,24 ; dest 24 call map_init ; init all the frame variables jc Map16to24Exit movzx eax, DstXE ; inner loop expanded by 4 shr eax, 2 jz Map16to24Exit mov DstXE,ax ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; align 4 Outer16to24Loop: movzx ecx,DstXE align 4 Inner16to24Loop: MAP16 0 MAP16 1 MAP16 2 MAP16 3 dec ecx jnz Inner16to24Loop add edi, DstInc add esi, SrcInc dec DstYE jnz Outer16to24Loop ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Map16to24Exit: pop ds pop edi pop esi cEnd ;--------------------------------------------------------------------------; ; ; Map32to24() ; ; Entry: ; Stack based parameters as described below. ; ; Returns: ; none ; ; Registers Preserved: ; DS,ES,ESI,EDI,EBP ; ;--------------------------------------------------------------------------; assumes ds,Data assumes es,nothing cProc Map32to24,,<> parmD biDst ;--> BITMAPINFO of dest parmD lpDst ;--> to destination bits parmW DstX ;Destination origin - x coordinate parmW DstY ;Destination origin - y coordinate parmW DstXE ;x extent of the BLT parmW DstYE ;y extent of the BLT parmD biSrc ;--> BITMAPINFO of source parmD lpSrc ;--> to source bits parmW SrcX ;Source origin - x coordinate parmW SrcY ;Source origin - y coordinate parmD lpDitherTable ;not used localD SrcWidth ;width of source in bytes localD DstWidth ;width of dest in bytes localD SrcInc localD DstInc localW OriginalDstXE cBegin push esi push edi push ds ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; align everything on four pixel boundries, we realy should ; not do this but should handle the general case instead, ; but hey we are hackers. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; mov ax, DstXE mov OriginalDstXE, ax mov bx, ax add ax, 011b and ax, not 011b mov DstXE, ax and bx, 011b jz short @f dec DstYE ; if the width isn't a multiple of 4, special- ; case the last line. @@: ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; mov eax,32 ; source 32 mov ebx,24 ; dest 24 call map_init ; init all the frame variables jc Map32to24Exit movzx eax, DstXE ; inner loop expanded by 4 shr eax, 2 jz short Map32to24Exit mov DstXE,ax ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; align 4 Outer32to24Loop: movzx ecx,DstXE align 4 Inner32to24Loop: mov eax,[esi] ; eax = XRGB mov ebx,[esi+4] ; ebx = xrgb shl eax,8 ; eax = RGB0 shrd eax,ebx,8 ; eax = bRGB mov es:[edi],eax ; store pels shl ebx,8 ; ebx = rgb0 mov eax,[esi+8] ; eax = XRGB shrd ebx,eax,16 ; ebx = GBrg mov es:[edi+4],ebx ; store pels shl eax,8 ; eax = RGB0 mov ebx,[esi+12] ; ebx = xrgb shrd eax,ebx,24 ; eax = rgbR mov es:[edi+8],eax ; store pels add esi,16 add edi,12 dec ecx jnz Inner32to24Loop add edi, DstInc add esi, SrcInc dec DstYE jnz Outer32to24Loop ; done, but might have to do one more scan line mov ax, OriginalDstXE and ax, 011b jz short Map32to24Exit movzx ecx,OriginalDstXE align 4 @@: ; one more scan line to do.... mov eax,[esi] ; eax = XRGB shl eax,8 ; eax = RGB0 mov es:[edi], ah shr eax,16 ; eax = 00RG mov es:[edi+1], ax add esi,4 add edi,3 dec ecx jnz @b ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Map32to24Exit: pop ds pop edi pop esi cEnd ;--------------------------------------------------------------------------; ; ; map_init ; ; init local frame vars for mapDIB ; ; ENTRY: ; AX - source bpp ; BX - dest bpp ; ss:bp --> mapdib frame ; ; EXIT: ; DS:ESI --> source DIB start x,y ; ES:EDI --> dest DIB start x,y ; ;--------------------------------------------------------------------------; map_init_error: stc ret map_init proc near ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; validate the DIBs ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; xor edi,edi xor esi,esi lds si, biSrc les di, biDst movzx ecx, es:[di].biBitCount ; dest must be right cmp cx, bx jne map_init_error mov cx, [si].biBitCount ; source must be 16 cmp cx, ax jne map_init_error map_init_bit_depth_ok: ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; ; Set up the initial source pointer ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; mov eax,[si].biWidth mul ecx add eax,31 and eax,not 31 shr eax,3 mov SrcWidth,eax mov SrcInc,eax lds si,lpSrc movzx edx,SrcY mul edx add esi,eax movzx eax,SrcX mul ecx shr eax,3 add esi,eax movzx eax, DstXE ; SrcInc = SrcWidth - DstXE*bits/8 mul ecx shr eax, 3 sub SrcInc, eax ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; ; Set up the initial dest pointer ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; movzx ecx, es:[di].biBitCount mov eax,es:[di].biWidth mul ecx add eax,31 and eax,not 31 shr eax,3 mov DstWidth,eax mov DstInc,eax les di,lpDst movzx edx,DstY mul edx add edi,eax movzx eax,DstX mul ecx shr eax,3 add edi,eax movzx eax, DstXE ; DstInc = DstWidth - DstXE*bits/8 mul ecx shr eax, 3 sub DstInc, eax ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; map_init_exit: clc ret map_init endp ;--------------------------------------------------------------------------; ; ; HugeToFlat ; ; map a bunch of bitmap bits in "huge" format to "flat" format ; ; this code only works for bitmaps <= 128k ; ; Entry: ; Stack based parameters as described below. ; ; Returns: ; none ; ; Registers Preserved: ; DS,ES,ESI,EDI,EBP ; ;--------------------------------------------------------------------------; assumes ds,nothing assumes es,nothing cProc HugeToFlat,,<> parmD lpBits ;--> bits parmD cbBits ;count of bits. parmD FillBytes ;the fill bytes cBegin push esi push edi push ds mov ax,word ptr lpBits[2] mov ds,ax mov es,ax mov eax,FillBytes mov ecx,cbBits add ecx,eax mov esi,00010000h sub ecx,esi mov edi,esi sub edi,eax shr ecx,2 rep movsd pop ds pop edi pop esi cEnd ;--------------------------------------------------------------------------; ; ; FlatToHuge ; ; map a bunch of bitmap bits in "flat" format to "huge" format ; ; this code only works for bitmaps <= 128k ; ; Entry: ; Stack based parameters as described below. ; ; Returns: ; none ; ; Registers Preserved: ; DS,ES,ESI,EDI,EBP ; ;--------------------------------------------------------------------------; assumes ds,Data assumes es,nothing cProc FlatToHuge,,<> parmD lpBits ;--> bits parmD cbBits ;count of bits. parmD FillBytes ;the fill bytes cBegin push esi push edi push ds mov ax,word ptr lpBits[2] mov ds,ax mov es,ax mov eax,FillBytes mov ecx,cbBits add ecx,eax mov edi,ecx sub edi,4 mov esi,edi sub esi,FillBytes sub ecx,00010000h std shr ecx,2 rep movsd cld pop ds pop edi pop esi cEnd sEnd CodeSeg end