|
|
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
|