windows-nt/Source/XPSP1/NT/multimedia/media/avi/drawdib.16/dither8.asm
2020-09-26 16:20:57 +08:00

264 lines
6.6 KiB
NASM

page ,132
;----------------------------Module-Header------------------------------;
; Module Name: DITHER.ASM
;
; dither a 256 color DIB down to a 16 color dib.
;
;-----------------------------------------------------------------------;
?PLM=1
?WIN=0
.xlist
include cmacro32.inc
include windows.inc
.list
sBegin Data
sEnd Data
; 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
ifndef SEGNAME
SEGNAME equ <_TEXT>
endif
createSeg %SEGNAME, CodeSeg, word, public, CODE
sBegin CodeSeg
.386
assumes cs,CodeSeg
assumes ds,nothing
assumes es,nothing
;--------------------------------------------------------------------------;
;
; DITHER
;
; Entry:
; dl pixel to dither (0-256)
; bl pattern x
; ah pattern y
; fs --> 8x256x8 dither table.
;
; HIWORD(eax) = 0
; HIWORD(ebx) = 0
;
; Returns:
; dl dithered pixel (0-15) (rotated into edx)
; bl pattern x (advanced mod 8)
;
;--------------------------------------------------------------------------;
DITH8 macro
mov al,dl ; get pel
mov dl,fs:[eax*8+ebx] ; get dithered version of the pixel.
ror edx,8
inc bl ; increment x
and bl,07h ; mod 8
endm
;--------------------------------------------------------------------------;
;
; DitherDIB()
;
; Entry:
; Stack based parameters as described below.
;
; Returns:
; none
;
; Registers Preserved:
; DS,ES,ESI,EDI,EBP
;
;--------------------------------------------------------------------------;
assumes ds,nothing
assumes es,nothing
cProc Dither8,<FAR,PUBLIC,PASCAL>,<>
parmD biDst ;--> BITMAPINFO of the 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 the source
parmD lpSrc ;--> to source bits
parmW SrcX ;Source origin - x coordinate
parmW SrcY ;Source origin - y coordinate
parmD lpDitherTable ;dither table.
LocalD DstWidth
LocalD SrcWidth
cBegin
cld
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 SrcX, not 011b ; align by four
add DstXE, 3
and DstXE, not 011b
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
call dither_init ; init all the frame variables
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; time to do the dither.
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
mov ax,DstY
and ax,07h
mov ah,al ; ah has the scanline mod 8
movzx eax,ax
movzx ebx,bx
movzx ecx,cx
align 4
DitherOuterLoop:
movzx ebx,DstX
and ebx,07h
movzx ecx,DstXE
shr ecx,2
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; we have a input pixel now look up the dithered version.
;
; the dither table is a byte array like so.
;
; lpDitherTable[y % 8][pixel][x % 8]
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
align 4
DitherInnerLoop:
mov edx, dword ptr ds:[esi] ; get four input pixel(s)
DITH8
DITH8
DITH8
DITH8
mov dword ptr es:[edi],edx ; write four output pixel(s)
add esi,4
add edi,4
dec ecx
jnz short DitherInnerLoop
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
inc ah
and ah, 07h
add esi, SrcWidth
add edi, DstWidth
dec DstYE
jnz short DitherOuterLoop
xor ax,ax
mov fs,ax ; to make KRNL286.EXE and DOSX happy
pop ds
pop edi
pop esi
cEnd
;--------------------------------------------------------------------------;
;
; dither_init
;
; init local frame vars for DitherDIB
;
; ENTRY:
; ss:bp --> ditherdib frame
;
; EXIT:
; DS:ESI --> source DIB start x,y
; ES:EDI --> dest DIB start x,y
; FS:EBX --> dither table
;
;--------------------------------------------------------------------------;
dither_init proc near
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
;
; Set up the initial dest pointer
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
lds si,biDst
mov eax,[si].biWidth
add eax,3
and eax,not 3
mov DstWidth,eax
xor edi,edi
les di,lpDst
movzx ebx,DstX
movzx edx,DstY
mul edx
add eax,ebx
add edi,eax
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
;
; Set up the initial source pointer
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
lds si,biSrc
mov eax,[si].biWidth
add eax,3
and eax,not 3
mov SrcWidth,eax
xor esi,esi
lds si,lpSrc
movzx ebx,SrcX
movzx edx,SrcY
mul edx
add eax,ebx
add esi,eax
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
xor ebx,ebx
lfs bx,lpDitherTable
movzx eax,DstXE
sub SrcWidth, eax
movzx eax,DstXE
sub DstWidth, eax
ret
dither_init endp
sEnd CodeSeg
end