Leaked source code of windows server 2003
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.

1200 lines
36 KiB

  1. page ,132
  2. ;----------------------------Module-Header------------------------------;
  3. ; Module Name: DITH775.ASM
  4. ;
  5. ; code to dither 16 or 24 bit DIBs to a 8bit DIB with a fixed palette
  6. ;
  7. ; NOTES:
  8. ; this is a ASM version of the code found in dith775.c
  9. ;
  10. ;-----------------------------------------------------------------------;
  11. ?PLM=1
  12. ?WIN=0
  13. .xlist
  14. include cmacro32.inc
  15. include windows.inc
  16. .list
  17. externA __AHINCR
  18. externA __AHSHIFT
  19. sBegin Data
  20. externB _lookup775 ; in look775.h
  21. externB _rdith775 ; in dtab775.h
  22. externB _gdith775 ; in dtab775.h
  23. sEnd Data
  24. ; The following structure should be used to access high and low
  25. ; words of a DWORD. This means that "word ptr foo[2]" -> "foo.hi".
  26. LONG struc
  27. lo dw ?
  28. hi dw ?
  29. LONG ends
  30. FARPOINTER struc
  31. off dw ?
  32. sel dw ?
  33. FARPOINTER ends
  34. ifndef SEGNAME
  35. SEGNAME equ <_TEXT>
  36. endif
  37. createSeg %SEGNAME, CodeSeg, word, public, CODE
  38. sBegin CodeSeg
  39. .386
  40. assumes cs,CodeSeg
  41. assumes ds,nothing
  42. assumes es,nothing
  43. ;--------------------------------------------------------------------------;
  44. ;
  45. ; GET16 - read a RGB555 from the input
  46. ;
  47. ; INPUT:
  48. ; fs:[esi] rgb555 DIB
  49. ;
  50. ; OUTPUT:
  51. ; bx rgb555
  52. ;
  53. ;--------------------------------------------------------------------------;
  54. GET16 macro col
  55. if col and 1
  56. shr ebx,16 ; get pel from last time
  57. else
  58. mov ebx, dword ptr fs:[esi] ; grab two pels
  59. add esi,4
  60. endif
  61. endm
  62. ;--------------------------------------------------------------------------;
  63. ;
  64. ; DITH m1, m2, row, col
  65. ;
  66. ; grab a 16 bit pel and dither it.
  67. ;
  68. ; m1 and m2 are the magic dither table offsets.
  69. ;
  70. ; here is the 'C' code we are emulating
  71. ;
  72. ; w = *((WORD huge *)pbS)++;
  73. ; r = (int)((w >> 7) & 0xF8);
  74. ; g = (int)((w >> 2) & 0xF8);
  75. ; b = (int)((w << 3) & 0xF8);
  76. ;
  77. ; *pbD++ = (BYTE)lookup775[ rdith775[r + m1] + gdith775[g + m1] + ((b + m2) >> 6) ];
  78. ;
  79. ; the 'magic' values vary over a 4x4 block
  80. ;
  81. ; m1: 1 17 25 41 m2: 2 26 38 62
  82. ; 31 36 7 12 46 54 19 18
  83. ; 20 4 39 23 30 6 58 34
  84. ; 33 28 15 9 50 42 22 14
  85. ;
  86. ;
  87. ; for a 2x2 dither use the following numbers:
  88. ;
  89. ; m1: 5 27 m2: 8 40
  90. ; 38 16 56 24
  91. ;
  92. ; m1: 1 41 m2: 2 62
  93. ; 33 9 50 14
  94. ;
  95. ; NOTE:
  96. ; !!! the lookup tables should be BYTEs not INTs !!!
  97. ;
  98. ; Entry:
  99. ; m1, m2 - magic values
  100. ; fs:esi - 16bit pel to dither
  101. ; ds - data segment
  102. ;
  103. ; Returns:
  104. ; al - dithered pel (rotated into eax)
  105. ;
  106. ; Uses:
  107. ; eax, ebx, edx, ebp, esi, edi, flags
  108. ;
  109. ; Saves:
  110. ; ecx, edi, es,ds,fs,gs,ss
  111. ;
  112. ;--------------------------------------------------------------------------;
  113. DITH16 macro m1, m2, row, col
  114. GET16 col
  115. mov al, bl ; get blue
  116. and al, 1Fh
  117. add al, (m2 shr 3)
  118. shr al, 3
  119. shr bx, 2 ; get green
  120. mov dl, bl
  121. and dx, 0F8h
  122. shr bx, 5 ; get red
  123. and bx, 0F8h
  124. add al, _rdith775[bx + m1]
  125. mov bl, dl
  126. add al, _gdith775[bx + m1]
  127. mov bl, al
  128. if col and 1
  129. mov al, byte ptr _lookup775[bx]
  130. xchg al, ah
  131. ror eax,16 ; rotate pixel into eax
  132. else
  133. mov ah, byte ptr _lookup775[bx]
  134. endif
  135. endm
  136. ;--------------------------------------------------------------------------;
  137. ;
  138. ; Dither16()
  139. ;
  140. ; Entry:
  141. ; Stack based parameters as described below.
  142. ;
  143. ; Returns:
  144. ; none
  145. ;
  146. ; Registers Preserved:
  147. ; DS,ES,ESI,EDI,EBP
  148. ;
  149. ;--------------------------------------------------------------------------;
  150. assumes ds,Data
  151. assumes es,nothing
  152. Dither16TJumpTable label dword
  153. dd Dither16Scan0
  154. dd Dither16Scan3
  155. dd Dither16Scan2
  156. dd Dither16Scan1
  157. cProc Dither16T,<FAR,PUBLIC,PASCAL>,<>
  158. parmD biDst ;--> BITMAPINFO of dest
  159. parmD lpDst ;--> to destination bits
  160. parmW DstX ;Destination origin - x coordinate
  161. parmW DstY ;Destination origin - y coordinate
  162. parmW DstXE ;x extent of the BLT
  163. parmW DstYE ;y extent of the BLT
  164. parmD biSrc ;--> BITMAPINFO of source
  165. parmD lpSrc ;--> to source bits
  166. parmW SrcX ;Source origin - x coordinate
  167. parmW SrcY ;Source origin - y coordinate
  168. parmD lpDitherTable ;not used (for 8->4 bit dither)
  169. localD SrcWidth ;width of source in bytes
  170. localD DstWidth ;width of dest in bytes
  171. localD SrcInc
  172. localD DstInc
  173. cBegin
  174. push esi
  175. push edi
  176. ; push ds
  177. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  178. ; We only handle (DstXE % 4) == 0 or 3. If it's == 1 or 2, then we
  179. ; round down, because otherwise we'd have to deal with half of a
  180. ; dither cell on the end.
  181. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  182. inc DstXE ; Make the == 3 mod 4 case work
  183. and DstXE, not 011b
  184. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  185. mov eax,16
  186. mov ebx,8
  187. call dither_init ; init all the frame variables
  188. jc Dither16Exit
  189. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  190. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  191. movzx ecx, DstYE ; divide by 4
  192. mov ebx, ecx
  193. add ecx, 3 ; be sure to round up
  194. shr ecx, 2
  195. jz Dither16Exit
  196. mov DstYE, cx
  197. movzx ecx, DstXE ; divide by 4
  198. shr ecx,2
  199. jz Dither16Exit
  200. mov DstXE,cx
  201. and ebx, 011b ; Get height mod 4
  202. jmp Dither16TJumpTable[ebx*4]
  203. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  204. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  205. align 4
  206. Dither16OuterLoop:
  207. movzx ecx, DstXE
  208. align 4
  209. Dither16Scan0:
  210. DITH16 1 2 0 0 ; DITH16 1 2 0 0
  211. DITH16 17 26 0 1 ; DITH16 41 62 0 1
  212. DITH16 25 38 0 2 ; DITH16 1 2 0 2
  213. DITH16 41 62 0 3 ; DITH16 41 62 0 3
  214. stos dword ptr es:[edi]
  215. dec ecx
  216. jnz Dither16Scan0
  217. add esi, SrcInc
  218. add edi, DstInc
  219. movzx ecx, DstXE
  220. align 4
  221. Dither16Scan1:
  222. DITH16 31 46 1 0 ; DITH16 33 50 1 0
  223. DITH16 36 54 1 1 ; DITH16 9 14 1 1
  224. DITH16 7 19 1 2 ; DITH16 33 50 1 2
  225. DITH16 12 18 1 3 ; DITH16 9 14 1 3
  226. stos dword ptr es:[edi]
  227. dec ecx
  228. jnz Dither16Scan1
  229. add esi, SrcInc
  230. add edi, DstInc
  231. movzx ecx, DstXE
  232. align 4
  233. Dither16Scan2:
  234. DITH16 20 30 2 0 ; DITH16 1 2 2 0
  235. DITH16 4 6 2 1 ; DITH16 41 62 2 1
  236. DITH16 39 58 2 2 ; DITH16 1 2 2 2
  237. DITH16 23 34 2 3 ; DITH16 41 62 2 3
  238. stos dword ptr es:[edi]
  239. dec ecx
  240. jnz Dither16Scan2
  241. add esi, SrcInc
  242. add edi, DstInc
  243. movzx ecx, DstXE
  244. align 4
  245. Dither16Scan3:
  246. DITH16 33 50 3 0 ; DITH16 33 50 3 0
  247. DITH16 28 42 3 1 ; DITH16 9 14 3 1
  248. DITH16 15 22 3 2 ; DITH16 33 50 3 2
  249. DITH16 9 14 3 3 ; DITH16 9 14 3 3
  250. stos dword ptr es:[edi]
  251. dec ecx
  252. jnz Dither16Scan3
  253. add esi, SrcInc
  254. add edi, DstInc
  255. dec DstYE
  256. jnz Dither16OuterLoop
  257. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  258. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  259. Dither16Exit:
  260. xor ax,ax
  261. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  262. ; pop ds
  263. pop edi
  264. pop esi
  265. cEnd
  266. ;--------------------------------------------------------------------------;
  267. ;
  268. ; Dither16L() - dither using lookup table(s)
  269. ;
  270. ; using dither matrix:
  271. ;
  272. ; 0 2 2 4
  273. ; 3 4 0 1 [or possibly 3 3 1 1 -- see which looks better]
  274. ; 2 0 4 2
  275. ; 3 3 1 1
  276. ;
  277. ; the dither matrix determines which lookup table to use.
  278. ;
  279. ; Entry:
  280. ; Stack based parameters as described below.
  281. ;
  282. ; Returns:
  283. ; none
  284. ;
  285. ; Registers Preserved:
  286. ; DS,ES,ESI,EDI,EBP
  287. ;
  288. ;--------------------------------------------------------------------------;
  289. assumes ds,Data
  290. assumes es,nothing
  291. FOO macro reg, err
  292. if err eq 0
  293. mov reg, ds:[ebx]
  294. elseif err eq 1
  295. mov reg, ds:[ebx + edx]
  296. elseif err eq 2
  297. mov reg, ds:[ebx + 2*edx]
  298. elseif err eq 3
  299. or bh,80h
  300. mov reg, ds:[ebx + 2*edx]
  301. elseif err eq 4
  302. mov reg, ds:[ebx + 4*edx]
  303. else
  304. bark
  305. endif
  306. endm
  307. DITH16L macro m1, m2, m3, m4
  308. mov bx, fs:[esi + 4]
  309. and bh, ch
  310. FOO al, m3
  311. mov bx, fs:[esi + 6]
  312. and bh, ch
  313. FOO ah, m4
  314. shl eax,16
  315. mov bx, fs:[esi + 0]
  316. and bh, ch
  317. FOO al, m1
  318. mov bx, fs:[esi + 2]
  319. and bh, ch
  320. FOO ah, m2
  321. mov dword ptr es:[edi], eax
  322. add edi, 4
  323. add esi, 8
  324. endm
  325. Dither16LJumpTable label dword
  326. dd Dither16lScan0
  327. dd Dither16lScan3
  328. dd Dither16lScan2
  329. dd Dither16lScan1
  330. cProc Dither16L,<FAR,PUBLIC,PASCAL>,<>
  331. parmD biDst ;--> BITMAPINFO of dest
  332. parmD lpDst ;--> to destination bits
  333. parmW DstX ;Destination origin - x coordinate
  334. parmW DstY ;Destination origin - y coordinate
  335. parmW DstXE ;x extent of the BLT
  336. parmW DstYE ;y extent of the BLT
  337. parmD biSrc ;--> BITMAPINFO of source
  338. parmD lpSrc ;--> to source bits
  339. parmW SrcX ;Source origin - x coordinate
  340. parmW SrcY ;Source origin - y coordinate
  341. parmD lpDitherTable ;196k dither table
  342. localD SrcWidth ;width of source in bytes
  343. localD DstWidth ;width of dest in bytes
  344. localD SrcInc
  345. localD DstInc
  346. cBegin
  347. push esi
  348. push edi
  349. push ds
  350. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  351. ; We only handle (DstXE % 4) == 0 or 3. If it's == 1 or 2, then we
  352. ; round down, because otherwise we'd have to deal with half of a
  353. ; dither cell on the end.
  354. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  355. inc DstXE ; Make the == 3 mod 4 case work
  356. and DstXE, not 011b
  357. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  358. mov eax,16
  359. mov ebx,8
  360. call dither_init ; init all the frame variables
  361. jc Dither16lExit
  362. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  363. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  364. movzx ecx, DstYE ; divide by 4
  365. mov ebx, ecx
  366. add ecx, 3 ; be sure to round up
  367. shr ecx, 2
  368. jz Dither16lExit
  369. mov DstYE, cx
  370. movzx ecx, DstXE ; divide by 4
  371. shr ecx,2
  372. jz Dither16lExit
  373. mov DstXE,cx
  374. mov ds, lpDitherTable.sel ; DS --> dither table
  375. mov ax, ds
  376. add ax, __AHINCR
  377. mov gs, ax
  378. xor ebx, ebx
  379. mov edx, 32768
  380. mov ch,7Fh
  381. and ebx, 011b ; Get height mod 4
  382. jmp Dither16LJumpTable[ebx*4]
  383. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  384. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  385. align 4
  386. Dither16lOuterLoop:
  387. mov cl, byte ptr DstXE
  388. align 4
  389. Dither16lScan0:
  390. DITH16L 0 2 2 4
  391. dec cl
  392. jnz short Dither16lScan0
  393. add esi, SrcInc
  394. add edi, DstInc
  395. mov cl, byte ptr DstXE
  396. align 4
  397. Dither16lScan1:
  398. DITH16L 3 4 0 1
  399. dec cl
  400. jnz short Dither16lScan1
  401. add esi, SrcInc
  402. add edi, DstInc
  403. mov cl, byte ptr DstXE
  404. align 4
  405. Dither16lScan2:
  406. DITH16L 2 0 4 2
  407. dec cl
  408. jnz short Dither16lScan2
  409. add esi, SrcInc
  410. add edi, DstInc
  411. mov cl, byte ptr DstXE
  412. align 4
  413. Dither16lScan3:
  414. DITH16L 3 3 1 1
  415. dec cl
  416. jnz short Dither16lScan3
  417. add esi, SrcInc
  418. add edi, DstInc
  419. dec DstYE
  420. jnz Dither16lOuterLoop
  421. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  422. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  423. Dither16lExit:
  424. xor ax,ax
  425. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  426. mov gs,ax
  427. pop ds
  428. pop edi
  429. pop esi
  430. cEnd
  431. ;--------------------------------------------------------------------------;
  432. ;
  433. ; Dither16S() - dither using scale table(s)
  434. ;
  435. ; pel8 = lookup[scale[rgb555] + error]
  436. ;
  437. ; using error matrix:
  438. ;
  439. ; 0 3283 4924 8207
  440. ; 6565 6566 1641 1642
  441. ; 3283 0 8207 4924
  442. ; 6566 4925 3282 1641
  443. ;
  444. ; Entry:
  445. ; Stack based parameters as described below.
  446. ;
  447. ; Returns:
  448. ; none
  449. ;
  450. ; Registers Preserved:
  451. ; DS,ES,ESI,EDI,EBP
  452. ;
  453. ;--------------------------------------------------------------------------;
  454. assumes ds,Data
  455. assumes es,nothing
  456. DITH16S macro m1, m2, m3, m4
  457. mov ebx, fs:[esi + 4] ; grab rgb555
  458. add bx, bx
  459. mov bx, ds:[bx] ; scale it
  460. mov al, gs:[bx + m3] ; dither it with error
  461. shr ebx,16
  462. ; mov bx, fs:[esi + 6] ; grab rgb555
  463. add bx, bx
  464. mov bx, ds:[bx] ; scale it
  465. mov ah, gs:[bx + m4] ; dither it with error
  466. shl eax,16
  467. mov ebx, fs:[esi + 0] ; grab rgb555
  468. add bx, bx
  469. mov bx, ds:[bx] ; scale it
  470. mov al, gs:[bx + m1] ; dither it with error
  471. shr ebx,16
  472. ; mov bx, fs:[esi + 2] ; grab rgb555
  473. add bx, bx
  474. mov bx, ds:[bx] ; scale it
  475. mov ah, gs:[bx + m2] ; dither it with error
  476. mov dword ptr es:[edi], eax
  477. add edi, 4
  478. add esi, 8
  479. endm
  480. Dither16SJumpTable label dword
  481. dd Dither16sScan0
  482. dd Dither16sScan3
  483. dd Dither16sScan2
  484. dd Dither16sScan1
  485. cProc Dither16S,<FAR,PUBLIC,PASCAL>,<>
  486. parmD biDst ;--> BITMAPINFO of dest
  487. parmD lpDst ;--> to destination bits
  488. parmW DstX ;Destination origin - x coordinate
  489. parmW DstY ;Destination origin - y coordinate
  490. parmW DstXE ;x extent of the BLT
  491. parmW DstYE ;y extent of the BLT
  492. parmD biSrc ;--> BITMAPINFO of source
  493. parmD lpSrc ;--> to source bits
  494. parmW SrcX ;Source origin - x coordinate
  495. parmW SrcY ;Source origin - y coordinate
  496. parmD lpDitherTable ;196k dither table
  497. localD SrcWidth ;width of source in bytes
  498. localD DstWidth ;width of dest in bytes
  499. localD SrcInc
  500. localD DstInc
  501. cBegin
  502. push esi
  503. push edi
  504. push ds
  505. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  506. ; align everything on four pixel boundries, we realy should
  507. ; not do this but should handle the general case instead,
  508. ; but hey we are hackers.
  509. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  510. inc DstXE ; Make the == 3 mod 4 case work
  511. and DstXE, not 011b
  512. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  513. mov eax,16
  514. mov ebx,8
  515. call dither_init ; init all the frame variables
  516. jc Dither16sExit
  517. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  518. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  519. movzx ecx, DstYE ; divide by 4
  520. mov ebx, ecx
  521. add ecx, 3 ; be sure to round up
  522. shr ecx, 2
  523. jz Dither16sExit
  524. mov DstYE, cx
  525. movzx ecx, DstXE ; divide by 4
  526. shr ecx,2
  527. jz Dither16sExit
  528. mov DstXE,cx
  529. mov ds, lpDitherTable.sel ; DS --> dither table
  530. mov ax, ds
  531. add ax, __AHINCR
  532. mov gs, ax
  533. and ebx, 011b ; Get height mod 4
  534. jmp Dither16SJumpTable[ebx*4]
  535. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  536. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  537. align 4
  538. Dither16sOuterLoop:
  539. movzx ecx, DstXE
  540. align 4
  541. Dither16sScan0:
  542. DITH16S 0 3283 4924 8207
  543. dec ecx
  544. jnz short Dither16sScan0
  545. add esi, SrcInc
  546. add edi, DstInc
  547. movzx ecx, DstXE
  548. align 4
  549. Dither16sScan1:
  550. DITH16S 6565 6566 1641 1642
  551. dec ecx
  552. jnz short Dither16sScan1
  553. add esi, SrcInc
  554. add edi, DstInc
  555. movzx ecx, DstXE
  556. align 4
  557. Dither16sScan2:
  558. DITH16S 3283 0 8207 4924
  559. dec ecx
  560. jnz short Dither16sScan2
  561. add esi, SrcInc
  562. add edi, DstInc
  563. movzx ecx, DstXE
  564. align 4
  565. Dither16sScan3:
  566. DITH16S 6566 4925 3282 1641
  567. dec ecx
  568. jnz short Dither16sScan3
  569. add esi, SrcInc
  570. add edi, DstInc
  571. dec DstYE
  572. jnz Dither16sOuterLoop
  573. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  574. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  575. Dither16sExit:
  576. xor ax,ax
  577. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  578. mov gs,ax
  579. pop ds
  580. pop edi
  581. pop esi
  582. cEnd
  583. ;--------------------------------------------------------------------------;
  584. ;
  585. ; LODSB32 - get a byte, every four times doing a LODSD
  586. ;
  587. ;--------------------------------------------------------------------------;
  588. LODSB32_N = 0
  589. LODSB32 macro
  590. if (LODSB32_N mod 4) eq 0
  591. ;; lods dword ptr ds:[esi]
  592. mov eax,dword ptr fs:[esi]
  593. add esi,4
  594. else
  595. ror eax,8
  596. endif
  597. LODSB32_N = LODSB32_N + 1
  598. endm
  599. ;--------------------------------------------------------------------------;
  600. ;
  601. ; Dither24S() - dither using scale table(s)
  602. ;
  603. ; pel8 = lookup[scale[rgb555] + error]
  604. ;
  605. ; using error matrix:
  606. ;
  607. ; 0 3283 4924 8207
  608. ; 6565 6566 1641 1642
  609. ; 3283 0 8207 4924
  610. ; 6566 4925 3282 1641
  611. ;
  612. ; Entry:
  613. ; Stack based parameters as described below.
  614. ;
  615. ; Returns:
  616. ; none
  617. ;
  618. ; Registers Preserved:
  619. ; DS,ES,ESI,EDI,EBP
  620. ;
  621. ;--------------------------------------------------------------------------;
  622. assumes ds,Data
  623. assumes es,nothing
  624. GET24 macro
  625. LODSB32 ; get BLUE
  626. and al,0F8h
  627. mov bl,al
  628. LODSB32 ; get GREEN
  629. mov bh,al
  630. shr bh,3
  631. shr ebx,2
  632. LODSB32 ; get RED
  633. and al,0F8h
  634. or bh,al
  635. endm
  636. DITH24S macro m1, m2, m3, m4
  637. GET24 ; grab rgb555*2
  638. movzx ebx, word ptr ds:[ebx] ; scale it
  639. mov dl, ds:[ebx + m1 + 65536] ; dither it with error
  640. GET24 ; grab rgb555*2
  641. movzx ebx, word ptr ds:[ebx] ; scale it
  642. mov dh, ds:[ebx + m2 + 65536] ; dither it with error
  643. ror edx,16 ; save ax
  644. GET24 ; grab rgb555
  645. movzx ebx, word ptr ds:[ebx] ; scale it
  646. mov dl, ds:[ebx + m3 + 65536] ; dither it with error
  647. GET24 ; grab rgb555
  648. movzx ebx, word ptr ds:[ebx] ; scale it
  649. mov dh, ds:[ebx + m4 + 65536] ; dither it with error
  650. ror edx,16 ; get eax right
  651. mov dword ptr es:[edi], edx ; store four pixels
  652. add edi, 4
  653. endm
  654. Dither24SJumpTable label dword
  655. dd Dither24sScan0
  656. dd Dither24sScan3
  657. dd Dither24sScan2
  658. dd Dither24sScan1
  659. cProc Dither24S,<FAR,PUBLIC,PASCAL>,<>
  660. parmD biDst ;--> BITMAPINFO of dest
  661. parmD lpDst ;--> to destination bits
  662. parmW DstX ;Destination origin - x coordinate
  663. parmW DstY ;Destination origin - y coordinate
  664. parmW DstXE ;x extent of the BLT
  665. parmW DstYE ;y extent of the BLT
  666. parmD biSrc ;--> BITMAPINFO of source
  667. parmD lpSrc ;--> to source bits
  668. parmW SrcX ;Source origin - x coordinate
  669. parmW SrcY ;Source origin - y coordinate
  670. parmD lpDitherTable ;196k dither table
  671. localD SrcWidth ;width of source in bytes
  672. localD DstWidth ;width of dest in bytes
  673. localD SrcInc
  674. localD DstInc
  675. cBegin
  676. push esi
  677. push edi
  678. push ds
  679. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  680. ; align everything on four pixel boundries, we realy should
  681. ; not do this but should handle the general case instead,
  682. ; but hey we are hackers.
  683. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  684. ; inc DstXE ; Make the == 3 mod 4 case work
  685. and DstXE, not 011b
  686. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  687. mov eax,24
  688. mov ebx,8
  689. call dither_init ; init all the frame variables
  690. jc Dither24sExit
  691. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  692. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  693. movzx ecx, DstYE ; divide by 4
  694. mov ebx, ecx
  695. add ecx, 3 ; be sure to round up
  696. shr ecx, 2
  697. jz Dither24sExit
  698. mov DstYE, cx
  699. movzx ecx, DstXE ; divide by 4
  700. shr ecx,2
  701. jz Dither24sExit
  702. mov DstXE,cx
  703. mov ds, lpDitherTable.sel ; DS --> dither table
  704. mov ax, ds
  705. add ax, __AHINCR
  706. mov gs, ax
  707. and ebx, 011b ; Get height mod 4
  708. jmp Dither24SJumpTable[ebx*4]
  709. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  710. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  711. align 4
  712. Dither24sOuterLoop:
  713. movzx ecx, DstXE
  714. align 4
  715. Dither24sScan0:
  716. DITH24S 0 3283 4924 8207
  717. dec ecx
  718. jnz Dither24sScan0
  719. add esi, SrcInc
  720. add edi, DstInc
  721. movzx ecx, DstXE
  722. align 4
  723. Dither24sScan1:
  724. DITH24S 6565 6566 1641 1642
  725. dec ecx
  726. jnz Dither24sScan1
  727. add esi, SrcInc
  728. add edi, DstInc
  729. movzx ecx, DstXE
  730. align 4
  731. Dither24sScan2:
  732. DITH24S 3283 0 8207 4924
  733. dec ecx
  734. jnz Dither24sScan2
  735. add esi, SrcInc
  736. add edi, DstInc
  737. movzx ecx, DstXE
  738. align 4
  739. Dither24sScan3:
  740. DITH24S 6566 4925 3282 1641
  741. dec ecx
  742. jnz Dither24sScan3
  743. add esi, SrcInc
  744. add edi, DstInc
  745. dec DstYE
  746. jnz Dither24sOuterLoop
  747. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  748. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  749. Dither24sExit:
  750. xor ax,ax
  751. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  752. mov gs,ax
  753. pop ds
  754. pop edi
  755. pop esi
  756. cEnd
  757. ;--------------------------------------------------------------------------;
  758. ;
  759. ; Dither32S() - dither using scale table(s)
  760. ;
  761. ; pel8 = lookup[scale[rgb555] + error]
  762. ;
  763. ; using error matrix:
  764. ;
  765. ; 0 3283 4924 8207
  766. ; 6565 6566 1641 1642
  767. ; 3283 0 8207 4924
  768. ; 6566 4925 3282 1641
  769. ;
  770. ; Entry:
  771. ; Stack based parameters as described below.
  772. ;
  773. ; Returns:
  774. ; none
  775. ;
  776. ; Registers Preserved:
  777. ; DS,ES,ESI,EDI,EBP
  778. ;
  779. ;--------------------------------------------------------------------------;
  780. assumes ds,Data
  781. assumes es,nothing
  782. GET32 macro
  783. if 1
  784. mov bx,fs:[esi+0] ; ebx = ????????????????GGGGGgggBBBBBbbb
  785. shr bh,3 ; ebx = 000?????????????000GGGGGBBBBBbbb
  786. shr bx,3 ; ebx = 000?????????????000000GGGGGBBBBB
  787. mov al,fs:[esi+2] ; eax = ????????????????????????RRRRRrrr
  788. and al,0F8h ; eax = ????????????????????????RRRRR000
  789. shr al,1 ; eax = ????????????????????????0RRRRR00
  790. or bh,al ; ebx = 000?????????????0RRRRRGGGGGBBBBB
  791. add ebx,ebx ; ebx = 00?????????????0RRRRRGGGGGBBBBB0
  792. add esi,4
  793. else
  794. mov eax,fs:[esi] ; eax = RRRRRrrrGGGGGgggBBBBBbbb
  795. add esi,2
  796. mov bl,al ; ebx = 00000000????????BBBBBbbb
  797. shr eax,8 ; eax = 00000000RRRRRrrrGGGGGggg
  798. shr ah,3 ; eax = 00000000000RRRRRGGGGGggg
  799. shl ax,5 ; eax = 000000RRRRRGGGGGggg00000
  800. endif
  801. endm
  802. DITH32S macro m1, m2, m3, m4
  803. GET32 ; grab rgb555*2
  804. mov bx, word ptr ds:[ebx] ; scale it
  805. mov dl, ds:[ebx + m1 + 65536] ; dither it with error
  806. GET32 ; grab rgb555*2
  807. mov bx, word ptr ds:[ebx] ; scale it
  808. mov dh, ds:[ebx + m2 + 65536] ; dither it with error
  809. ror edx,16 ; save ax
  810. GET32 ; grab rgb555
  811. mov bx, word ptr ds:[ebx] ; scale it
  812. mov dl, ds:[ebx + m3 + 65536] ; dither it with error
  813. GET32 ; grab rgb555
  814. movzx bx, word ptr ds:[ebx] ; scale it
  815. mov dh, ds:[ebx + m4 + 65536] ; dither it with error
  816. ror edx,16 ; get eax right
  817. mov dword ptr es:[edi], edx ; store four pixels
  818. add edi, 4
  819. endm
  820. Dither32SJumpTable label dword
  821. dd Dither32sScan0
  822. dd Dither32sScan3
  823. dd Dither32sScan2
  824. dd Dither32sScan1
  825. cProc Dither32S,<FAR,PUBLIC,PASCAL>,<>
  826. parmD biDst ;--> BITMAPINFO of dest
  827. parmD lpDst ;--> to destination bits
  828. parmW DstX ;Destination origin - x coordinate
  829. parmW DstY ;Destination origin - y coordinate
  830. parmW DstXE ;x extent of the BLT
  831. parmW DstYE ;y extent of the BLT
  832. parmD biSrc ;--> BITMAPINFO of source
  833. parmD lpSrc ;--> to source bits
  834. parmW SrcX ;Source origin - x coordinate
  835. parmW SrcY ;Source origin - y coordinate
  836. parmD lpDitherTable ;196k dither table
  837. localD SrcWidth ;width of source in bytes
  838. localD DstWidth ;width of dest in bytes
  839. localD SrcInc
  840. localD DstInc
  841. cBegin
  842. push esi
  843. push edi
  844. push ds
  845. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  846. ; align everything on four pixel boundries, we realy should
  847. ; not do this but should handle the general case instead,
  848. ; but hey we are hackers.
  849. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  850. ; inc DstXE ; Make the == 3 mod 4 case work
  851. and DstXE, not 011b
  852. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  853. mov eax,32
  854. mov ebx,8
  855. call dither_init ; init all the frame variables
  856. jc Dither32sExit
  857. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  858. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  859. movzx ecx, DstYE ; divide by 4
  860. mov ebx, ecx
  861. add ecx, 3 ; be sure to round up
  862. shr ecx, 2
  863. jz Dither32sExit
  864. mov DstYE, cx
  865. movzx ecx, DstXE ; divide by 4
  866. shr ecx,2
  867. jz Dither32sExit
  868. mov DstXE,cx
  869. mov ds, lpDitherTable.sel ; DS --> dither table
  870. mov ax, ds
  871. add ax, __AHINCR
  872. mov gs, ax
  873. and ebx, 011b ; Get height mod 4
  874. jmp Dither32SJumpTable[ebx*4]
  875. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  876. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  877. align 4
  878. Dither32sOuterLoop:
  879. movzx ecx, DstXE
  880. align 4
  881. Dither32sScan0:
  882. DITH32S 0 3283 4924 8207
  883. dec ecx
  884. jnz Dither32sScan0
  885. add esi, SrcInc
  886. add edi, DstInc
  887. movzx ecx, DstXE
  888. align 4
  889. Dither32sScan1:
  890. DITH32S 6565 6566 1641 1642
  891. dec ecx
  892. jnz Dither32sScan1
  893. add esi, SrcInc
  894. add edi, DstInc
  895. movzx ecx, DstXE
  896. align 4
  897. Dither32sScan2:
  898. DITH32S 3283 0 8207 4924
  899. dec ecx
  900. jnz Dither32sScan2
  901. add esi, SrcInc
  902. add edi, DstInc
  903. movzx ecx, DstXE
  904. align 4
  905. Dither32sScan3:
  906. DITH32S 6566 4925 3282 1641
  907. dec ecx
  908. jnz Dither32sScan3
  909. add esi, SrcInc
  910. add edi, DstInc
  911. dec DstYE
  912. jnz Dither32sOuterLoop
  913. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  914. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  915. Dither32sExit:
  916. xor ax,ax
  917. mov fs,ax ; to make KRNL286.EXE and DOSX happy
  918. mov gs,ax
  919. pop ds
  920. pop edi
  921. pop esi
  922. cEnd
  923. ;--------------------------------------------------------------------------;
  924. ;
  925. ; dither_init
  926. ;
  927. ; init local frame vars for DitherDIB
  928. ;
  929. ; ENTRY:
  930. ; AX - source bpp
  931. ; BX - dest bpp
  932. ; ss:bp --> ditherdib frame
  933. ;
  934. ; EXIT:
  935. ; FS:ESI --> source DIB start x,y
  936. ; ES:EDI --> dest DIB start x,y
  937. ; DS: --> dither tables (in DGROUP)
  938. ;
  939. ;--------------------------------------------------------------------------;
  940. dither_init_error:
  941. stc
  942. ret
  943. dither_init proc near
  944. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  945. ; validate the DIBs
  946. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  947. movzx eax,ax
  948. movzx ebx,bx
  949. movzx ecx,cx
  950. movzx edx,dx
  951. movzx edi,di
  952. movzx esi,si
  953. lfs si, biSrc
  954. les di, biDst
  955. mov cx, es:[di].biBitCount ; dest must be right
  956. cmp cx, bx
  957. jne dither_init_error
  958. mov cx, fs:[si].biBitCount ; source must be right
  959. cmp cx, ax
  960. jne dither_init_error
  961. dither_init_bit_depth_ok:
  962. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  963. ;
  964. ; Set up the initial source pointer
  965. ;
  966. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  967. mov eax,fs:[si].biWidth
  968. mul ecx
  969. add eax,31
  970. and eax,not 31
  971. shr eax,3
  972. mov SrcWidth,eax
  973. mov SrcInc,eax
  974. lfs si,lpSrc
  975. movzx edx,SrcY
  976. mul edx
  977. add esi,eax
  978. movzx eax,SrcX
  979. mul ecx
  980. shr eax,3
  981. add esi,eax
  982. movzx eax, DstXE ; SrcInc = SrcWidth - DstXE*bits/8
  983. mul ecx
  984. shr eax, 3
  985. sub SrcInc, eax
  986. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  987. ;
  988. ; Set up the initial dest pointer
  989. ;
  990. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  991. mov cx, es:[di].biBitCount
  992. mov eax,es:[di].biWidth
  993. mul ecx
  994. add eax,31
  995. and eax,not 31
  996. shr eax,3
  997. mov DstWidth,eax
  998. mov DstInc,eax
  999. cmp es:[edi].biHeight,0 ; init a upside down DIB
  1000. jge short @f
  1001. movsx ebx,DstY
  1002. add ebx,es:[edi].biHeight
  1003. not ebx
  1004. mov DstY,bx
  1005. neg DstWidth
  1006. neg DstInc
  1007. @@:
  1008. les di,lpDst
  1009. movsx edx,DstY
  1010. mul edx
  1011. add edi,eax
  1012. movsx eax,DstX
  1013. mul ecx
  1014. shr eax,3
  1015. add edi,eax
  1016. movzx eax, DstXE ; DstInc = DstWidth - DstXE*bits/8
  1017. mul ecx
  1018. shr eax, 3
  1019. sub DstInc, eax
  1020. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  1021. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
  1022. dither_init_exit:
  1023. clc
  1024. ret
  1025. dither_init endp
  1026. sEnd CodeSeg
  1027. end