Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

474 lines
11 KiB

  1. PAGE ,132
  2. TITLE BltProp.asm
  3. NAME BltProp
  4. ?WIN = 0
  5. ?PLM = 1
  6. .286
  7. .xlist
  8. include cmacros.inc
  9. include windows.inc
  10. .list
  11. ; The following structure should be used to access high and low
  12. ; words of a DWORD. This means that "word ptr foo[2]" -> "foo.hi".
  13. LONG struc
  14. lo dw ?
  15. hi dw ?
  16. LONG ends
  17. FARPOINTER struc
  18. off dw ?
  19. sel dw ?
  20. FARPOINTER ends
  21. MAXWIDTH = 1500
  22. externA __AHINCR
  23. sBegin DATA
  24. ;;externW sColorsOut
  25. ;;externW GrayThresh
  26. ;;externW LoThresh
  27. ;;externW HiThresh
  28. ;;externW Prop
  29. ;;externW Mult
  30. GrayThresh dw 128 ; 135
  31. LoThresh dw 128 ; 120
  32. HiThresh dw 192 ; 200
  33. Prop dw 8 ; 6
  34. Mult dw 32, 32, 32 ; 28, 28, 28
  35. usPalMult DW 3 * 256 DUP (?)
  36. sCol DW 0
  37. v DW 3 DUP (?)
  38. val DW 3 DUP (?)
  39. errx DW 3 DUP (?)
  40. errz DW 3 DUP (?)
  41. erry DW 3 * MAXWIDTH DUP (?)
  42. ; the output Color Table
  43. ;
  44. ; The pixel values that index this table are generated by PropImage
  45. ; as follows:
  46. ;
  47. ; bits 7x543210
  48. ; | ||||||
  49. ; | |||||+-- set iff RED > HiThresh
  50. ; | ||||+--- set iff RED > LoThresh
  51. ; | |||+---- set iff GREEN > HiThresh
  52. ; | ||+----- set iff GREEN > LoThresh
  53. ; | |+------ set iff BLUE > HiThresh
  54. ; | +------- set iff BLUE > LoThresh
  55. ; +--------- set iff all colors > GrayThresh
  56. ;
  57. ; The color values map to the appropriate 16 colors of the standard
  58. ; palette.
  59. ;
  60. ; 0 - LoThresh 0
  61. ; LoThresh - HiThresh 128
  62. ; HiThresh - 255 255
  63. ;
  64. ; As usual the magic grays are special cased
  65. ;
  66. dwrgb macro n
  67. red = 0
  68. green = 0
  69. blue = 0
  70. if n and 010101b
  71. rgbval = 0FFh
  72. else
  73. rgbval = 080h
  74. endif
  75. if n and 000011b
  76. red = rgbval
  77. endif
  78. if n and 001100b
  79. green = rgbval
  80. endif
  81. if n and 110000b
  82. blue = rgbval
  83. endif
  84. if n eq 0AAh
  85. red = 0C0h
  86. green = 0C0h
  87. blue = 0C0h
  88. endif
  89. if n eq 080h
  90. red = 080h
  91. green = 080h
  92. blue = 080h
  93. endif
  94. dw red,green,blue
  95. endm
  96. sColorsOut label word
  97. n = 0
  98. rept 256
  99. dwrgb n
  100. n = n + 1
  101. endm
  102. sEnd DATA
  103. sBegin CODE
  104. assumes ds,DATA
  105. assumes ss,DATA
  106. assumes cs,CODE
  107. ;-------------------------------------------------------------------------;
  108. ;
  109. ; BltProp
  110. ;
  111. ; Does error proagation on a input 8 bpp DIB producing a 8 bpp DIB
  112. ; that only uses 16 colors.
  113. ;
  114. ; assumes SS == DS !!
  115. ;
  116. ; Entry:
  117. ;
  118. ; Returns:
  119. ; AX = 1
  120. ; Error Returns:
  121. ; AX = 0 if error
  122. ; Registers Preserved:
  123. ; SI,DI,DS,BP
  124. ; Registers Destroyed:
  125. ; AX,BX,CX,DX,FLAGS
  126. ; Calls:
  127. ;
  128. ;-------------------------------------------------------------------------;
  129. cProc BltProp, <FAR, PUBLIC, PASCAL>, <ds,si,di>
  130. parmD pbiSrc ; BITMAP info for source DIB
  131. parmD pbSrc ; Source bits pointer
  132. parmW SrcX ; Source X offset
  133. parmW SrcY ; Source Y offset
  134. parmW SrcXE ; Source X extent
  135. parmW SrcYE ; Source Y extent
  136. parmD pbiDst ; BITMAP info for destination DIB
  137. parmD pbDst ; Destination bits pointer
  138. parmW DstX ; Destination X offset
  139. parmW DstY ; Destination Y offset
  140. localW cbScanSrc ; width of a source scanline
  141. localW cbScanDst
  142. localW cbIncS ; next scan
  143. localW cbIncD
  144. cBegin
  145. mov ax,ds
  146. mov es,ax
  147. lea di,erry ; clear out erry[]
  148. xor ax,ax
  149. mov cx,3 * MAXWIDTH
  150. rep stosb
  151. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  152. ;
  153. ; pre-multiply the input palette by the intensity multipliers
  154. ;
  155. ; for (row = 0; row < cColorsIn; ++row)
  156. ; for (clr = 0; clr < 3; ++clr)
  157. ; usPalMult[row][2-clr] = rcbmIn.argbColor[row][clr] * Mult[2-clr] / 32;
  158. ;
  159. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  160. les di,pbiSrc ; es:[di] --> source BITMAPINFO
  161. mov ax,word ptr es:[di].biWidth ; DWORD align bitmap width
  162. add ax,3
  163. and ax,not 3
  164. mov cbScanSrc,ax
  165. add di,word ptr es:[di].biSize ; es:[di] --> color table
  166. lea si,usPalMult ; ds:[si] --> usPalMult
  167. mov cx,256
  168. PalMulLoop:
  169. xor bx,bx
  170. irp rgbX, <rgbRed,rgbGreen,rgbBlue>
  171. xor ah,ah
  172. mov al,es:[di].&rgbX
  173. mul Mult[bx]
  174. shr ax,5
  175. mov ds:[si+bx],ax
  176. add bx,2
  177. endm
  178. add si,6
  179. add di,4
  180. loop PalMulLoop
  181. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  182. ;
  183. ; fill in the destination color table
  184. ;
  185. ; for (inx = 0; inx < 256; ++inx)
  186. ; for (clr = 0; clr < 3; ++clr)
  187. ; rcbmOut.argbColor[inx][clr] = (BYTE)sColorsOut[inx][2-clr];
  188. ;
  189. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  190. les di,pbiDst ; es:[di] --> destination BITMAPINFO
  191. mov ax,word ptr es:[di].biWidth ; DWORD align bitmap width
  192. add ax,3
  193. and ax,not 3
  194. mov cbScanDst,ax
  195. add di,word ptr es:[di].biSize ; es:[di] --> color table
  196. lea si,sColorsOut ; ds:[si] --> sColorsOut
  197. mov cx,256
  198. sColorsOutLoop:
  199. lodsw
  200. mov es:[di].rgbRed ,al
  201. lodsw
  202. mov es:[di].rgbGreen,al
  203. lodsw
  204. mov es:[di].rgbBlue ,al
  205. add di,4
  206. loop sColorsOutLoop
  207. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  208. ;
  209. ; caclulate amount to add to source/dest pointer to get the the next scanline
  210. ;
  211. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  212. mov bx,SrcXE
  213. mov ax,cbScanSrc
  214. sub ax,bx ; cbIncS = source ptr inc ea. row
  215. mov cbIncS,ax
  216. mov ax,cbScanDst
  217. sub ax,bx ; cbIncD = dest ptr inc ea. row
  218. mov cbIncD,ax
  219. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  220. ;
  221. ; caclulate the source/dest bitmap pointers
  222. ;
  223. ; ds:si --> source bitmap bits (pbSrc + cbScanSrc * SrcY + SrcX)
  224. ; es:di --> dest bitmap bits (pbDst + cbScanDst * DstY + DstX)
  225. ;
  226. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  227. mov ax, DstY ; ax = start scan
  228. mul cbScanDst ; ax *= size of a scanline
  229. add ax, DstX ; ax += X offset
  230. adc dx, 0 ; dx = segment number
  231. mov di, ax ; set di = offset into segment
  232. add di, pbDst.off
  233. mov ax,dx ; set es = segment
  234. mov bx,__AHINCR
  235. mul bx
  236. add ax, pbDst.sel
  237. mov es,ax
  238. ;
  239. mov ax, SrcY ; ax = start scan
  240. mul cbScanSrc ; ax *= size of a scanline
  241. add ax, SrcX ; ax += X offset
  242. adc dx, 0 ; dx = segment number
  243. mov si, ax ; set si = offset into segment
  244. add si, pbSrc.off
  245. mov ax,dx ; set ds = segment
  246. mov bx,__AHINCR
  247. mul bx
  248. add ax, pbSrc.sel
  249. mov ds,ax
  250. assume ds:nothing
  251. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  252. ;
  253. ; start a new row
  254. ;
  255. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  256. RowLoop:
  257. xor ax,ax ; clear X error for start of line
  258. mov errx,ax
  259. mov errx+2,ax
  260. mov errx+4,ax
  261. mov errz,ax ; clear Z error for start of line
  262. mov errz+2,ax
  263. mov errz+4,ax
  264. mov ax,SrcXE ; sCol = number of cols to do
  265. mov sCol,ax
  266. xor bx,bx ; (bx) = initial column number
  267. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  268. ;
  269. ; start of the column loop
  270. ;
  271. ; MOTE: bp is used in this loop!!! stack locals are not accessable.
  272. ;
  273. ; es:di --> dest bits
  274. ; ds:si --> source bits
  275. ; bx = Current column # * 6
  276. ; bp = is *NOT* stack frame
  277. ; ss = DGROUP
  278. ;
  279. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  280. push bp
  281. ColLoop:
  282. lodsb ; get a source BYTE
  283. xor ah,ah ; (ax) = dib color
  284. add ax,ax ; (ax) = 2 * dib color
  285. mov bp,ax ; (bp) = 2 * dib color
  286. add ax,ax ; (ax) = 4 * dib color
  287. add bp,ax ; (bp) = 6 * dib color (usPalMult index)
  288. mov cx,80H ; CL = lointens (MSB flag)
  289. xor ax,ax ; AL = output value
  290. irpc color,<420>
  291. mov dx,errz[color] ; move previous Z error to next Y
  292. xchg dx,erry[bx+color] ; and get this Y error
  293. add dx,usPalMult[bp+color] ; desired intensity of this color
  294. add dx,errx[color] ; plus X error
  295. mov v[color],dx ; save for ClrLoop2
  296. cmp LoThresh,dx ; above low threshold?
  297. lahf ; set bit for this color accordingly
  298. rol ax,1
  299. cmp HiThresh,dx ; above high threshold?
  300. lahf ; set bit for this color accordingly
  301. rol ax,1
  302. cmp GrayThresh,dx ; above gray threshold?
  303. lahf ; AND together gray requirements
  304. and cl,ah
  305. endm
  306. or al,cl ; compose value
  307. ; (al) = Output color value
  308. ; (bx) = Column number * 6
  309. ; (ss) = DGROUP
  310. stosb ; write a dest byte
  311. xor ah,ah
  312. add ax,ax
  313. mov bp,ax
  314. add ax,ax
  315. add bp,ax ; BP = input value * 6 (usPalMult index)
  316. cmp Prop,0
  317. ;;jz NoProp
  318. irpc color,<420>
  319. mov ax,v[color] ; compute error for this color
  320. sub ax,sColorsOut[bp+color]
  321. imul Prop
  322. xor ax,dx ; ABS error
  323. sub ax,dx ;;
  324. shr ax,5 ; / 32
  325. mov cx,ax
  326. shr cx,1 ; / 64 for Z
  327. xor ax,dx ; unABS error
  328. sub ax,dx ;;
  329. xor cx,dx ; unABS error
  330. sub cx,dx ;;
  331. add erry[bx+color],ax ; add Y error to previous Z
  332. mov errx[color],ax ; set X error
  333. mov errz[color],cx ; set Z error
  334. endm
  335. ; We get weird, below, trying to allow the common jump cases to fall
  336. ; through. Since ColLoop is so large, we will use the dead space
  337. ; after the unconditional jump to hide out-of-line code
  338. NoProp:
  339. or si,si
  340. jz fixSSeg
  341. fixDOff:
  342. or di,di
  343. jz fixDSeg
  344. EndColLoop:
  345. add bx,6
  346. dec sCol
  347. jz ColLoopDone
  348. jmp ColLoop
  349. fixSSeg:
  350. mov ax,ds
  351. add ax,__AHINCR
  352. mov ds,ax
  353. jmp fixDOff
  354. fixDSeg:
  355. mov ax,es
  356. add ax,__AHINCR
  357. mov es,ax
  358. jmp EndColLoop
  359. ColLoopDone:
  360. ; End Weirdness.
  361. pop bp ; it is safe to use locals now
  362. add si,cbIncS
  363. jnc @f
  364. mov ax,ds
  365. add ax,__AHINCR
  366. mov ds,ax
  367. @@:
  368. add di,cbIncD
  369. jnc @f
  370. mov ax,es
  371. add ax,__AHINCR
  372. mov es,ax
  373. @@:
  374. dec SrcYE
  375. jz @F
  376. jmp RowLoop
  377. @@:
  378. cEnd
  379. sEnd CODE
  380. END