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.

1032 lines
27 KiB

  1. page ,132
  2. ;----------------------------Module-Header------------------------------;
  3. ; Module Name: DITH666.ASM
  4. ;
  5. ; code to dither 16,24,32 bit DIBs to a 8bit DIB with a fixed palette
  6. ;
  7. ; NOTES:
  8. ; this is a ASM version of the code found in dith666.c
  9. ;
  10. ;-----------------------------------------------------------------------;
  11. ?PLM=1
  12. ?WIN=0
  13. .xlist
  14. include cmacro32.inc
  15. include windows.inc
  16. .list
  17. ;-----------------------------------------------------------------------;
  18. ;
  19. ; Halftone tables...
  20. ;
  21. ; extern BYTE aHalftone8[3][4][4][256];
  22. ; extern BYTE aHalftone5[3][4][4][256];
  23. ; extern BYTE aHalftoneTranslate[256];
  24. ;
  25. ; for 24 bit or 32 bit (256 levels):
  26. ;
  27. ; pal8 = aHalftone8[0][x%4][y%4][r] +
  28. ; aHalftone8[1][x%4][y%4][g] +
  29. ; aHalftone8[2][x%4][y%4][b];
  30. ;
  31. ; pal8 = aHalftoneTranslate[pal8]
  32. ;
  33. ; for 16 bit (32 levels):
  34. ;
  35. ; pal8 = aHalftone5[0][x%4][y%4][rgb & 0xFF] +
  36. ; aHalftone5[1][x%4][y%4][rgb&0xFF |] +
  37. ; aHalftone5[2][x%4][y%4][rgb>>8];
  38. ;
  39. ; pal8 = aHalftoneTranslate[pal8]
  40. ;
  41. ; for fast 16 bit: (2x2 dither...)
  42. ; pal8 = aHalftone16[y%1][x%1][rgb16]
  43. ;
  44. ;-----------------------------------------------------------------------;
  45. sBegin Data
  46. sEnd Data
  47. externB _aHalftone8 ; in dith666.h
  48. externB _aTranslate666 ; in dith666.h
  49. aHalftone8R equ <_aHalftone8>
  50. aHalftone8G equ <_aHalftone8 + 4096>
  51. aHalftone8B equ <_aHalftone8 + 8192>
  52. aTranslate equ <_aTranslate666>
  53. ; The following structure should be used to access high and low
  54. ; words of a DWORD. This means that "word ptr foo[2]" -> "foo.hi".
  55. LONG struc
  56. lo dw ?
  57. hi dw ?
  58. LONG ends
  59. FARPOINTER struc
  60. off dw ?
  61. sel dw ?
  62. FARPOINTER ends
  63. ifndef SEGNAME
  64. SEGNAME equ <_TEXT>
  65. endif
  66. createSeg %SEGNAME, CodeSeg, word, public, CODE
  67. sBegin CodeSeg
  68. .386
  69. assumes cs,CodeSeg
  70. assumes ds,nothing
  71. assumes es,nothing
  72. ;--------------------------------------------------------------------------;
  73. ;
  74. ; DITH16 row
  75. ;
  76. ; dither 4 16 bit pels
  77. ;
  78. ; Entry:
  79. ; fs:esi - 16bit pel to dither
  80. ; es:edi - 8bit dest
  81. ; ds - dither tables
  82. ;
  83. ; Uses:
  84. ; eax, ebx, edx, ebp, esi, edi, flags
  85. ;
  86. ; Saves:
  87. ; ecx, edi, es,ds,fs,gs,ss
  88. ;
  89. ; access the dither tables like so:
  90. ;
  91. ; 0 1 0 1 0 = (0,0) (what dither matrix to look at)
  92. ; 2 3 2 3 1 = (0,1)
  93. ; 0 1 0 1 2 = (1,0)
  94. ; 2 3 2 3 3 = (1,1)
  95. ;
  96. ; the table is layed out like so
  97. ;
  98. ; yrrrrrgggggbbbbbx
  99. ;
  100. ;--------------------------------------------------------------------------;
  101. DITH16 macro row
  102. mov edx,fs:[esi+4] ; edx = ?rrrrrgggggbbbbb?rrrrrgggggbbbbb
  103. or dh,80h ; edx = ?rrrrrgggggbbbbb1rrrrrgggggbbbbb
  104. add edx,edx ; edx = rrrrrgggggbbbbb1rrrrrgggggbbbbb0
  105. mov bx,dx ; ebx = 0000000000000000rrrrrgggggbbbbb0
  106. shr edx,16 ; edx = 0000000000000000rrrrrgggggbbbbb1
  107. mov al,[ebx + ((row and 1) * 65536)]
  108. mov ah,[edx + ((row and 1) * 65536)]
  109. shl eax,16
  110. mov edx,fs:[esi] ; edx = ?rrrrrgggggbbbbb?rrrrrgggggbbbbb
  111. or dh,80h ; edx = ?rrrrrgggggbbbbb1rrrrrgggggbbbbb
  112. shl edx,1 ; edx = rrrrrgggggbbbbb1rrrrrgggggbbbbb0
  113. mov bx,dx ; ebx = 0000000000000000rrrrrgggggbbbbb0
  114. shr edx,16 ; edx = 0000000000000000rrrrrgggggbbbbb1
  115. mov al,[ebx + ((row and 1) * 65536)]
  116. mov ah,[edx + ((row and 1) * 65536)]
  117. mov es:[edi],eax
  118. add esi,8
  119. add edi,4
  120. endm
  121. ;--------------------------------------------------------------------------;
  122. ;
  123. ; Dither16()
  124. ;
  125. ; Entry:
  126. ; Stack based parameters as described below.
  127. ;
  128. ; Returns:
  129. ; none
  130. ;
  131. ; Registers Preserved:
  132. ; DS,ES,ESI,EDI,EBP
  133. ;
  134. ;--------------------------------------------------------------------------;
  135. assumes ds,nothing
  136. assumes es,nothing
  137. Dither16JumpTable label dword
  138. dd Dither16Scan0
  139. dd Dither16Scan3
  140. dd Dither16Scan2
  141. dd Dither16Scan1
  142. cProc Dither16,<FAR,PUBLIC,PASCAL>,<>
  143. parmD biDst ;--> BITMAPINFO of dest
  144. parmD lpDst ;--> to destination bits
  145. parmW DstX ;Destination origin - x coordinate
  146. parmW DstY ;Destination origin - y coordinate
  147. parmW DstXE ;x extent of the BLT
  148. parmW DstYE ;y extent of the BLT
  149. parmD biSrc ;--> BITMAPINFO of source
  150. parmD lpSrc ;--> to source bits
  151. parmW SrcX ;Source origin - x coordinate
  152. parmW SrcY ;Source origin - y coordinate
  153. parmD lpDitherTable ;not used (for 8->4 bit dither)
  154. localD SrcWidth ;width of source in bytes
  155. localD DstWidth ;width of dest in bytes
  156. localD SrcInc
  157. localD DstInc
  158. cBegin
  159. push esi
  160. push edi
  161. push ds
  162. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  163. ; We only handle (DstXE % 4) == 0 or 3. If it's == 1 or 2, then we
  164. ; round down, because otherwise we'd have to deal with half of a
  165. ; dither cell on the end.
  166. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  167. inc DstXE ; Make the == 3 mod 4 case work
  168. and DstXE, not 011b
  169. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  170. mov eax,16
  171. mov ebx,8
  172. call dither_init ; init all the frame variables
  173. jc Dither16Exit
  174. mov ds,word ptr lpDitherTable[2] ; DS --> dither table
  175. assumes ds,nothing
  176. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  177. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  178. movzx ecx, DstYE ; divide by 4
  179. mov ebx, ecx
  180. add ecx, 3 ; be sure to round up
  181. shr ecx, 2
  182. jz Dither16Exit
  183. mov DstYE, cx
  184. movzx ecx, DstXE ; divide by 4
  185. shr ecx,2
  186. jz Dither16Exit
  187. mov DstXE,cx
  188. movzx ecx, DstXE
  189. and ebx, 011b ; Get height mod 4
  190. xor edx,edx ; set up for dither macros
  191. jmp Dither16JumpTable[ebx*4]
  192. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  193. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  194. align 4
  195. Dither16OuterLoop:
  196. movzx ecx, DstXE
  197. align 4
  198. Dither16Scan0:
  199. DITH16 0
  200. dec ecx
  201. jnz Dither16Scan0
  202. add esi, SrcInc
  203. add edi, DstInc
  204. movzx ecx, DstXE
  205. align 4
  206. Dither16Scan1:
  207. DITH16 1
  208. dec ecx
  209. jnz Dither16Scan1
  210. add esi, SrcInc
  211. add edi, DstInc
  212. movzx ecx, DstXE
  213. align 4
  214. Dither16Scan2:
  215. DITH16 2
  216. dec ecx
  217. jnz Dither16Scan2
  218. add esi, SrcInc
  219. add edi, DstInc
  220. movzx ecx, DstXE
  221. align 4
  222. Dither16Scan3:
  223. DITH16 3
  224. dec ecx
  225. jnz Dither16Scan3
  226. add esi, SrcInc
  227. add edi, DstInc
  228. dec DstYE
  229. jnz Dither16OuterLoop
  230. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  231. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  232. Dither16Exit:
  233. xor ax,ax
  234. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  235. pop ds
  236. pop edi
  237. pop esi
  238. cEnd
  239. ;--------------------------------------------------------------------------;
  240. ;
  241. ; GET24 - get a byte, every four times doing a LODSD
  242. ;
  243. ;--------------------------------------------------------------------------;
  244. GET24_N = 0
  245. GET24 macro dst
  246. if (GET24_N mod 4) eq 0
  247. mov edx,dword ptr fs:[esi]
  248. mov dst,dl
  249. add esi,4
  250. elseif (GET24_N mod 4) eq 1
  251. mov dst,dh
  252. elseif (GET24_N mod 4) eq 2
  253. shr edx,16
  254. mov dst,dl
  255. elseif (GET24_N mod 4) eq 3
  256. mov dst,dh
  257. endif
  258. GET24_N = GET24_N + 1
  259. endm
  260. ;--------------------------------------------------------------------------;
  261. ;
  262. ; Dither24() - dither 24 to 8
  263. ;
  264. ; Entry:
  265. ; Stack based parameters as described below.
  266. ;
  267. ; Returns:
  268. ; none
  269. ;
  270. ; Registers Preserved:
  271. ; DS,ES,ESI,EDI,EBP
  272. ;
  273. ;--------------------------------------------------------------------------;
  274. assumes ds,nothing
  275. assumes es,nothing
  276. DITH24 macro row, col, dst
  277. GET24 bl ; get BLUE
  278. mov dst,ds:[aHalftone8B + ebx + row*256 + col*256*4]
  279. GET24 bl ; get GREEN
  280. add dst,ds:[aHalftone8G + ebx + row*256 + col*256*4]
  281. GET24 bl ; get RED
  282. add dst,ds:[aHalftone8R + ebx + row*256 + col*256*4]
  283. mov bl,dst
  284. mov dst,ds:[aTranslate + ebx]
  285. endm
  286. Dither24JumpTable label dword
  287. dd Dither24Scan0
  288. dd Dither24Scan3
  289. dd Dither24Scan2
  290. dd Dither24Scan1
  291. cProc Dither24,<FAR,PUBLIC,PASCAL>,<>
  292. parmD biDst ;--> BITMAPINFO of dest
  293. parmD lpDst ;--> to destination bits
  294. parmW DstX ;Destination origin - x coordinate
  295. parmW DstY ;Destination origin - y coordinate
  296. parmW DstXE ;x extent of the BLT
  297. parmW DstYE ;y extent of the BLT
  298. parmD biSrc ;--> BITMAPINFO of source
  299. parmD lpSrc ;--> to source bits
  300. parmW SrcX ;Source origin - x coordinate
  301. parmW SrcY ;Source origin - y coordinate
  302. parmD lpDitherTable ;196k dither table
  303. localD SrcWidth ;width of source in bytes
  304. localD DstWidth ;width of dest in bytes
  305. localD SrcInc
  306. localD DstInc
  307. cBegin
  308. push esi
  309. push edi
  310. push ds
  311. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  312. ; align everything on four pixel boundries, we realy should
  313. ; not do this but should handle the general case instead,
  314. ; but hey we are hackers.
  315. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  316. ; inc DstXE ; Make the == 3 mod 4 case work
  317. and DstXE, not 011b
  318. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  319. mov eax,24
  320. mov ebx,8
  321. call dither_init ; init all the frame variables
  322. jc Dither24Exit
  323. mov ax, seg aHalftone8R
  324. mov ds, ax
  325. assumes ds,nothing
  326. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  327. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  328. movzx ecx, DstYE ; divide by 4
  329. mov ebx, ecx
  330. add ecx, 3 ; be sure to round up
  331. shr ecx, 2
  332. jz Dither24Exit
  333. mov DstYE, cx
  334. movzx ecx, DstXE ; divide by 4
  335. shr ecx,2
  336. jz Dither24Exit
  337. mov DstXE,cx
  338. and ebx, 011b ; Get height mod 4
  339. jmp Dither24JumpTable[ebx*4]
  340. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  341. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  342. align 4
  343. Dither24OuterLoop:
  344. movzx ecx, DstXE
  345. align 4
  346. Dither24Scan0:
  347. DITH24 0,0,al
  348. DITH24 0,1,ah
  349. shl eax,16
  350. DITH24 0,2,al
  351. DITH24 0,3,ah
  352. rol eax,16
  353. mov es:[edi], eax
  354. add edi,4
  355. dec ecx
  356. jnz Dither24Scan0
  357. add esi, SrcInc
  358. add edi, DstInc
  359. movzx ecx, DstXE
  360. align 4
  361. Dither24Scan1:
  362. DITH24 1,0,al
  363. DITH24 1,1,ah
  364. shl eax,16
  365. DITH24 1,2,al
  366. DITH24 1,3,ah
  367. rol eax,16
  368. mov es:[edi], eax
  369. add edi,4
  370. dec ecx
  371. jnz Dither24Scan1
  372. add esi, SrcInc
  373. add edi, DstInc
  374. movzx ecx, DstXE
  375. align 4
  376. Dither24Scan2:
  377. DITH24 2,0,al
  378. DITH24 2,1,ah
  379. shl eax,16
  380. DITH24 2,2,al
  381. DITH24 2,3,ah
  382. rol eax,16
  383. mov es:[edi], eax
  384. add edi,4
  385. dec ecx
  386. jnz Dither24Scan2
  387. add esi, SrcInc
  388. add edi, DstInc
  389. movzx ecx, DstXE
  390. align 4
  391. Dither24Scan3:
  392. DITH24 3,0,al
  393. DITH24 3,1,ah
  394. shl eax,16
  395. DITH24 3,2,al
  396. DITH24 3,3,ah
  397. rol eax,16
  398. mov es:[edi], eax
  399. add edi,4
  400. dec ecx
  401. jnz Dither24Scan3
  402. add esi, SrcInc
  403. add edi, DstInc
  404. dec DstYE
  405. jnz Dither24OuterLoop
  406. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  407. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  408. Dither24Exit:
  409. xor ax,ax
  410. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  411. pop ds
  412. pop edi
  413. pop esi
  414. cEnd
  415. ;--------------------------------------------------------------------------;
  416. ;
  417. ; GET32 - get a byte from a 32 bit DIB
  418. ;
  419. ;--------------------------------------------------------------------------;
  420. GET32_N = 0
  421. GET32 macro dst
  422. if (GET32_N mod 3) eq 0
  423. mov edx,dword ptr fs:[esi]
  424. mov dst,dl
  425. add esi,4
  426. elseif (GET32_N mod 3) eq 1
  427. mov dst,dh
  428. elseif (GET32_N mod 3) eq 2
  429. shr edx,16
  430. mov dst,dl
  431. endif
  432. GET32_N = GET32_N + 1
  433. endm
  434. ;--------------------------------------------------------------------------;
  435. ;
  436. ; Dither32() - dither 32 to 8
  437. ;
  438. ; Entry:
  439. ; Stack based parameters as described below.
  440. ;
  441. ; Returns:
  442. ; none
  443. ;
  444. ; Registers Preserved:
  445. ; DS,ES,ESI,EDI,EBP
  446. ;
  447. ;--------------------------------------------------------------------------;
  448. assumes ds,nothing
  449. assumes es,nothing
  450. DITH32 macro row, col, dst
  451. GET32 bl ; get BLUE
  452. mov dst,ds:[aHalftone8B + ebx + row*256 + col*256*4]
  453. GET32 bl ; get GREEN
  454. add dst,ds:[aHalftone8G + ebx + row*256 + col*256*4]
  455. GET32 bl ; get RED
  456. add dst,ds:[aHalftone8R + ebx + row*256 + col*256*4]
  457. mov bl,dst
  458. mov dst,aTranslate[ebx]
  459. endm
  460. Dither32JumpTable label dword
  461. dd Dither32Scan0
  462. dd Dither32Scan3
  463. dd Dither32Scan2
  464. dd Dither32Scan1
  465. cProc Dither32,<FAR,PUBLIC,PASCAL>,<>
  466. parmD biDst ;--> BITMAPINFO of dest
  467. parmD lpDst ;--> to destination bits
  468. parmW DstX ;Destination origin - x coordinate
  469. parmW DstY ;Destination origin - y coordinate
  470. parmW DstXE ;x extent of the BLT
  471. parmW DstYE ;y extent of the BLT
  472. parmD biSrc ;--> BITMAPINFO of source
  473. parmD lpSrc ;--> to source bits
  474. parmW SrcX ;Source origin - x coordinate
  475. parmW SrcY ;Source origin - y coordinate
  476. parmD lpDitherTable ;196k dither table
  477. localD SrcWidth ;width of source in bytes
  478. localD DstWidth ;width of dest in bytes
  479. localD SrcInc
  480. localD DstInc
  481. cBegin
  482. push esi
  483. push edi
  484. push ds
  485. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  486. ; align everything on four pixel boundries, we realy should
  487. ; not do this but should handle the general case instead,
  488. ; but hey we are hackers.
  489. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  490. ; inc DstXE ; Make the == 3 mod 4 case work
  491. and DstXE, not 011b
  492. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  493. mov eax,32
  494. mov ebx,8
  495. call dither_init ; init all the frame variables
  496. jc Dither32Exit
  497. mov ax, seg aHalftone8R
  498. mov ds, ax
  499. assumes ds,nothing
  500. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  501. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  502. movzx ecx, DstYE ; divide by 4
  503. mov ebx, ecx
  504. add ecx, 3 ; be sure to round up
  505. shr ecx, 2
  506. jz Dither32Exit
  507. mov DstYE, cx
  508. movzx ecx, DstXE ; divide by 4
  509. shr ecx,2
  510. jz Dither32Exit
  511. mov DstXE,cx
  512. and ebx, 011b ; Get height mod 4
  513. jmp Dither32JumpTable[ebx*4]
  514. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  515. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  516. align 4
  517. Dither32OuterLoop:
  518. movzx ecx, DstXE
  519. align 4
  520. Dither32Scan0:
  521. DITH32 0,0,al
  522. DITH32 0,1,ah
  523. shl eax,16
  524. DITH32 0,2,al
  525. DITH32 0,3,ah
  526. rol eax,16
  527. mov es:[edi], eax
  528. add edi,4
  529. dec ecx
  530. jnz Dither32Scan0
  531. add esi, SrcInc
  532. add edi, DstInc
  533. movzx ecx, DstXE
  534. align 4
  535. Dither32Scan1:
  536. DITH32 1,0,al
  537. DITH32 1,1,ah
  538. shl eax,16
  539. DITH32 1,2,al
  540. DITH32 1,3,ah
  541. rol eax,16
  542. mov es:[edi], eax
  543. add edi,4
  544. dec ecx
  545. jnz Dither32Scan1
  546. add esi, SrcInc
  547. add edi, DstInc
  548. movzx ecx, DstXE
  549. align 4
  550. Dither32Scan2:
  551. DITH32 2,0,al
  552. DITH32 2,1,ah
  553. shl eax,16
  554. DITH32 2,2,al
  555. DITH32 2,3,ah
  556. rol eax,16
  557. mov es:[edi], eax
  558. add edi,4
  559. dec ecx
  560. jnz Dither32Scan2
  561. add esi, SrcInc
  562. add edi, DstInc
  563. movzx ecx, DstXE
  564. align 4
  565. Dither32Scan3:
  566. DITH32 3,0,al
  567. DITH32 3,1,ah
  568. shl eax,16
  569. DITH32 3,2,al
  570. DITH32 3,3,ah
  571. rol eax,16
  572. mov es:[edi], eax
  573. add edi,4
  574. dec ecx
  575. jnz Dither32Scan3
  576. add esi, SrcInc
  577. add edi, DstInc
  578. dec DstYE
  579. jnz Dither32OuterLoop
  580. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  581. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  582. Dither32Exit:
  583. xor ax,ax
  584. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  585. pop ds
  586. pop edi
  587. pop esi
  588. cEnd
  589. ;--------------------------------------------------------------------------;
  590. ;
  591. ; dither_init
  592. ;
  593. ; init local frame vars for DitherDIB
  594. ;
  595. ; ENTRY:
  596. ; AX - source bpp
  597. ; BX - dest bpp
  598. ; ss:ebp --> ditherdib frame
  599. ;
  600. ; EXIT:
  601. ; FS:ESI --> source DIB start x,y
  602. ; ES:EDI --> dest DIB start x,y
  603. ; DS: --> dither tables (in DGROUP)
  604. ;
  605. ;--------------------------------------------------------------------------;
  606. dither_init_error:
  607. stc
  608. ret
  609. dither_init proc near
  610. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  611. ; validate the DIBs
  612. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  613. movzx eax,ax
  614. movzx ebx,bx
  615. movzx ecx,cx
  616. movzx edx,dx
  617. movzx edi,di
  618. movzx esi,si
  619. lfs si, biSrc
  620. les di, biDst
  621. mov cx, es:[di].biBitCount ; dest must be right
  622. cmp cx, bx
  623. jne short dither_init_error
  624. mov cx, fs:[si].biBitCount ; source must be right
  625. cmp cx, ax
  626. jne short dither_init_error
  627. dither_init_bit_depth_ok:
  628. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  629. ;
  630. ; Set up the initial source pointer
  631. ;
  632. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  633. mov eax,fs:[si].biWidth
  634. mul ecx
  635. add eax,31
  636. and eax,not 31
  637. shr eax,3
  638. mov SrcWidth,eax
  639. mov SrcInc,eax
  640. lfs si,lpSrc
  641. movzx edx,SrcY
  642. mul edx
  643. add esi,eax
  644. movzx eax,SrcX
  645. mul ecx
  646. shr eax,3
  647. add esi,eax
  648. movzx eax, DstXE ; SrcInc = SrcWidth - DstXE*bits/8
  649. mul ecx
  650. shr eax, 3
  651. sub SrcInc, eax
  652. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  653. ;
  654. ; Set up the initial dest pointer
  655. ;
  656. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  657. mov cx, es:[di].biBitCount
  658. mov eax,es:[di].biWidth
  659. mul ecx
  660. add eax,31
  661. and eax,not 31
  662. shr eax,3
  663. mov DstWidth,eax
  664. mov DstInc,eax
  665. cmp es:[edi].biHeight,0 ; init a upside down DIB
  666. jge short @f
  667. movsx ebx,DstY
  668. add ebx,es:[edi].biHeight
  669. not ebx
  670. mov DstY,bx
  671. neg DstWidth
  672. neg DstInc
  673. @@:
  674. les di,lpDst
  675. movsx edx,DstY
  676. mul edx
  677. add edi,eax
  678. movsx eax,DstX
  679. mul ecx
  680. shr eax,3
  681. add edi,eax
  682. movzx eax, DstXE ; DstInc = DstWidth - DstXE*bits/8
  683. mul ecx
  684. shr eax, 3
  685. sub DstInc, eax
  686. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  687. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  688. dither_init_exit:
  689. clc
  690. ret
  691. dither_init endp
  692. sEnd CodeSeg
  693. end
  694. ;--------------------------------------------------------------------------;
  695. ;
  696. ; GET16 - read a RGB555 from the input
  697. ;
  698. ; INPUT:
  699. ; fs:[esi] rgb555 DIB
  700. ;
  701. ; OUTPUT:
  702. ; edx rgb555
  703. ; esi+=2
  704. ;--------------------------------------------------------------------------;
  705. GET16 macro col
  706. if col and 1
  707. shr edx,6 ; get pel from last time
  708. else
  709. mov edx, dword ptr fs:[esi] ; grab two pels
  710. add esi,4
  711. endif
  712. endm
  713. ;--------------------------------------------------------------------------;
  714. ;
  715. ; DITH16 row, col
  716. ;
  717. ; grab a 16 bit pel and dither it.
  718. ;
  719. ; Entry:
  720. ; fs:esi - 16bit pel to dither
  721. ; ds - data segment
  722. ;
  723. ; Returns:
  724. ; al - dithered pel (rotated into eax)
  725. ;
  726. ; Uses:
  727. ; eax, ebx, edx, ebp, esi, edi, flags
  728. ;
  729. ; Saves:
  730. ; ecx, edi, es,ds,fs,gs,ss
  731. ;
  732. ;--------------------------------------------------------------------------;
  733. DITH16 macro row, col, dst
  734. GET16 col
  735. mov bl,dl
  736. mov dst,aHalftone5B[ebx + row*256 + col*256*4]
  737. mov bl,dh
  738. add dst,aHalftone5R[ebx + row*256 + col*256*4]
  739. and bl,11b
  740. or bl,dl
  741. add dst,aHalftone5G[ebx + row*256 + col*256*4]
  742. endm
  743. ;--------------------------------------------------------------------------;
  744. ;
  745. ; Dither16()
  746. ;
  747. ; Entry:
  748. ; Stack based parameters as described below.
  749. ;
  750. ; Returns:
  751. ; none
  752. ;
  753. ; Registers Preserved:
  754. ; DS,ES,ESI,EDI,EBP
  755. ;
  756. ;--------------------------------------------------------------------------;
  757. assumes ds,Data
  758. assumes es,nothing
  759. Dither16JumpTable label dword
  760. dd Dither16Scan0
  761. dd Dither16Scan3
  762. dd Dither16Scan2
  763. dd Dither16Scan1
  764. cProc Dither16,<FAR,PUBLIC,PASCAL>,<>
  765. parmD biDst ;--> BITMAPINFO of dest
  766. parmD lpDst ;--> to destination bits
  767. parmW DstX ;Destination origin - x coordinate
  768. parmW DstY ;Destination origin - y coordinate
  769. parmW DstXE ;x extent of the BLT
  770. parmW DstYE ;y extent of the BLT
  771. parmD biSrc ;--> BITMAPINFO of source
  772. parmD lpSrc ;--> to source bits
  773. parmW SrcX ;Source origin - x coordinate
  774. parmW SrcY ;Source origin - y coordinate
  775. parmD lpDitherTable ;not used (for 8->4 bit dither)
  776. localD SrcWidth ;width of source in bytes
  777. localD DstWidth ;width of dest in bytes
  778. localD SrcInc
  779. localD DstInc
  780. cBegin
  781. push esi
  782. push edi
  783. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  784. ; We only handle (DstXE % 4) == 0 or 3. If it's == 1 or 2, then we
  785. ; round down, because otherwise we'd have to deal with half of a
  786. ; dither cell on the end.
  787. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  788. inc DstXE ; Make the == 3 mod 4 case work
  789. and DstXE, not 011b
  790. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  791. mov eax,16
  792. mov ebx,8
  793. call dither_init ; init all the frame variables
  794. jc Dither16Exit
  795. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  796. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  797. movzx ecx, DstYE ; divide by 4
  798. mov ebx, ecx
  799. add ecx, 3 ; be sure to round up
  800. shr ecx, 2
  801. jz Dither16Exit
  802. mov DstYE, cx
  803. movzx ecx, DstXE ; divide by 4
  804. shr ecx,2
  805. jz Dither16Exit
  806. mov DstXE,cx
  807. and ebx, 011b ; Get height mod 4
  808. jmp Dither16JumpTable[ebx*4]
  809. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  810. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  811. align 4
  812. Dither16OuterLoop:
  813. movzx ecx, DstXE
  814. align 4
  815. Dither16Scan0:
  816. DITH16 0,0,al
  817. DITH16 0,1,ah
  818. shl eax,16
  819. DITH16 0,2,al
  820. DITH16 0,3,ah
  821. rol eax,16
  822. mov dword ptr es:[edi], eax
  823. add edi,4
  824. dec ecx
  825. jnz Dither16Scan0
  826. add esi, SrcInc
  827. add edi, DstInc
  828. movzx ecx, DstXE
  829. align 4
  830. Dither16Scan1:
  831. DITH16 1,0,al
  832. DITH16 1,1,ah
  833. shl eax,16
  834. DITH16 1,2,al
  835. DITH16 1,3,ah
  836. rol eax,16
  837. mov dword ptr es:[edi], eax
  838. add edi,4
  839. dec ecx
  840. jnz Dither16Scan1
  841. add esi, SrcInc
  842. add edi, DstInc
  843. movzx ecx, DstXE
  844. align 4
  845. Dither16Scan2:
  846. DITH16 2,0,al
  847. DITH16 2,1,ah
  848. shl eax,16
  849. DITH16 2,2,al
  850. DITH16 2,3,ah
  851. rol eax,16
  852. mov dword ptr es:[edi], eax
  853. add edi,4
  854. dec ecx
  855. jnz Dither16Scan2
  856. add esi, SrcInc
  857. add edi, DstInc
  858. movzx ecx, DstXE
  859. align 4
  860. Dither16Scan3:
  861. DITH16 3,0,al
  862. DITH16 3,1,ah
  863. shl eax,16
  864. DITH16 3,2,al
  865. DITH16 3,3,ah
  866. rol eax,16
  867. mov dword ptr es:[edi], eax
  868. add edi,4
  869. dec ecx
  870. jnz Dither16Scan3
  871. add esi, SrcInc
  872. add edi, DstInc
  873. dec DstYE
  874. jnz Dither16OuterLoop
  875. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  876. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  877. Dither16Exit:
  878. xor ax,ax
  879. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  880. pop edi
  881. pop esi
  882. cEnd