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

475 lines
11 KiB
NASM

PAGE ,132
TITLE BltProp.asm
NAME BltProp
?WIN = 0
?PLM = 1
.286
.xlist
include cmacros.inc
include windows.inc
.list
; 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
MAXWIDTH = 1500
externA __AHINCR
sBegin DATA
;;externW sColorsOut
;;externW GrayThresh
;;externW LoThresh
;;externW HiThresh
;;externW Prop
;;externW Mult
GrayThresh dw 128 ; 135
LoThresh dw 128 ; 120
HiThresh dw 192 ; 200
Prop dw 8 ; 6
Mult dw 32, 32, 32 ; 28, 28, 28
usPalMult DW 3 * 256 DUP (?)
sCol DW 0
v DW 3 DUP (?)
val DW 3 DUP (?)
errx DW 3 DUP (?)
errz DW 3 DUP (?)
erry DW 3 * MAXWIDTH DUP (?)
; the output Color Table
;
; The pixel values that index this table are generated by PropImage
; as follows:
;
; bits 7x543210
; | ||||||
; | |||||+-- set iff RED > HiThresh
; | ||||+--- set iff RED > LoThresh
; | |||+---- set iff GREEN > HiThresh
; | ||+----- set iff GREEN > LoThresh
; | |+------ set iff BLUE > HiThresh
; | +------- set iff BLUE > LoThresh
; +--------- set iff all colors > GrayThresh
;
; The color values map to the appropriate 16 colors of the standard
; palette.
;
; 0 - LoThresh 0
; LoThresh - HiThresh 128
; HiThresh - 255 255
;
; As usual the magic grays are special cased
;
dwrgb macro n
red = 0
green = 0
blue = 0
if n and 010101b
rgbval = 0FFh
else
rgbval = 080h
endif
if n and 000011b
red = rgbval
endif
if n and 001100b
green = rgbval
endif
if n and 110000b
blue = rgbval
endif
if n eq 0AAh
red = 0C0h
green = 0C0h
blue = 0C0h
endif
if n eq 080h
red = 080h
green = 080h
blue = 080h
endif
dw red,green,blue
endm
sColorsOut label word
n = 0
rept 256
dwrgb n
n = n + 1
endm
sEnd DATA
sBegin CODE
assumes ds,DATA
assumes ss,DATA
assumes cs,CODE
;-------------------------------------------------------------------------;
;
; BltProp
;
; Does error proagation on a input 8 bpp DIB producing a 8 bpp DIB
; that only uses 16 colors.
;
; assumes SS == DS !!
;
; Entry:
;
; Returns:
; AX = 1
; Error Returns:
; AX = 0 if error
; Registers Preserved:
; SI,DI,DS,BP
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; Calls:
;
;-------------------------------------------------------------------------;
cProc BltProp, <FAR, PUBLIC, PASCAL>, <ds,si,di>
parmD pbiSrc ; BITMAP info for source DIB
parmD pbSrc ; Source bits pointer
parmW SrcX ; Source X offset
parmW SrcY ; Source Y offset
parmW SrcXE ; Source X extent
parmW SrcYE ; Source Y extent
parmD pbiDst ; BITMAP info for destination DIB
parmD pbDst ; Destination bits pointer
parmW DstX ; Destination X offset
parmW DstY ; Destination Y offset
localW cbScanSrc ; width of a source scanline
localW cbScanDst
localW cbIncS ; next scan
localW cbIncD
cBegin
mov ax,ds
mov es,ax
lea di,erry ; clear out erry[]
xor ax,ax
mov cx,3 * MAXWIDTH
rep stosb
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;
; pre-multiply the input palette by the intensity multipliers
;
; for (row = 0; row < cColorsIn; ++row)
; for (clr = 0; clr < 3; ++clr)
; usPalMult[row][2-clr] = rcbmIn.argbColor[row][clr] * Mult[2-clr] / 32;
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
les di,pbiSrc ; es:[di] --> source BITMAPINFO
mov ax,word ptr es:[di].biWidth ; DWORD align bitmap width
add ax,3
and ax,not 3
mov cbScanSrc,ax
add di,word ptr es:[di].biSize ; es:[di] --> color table
lea si,usPalMult ; ds:[si] --> usPalMult
mov cx,256
PalMulLoop:
xor bx,bx
irp rgbX, <rgbRed,rgbGreen,rgbBlue>
xor ah,ah
mov al,es:[di].&rgbX
mul Mult[bx]
shr ax,5
mov ds:[si+bx],ax
add bx,2
endm
add si,6
add di,4
loop PalMulLoop
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;
; fill in the destination color table
;
; for (inx = 0; inx < 256; ++inx)
; for (clr = 0; clr < 3; ++clr)
; rcbmOut.argbColor[inx][clr] = (BYTE)sColorsOut[inx][2-clr];
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
les di,pbiDst ; es:[di] --> destination BITMAPINFO
mov ax,word ptr es:[di].biWidth ; DWORD align bitmap width
add ax,3
and ax,not 3
mov cbScanDst,ax
add di,word ptr es:[di].biSize ; es:[di] --> color table
lea si,sColorsOut ; ds:[si] --> sColorsOut
mov cx,256
sColorsOutLoop:
lodsw
mov es:[di].rgbRed ,al
lodsw
mov es:[di].rgbGreen,al
lodsw
mov es:[di].rgbBlue ,al
add di,4
loop sColorsOutLoop
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;
; caclulate amount to add to source/dest pointer to get the the next scanline
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
mov bx,SrcXE
mov ax,cbScanSrc
sub ax,bx ; cbIncS = source ptr inc ea. row
mov cbIncS,ax
mov ax,cbScanDst
sub ax,bx ; cbIncD = dest ptr inc ea. row
mov cbIncD,ax
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;
; caclulate the source/dest bitmap pointers
;
; ds:si --> source bitmap bits (pbSrc + cbScanSrc * SrcY + SrcX)
; es:di --> dest bitmap bits (pbDst + cbScanDst * DstY + DstX)
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
mov ax, DstY ; ax = start scan
mul cbScanDst ; ax *= size of a scanline
add ax, DstX ; ax += X offset
adc dx, 0 ; dx = segment number
mov di, ax ; set di = offset into segment
add di, pbDst.off
mov ax,dx ; set es = segment
mov bx,__AHINCR
mul bx
add ax, pbDst.sel
mov es,ax
;
mov ax, SrcY ; ax = start scan
mul cbScanSrc ; ax *= size of a scanline
add ax, SrcX ; ax += X offset
adc dx, 0 ; dx = segment number
mov si, ax ; set si = offset into segment
add si, pbSrc.off
mov ax,dx ; set ds = segment
mov bx,__AHINCR
mul bx
add ax, pbSrc.sel
mov ds,ax
assume ds:nothing
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;
; start a new row
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
RowLoop:
xor ax,ax ; clear X error for start of line
mov errx,ax
mov errx+2,ax
mov errx+4,ax
mov errz,ax ; clear Z error for start of line
mov errz+2,ax
mov errz+4,ax
mov ax,SrcXE ; sCol = number of cols to do
mov sCol,ax
xor bx,bx ; (bx) = initial column number
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;
; start of the column loop
;
; MOTE: bp is used in this loop!!! stack locals are not accessable.
;
; es:di --> dest bits
; ds:si --> source bits
; bx = Current column # * 6
; bp = is *NOT* stack frame
; ss = DGROUP
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
push bp
ColLoop:
lodsb ; get a source BYTE
xor ah,ah ; (ax) = dib color
add ax,ax ; (ax) = 2 * dib color
mov bp,ax ; (bp) = 2 * dib color
add ax,ax ; (ax) = 4 * dib color
add bp,ax ; (bp) = 6 * dib color (usPalMult index)
mov cx,80H ; CL = lointens (MSB flag)
xor ax,ax ; AL = output value
irpc color,<420>
mov dx,errz[color] ; move previous Z error to next Y
xchg dx,erry[bx+color] ; and get this Y error
add dx,usPalMult[bp+color] ; desired intensity of this color
add dx,errx[color] ; plus X error
mov v[color],dx ; save for ClrLoop2
cmp LoThresh,dx ; above low threshold?
lahf ; set bit for this color accordingly
rol ax,1
cmp HiThresh,dx ; above high threshold?
lahf ; set bit for this color accordingly
rol ax,1
cmp GrayThresh,dx ; above gray threshold?
lahf ; AND together gray requirements
and cl,ah
endm
or al,cl ; compose value
; (al) = Output color value
; (bx) = Column number * 6
; (ss) = DGROUP
stosb ; write a dest byte
xor ah,ah
add ax,ax
mov bp,ax
add ax,ax
add bp,ax ; BP = input value * 6 (usPalMult index)
cmp Prop,0
;;jz NoProp
irpc color,<420>
mov ax,v[color] ; compute error for this color
sub ax,sColorsOut[bp+color]
imul Prop
xor ax,dx ; ABS error
sub ax,dx ;;
shr ax,5 ; / 32
mov cx,ax
shr cx,1 ; / 64 for Z
xor ax,dx ; unABS error
sub ax,dx ;;
xor cx,dx ; unABS error
sub cx,dx ;;
add erry[bx+color],ax ; add Y error to previous Z
mov errx[color],ax ; set X error
mov errz[color],cx ; set Z error
endm
; We get weird, below, trying to allow the common jump cases to fall
; through. Since ColLoop is so large, we will use the dead space
; after the unconditional jump to hide out-of-line code
NoProp:
or si,si
jz fixSSeg
fixDOff:
or di,di
jz fixDSeg
EndColLoop:
add bx,6
dec sCol
jz ColLoopDone
jmp ColLoop
fixSSeg:
mov ax,ds
add ax,__AHINCR
mov ds,ax
jmp fixDOff
fixDSeg:
mov ax,es
add ax,__AHINCR
mov es,ax
jmp EndColLoop
ColLoopDone:
; End Weirdness.
pop bp ; it is safe to use locals now
add si,cbIncS
jnc @f
mov ax,ds
add ax,__AHINCR
mov ds,ax
@@:
add di,cbIncD
jnc @f
mov ax,es
add ax,__AHINCR
mov es,ax
@@:
dec SrcYE
jz @F
jmp RowLoop
@@:
cEnd
sEnd CODE
END