475 lines
11 KiB
NASM
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
|