home *** CD-ROM | disk | FTP | other *** search
- page ,132
- ;-----------------------------Module-Header-----------------------------;
- ; Module Name: RLEA.ASM - helper routines for RLE stuff
- ;
- ; Exported Functions: none
- ;
- ; Public Functions: DecodeRle386
- ;
- ; Public Data: none
- ;
- ; General Description:
- ;
- ; Restrictions:
- ;
- ;-----------------------------------------------------------------------;
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; (C) Copyright Microsoft Corp. 1991. All rights reserved.
- ;
- ; You have a royalty-free right to use, modify, reproduce and
- ; distribute the Sample Files (and/or any modified version) in
- ; any way you find useful, provided that you agree that
- ; Microsoft has no warranty obligations or liability for any
- ; Sample Application Files which are modified.
- ;
- ; Unless you got this from the MM Sys BBS, it may not be the most
- ; current version. We are continually improving our samples and
- ; their documentation. Call the BBS at 206 936-4082.
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- .xlist
- include cmacros.inc
- include windows.inc
- .list
-
- RLE_ESCAPE equ 0
- RLE_EOL equ 0
- RLE_EOF equ 1
- RLE_JMP equ 2
-
- ; The following structure should be used to access high and low
- ; words of a DWORD. This means that "word ptr foo[2]" -> "foo.hi".
-
- LONG struc
- lo dw ?
- hi dw ?
- LONG ends
-
- FARPOINTER struc
- off dw ?
- sel dw ?
- FARPOINTER ends
-
- wptr equ <word ptr>
- bptr equ <byte ptr>
-
- min_ax macro REG
- sub ax,REG
- cwd
- and ax,dx
- add ax,REG
- endm
-
- max_ax macro REG
- sub ax,REG
- cwd
- not dx
- and ax,dx
- add ax,REG
- endm
-
- ; -------------------------------------------------------
- ; DATA SEGMENT DECLARATIONS
- ; -------------------------------------------------------
-
- sBegin Data
-
- sEnd Data
-
- ; -------------------------------------------------------
- ; CODE SEGMENT DECLARATIONS
- ; -------------------------------------------------------
-
- ifndef SEGNAME
- SEGNAME equ <_TEXT>
- endif
-
- createSeg %SEGNAME, CodeSeg, word, public, CODE
- .386
-
- sBegin CodeSeg
- assumes cs,CodeSeg
- assumes ds,nothing
- assumes es,nothing
-
- ;---------------------------Public-Routine------------------------------;
- ; DecodeRle386
- ;
- ; Entry:
- ; lpbi bitmap info
- ; pb destination DIB
- ; pbRle RLE bits
- ;
- ; Returns:
- ; None
- ; Error Returns:
- ; None
- ; Registers Preserved:
- ; DS,SI,DI,SS,BP
- ; Registers Destroyed:
- ; all
- ; Calls:
- ; nothing
- ;-----------------------------------------------------------------------;
- assumes ds,nothing
- assumes es,nothing
-
- ;---------------------------Macro---------------------------------------;
- ; ReadRLE
- ;
- ; read a WORD from rle data
- ;
- ; Entry:
- ; DS:ESI --> rle data
- ; Returns:
- ; AX - word at DS:[ESI]
- ; DS:ESI advanced
- ;-----------------------------------------------------------------------;
- ReadRLE macro
- lods wptr ds:[esi]
- endm
-
- ;---------------------------Public-Routine------------------------------;
- ; DecodeRle386
- ;
- ; copy a rle bitmap to a DIB
- ;
- ; Entry:
- ; pBits - pointer to rle bits
- ; Returns:
- ; none
- ; Error Returns:
- ; None
- ; Registers Preserved:
- ; BP,DS,SI,DI
- ; Registers Destroyed:
- ; AX,BX,CX,DX,FLAGS
- ; Calls:
- ; INT 10h
- ;-----------------------------------------------------------------------;
- assumes ds,nothing
- assumes es,nothing
-
- cProc DecodeRle386, <FAR, PASCAL, PUBLIC>, <ds>
- ParmD lpbi
- ParmD pDest
- ParmD pBits
- cBegin
- push edi
- push esi
-
- xor edi,edi
- xor esi,esi
- xor eax,eax
- xor ecx,ecx
-
- lds si,lpbi
-
- mov ax,wptr [si].biWidth
- add ax,3
- and ax,not 3
- movzx ebx,ax ; ebx is next_scan
-
- les di,pDest
- lds si,pBits
- assumes ds,nothing
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; Start of RLE decoding
- ;
- ; DS:SI --> RLE bits
- ; ES:DI --> screen output (points to start of scan)
- ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltStart:
- mov edx,edi ; save start of scan
-
- RleBltNext:
- ReadRLE ; al=count ah=color
-
- or al,al ; is it a escape?
- jz RleBltEscape
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; We have found a encoded run (al != 0)
- ;
- ; al - run length
- ; ah - run color
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltEncodedRun:
- mov cl,al
- mov al,ah
-
- shr cx,1
- rep stos wptr es:[edi]
- adc cl,cl
- rep stos bptr es:[edi]
-
- jmp short RleBltNext
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; We have found a RLE escape code (al=0)
- ; Possibilities are:
- ; . End of Line - ah = 0
- ; . End of RLE - ah = 1
- ; . Delta - ah = 2
- ; . Unencoded run - ah = 3 or more
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltEscape:
- cmp ah,al
- je RleBltEOL
-
- inc al
- cmp ah,al
- je RleBltEOF
-
- inc al
- cmp ah,al
- je RleBltDelta
- errn$ RleBltUnencodedRun
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; We have found a un-encoded run (ah >= 3)
- ;
- ; ah is pixel count
- ; DS:SI --> pixels
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltUnencodedRun:
- mov cl,ah
-
- shr cx,1
- rep movs wptr es:[edi], wptr ds:[esi]
- adc cl,cl
- rep movs bptr es:[edi], bptr ds:[esi]
-
- inc esi ; !!! re-align source
- and si,not 1
- jmp short RleBltNext
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; We have found a delta jump, the next two bytes contain the jump values
- ; note the the jump values are unsigned bytes, x first then y
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltDelta:
- ReadRLE ; al = deltaX, ah = deltaY
-
- or ah,ah
- jnz RleBltDeltaXY
-
- RleBltDeltaX:
- add edi,eax
- jmp short RleBltNext
-
- RleBltDeltaXY:
- add edi,ebx
- add edx,ebx
- dec ah
- jnz RleBltDeltaXY
-
- add edi,eax
- jmp short RleBltNext
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; We have found a end of line marker, point ES:DI to the begining of the
- ; next scan
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltEOL:
- mov edi,edx ; go back to start of scan
- add edi,ebx ; advance to next scan
- jmp short RleBltStart ; go get some more
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; We have found a end of rle marker, clean up and exit.
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltEOF:
- errn$ RleBltExit
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- RleBltExit:
- pop esi
- pop edi
- cEnd
-
- sEnd
-
- end
-