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.

898 lines
26 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // DITH775.C - full color dither (to a palette with 7 red, 7 green 5 blue
  4. // levels)
  5. //
  6. // NOTE this file contains the 'C' code and DITH775A.ASM has the ASM code.
  7. //
  8. // This file does the following dithering
  9. //
  10. // 24bpp -> 8bpp
  11. // 16bpp -> 8bpp
  12. //
  13. // 8bpp -> 4bpp N/I
  14. // 16bpp -> 4bpp N/I
  15. // 24bpp -> 4bpp N/I
  16. //
  17. // Using four different methods
  18. //
  19. // Lookup - fastest 1 table lookup per 16bpp pel (160K for table)
  20. // Scale - fast 2 table lookups per 16bpp pel (128K for tables)
  21. // Table - fast 3 table lookups plus shifting (~1K for tables)
  22. //
  23. // Lookup and Scale are 386 asm code *only* (in dith775a.asm)
  24. // Table is in 'C' and 386 asm.
  25. //
  26. //////////////////////////////////////////////////////////////////////////////
  27. #include <windows.h>
  28. #include <windowsx.h>
  29. #include "drawdibi.h"
  30. #include "dither.h"
  31. #include "dith775.h"
  32. //#define OLDDITHER
  33. #ifdef WIN32
  34. #define DITHER_DEFAULT DITHER_TABLEC
  35. #else
  36. #define DITHER_DEFAULT DITHER_SCALE
  37. #endif
  38. #define DITHER_TABLEC 0 // table based 'C' code
  39. #define DITHER_TABLE 1 // table based assembler
  40. #define DITHER_SCALE 2 // scale tables
  41. #define DITHER_LOOKUP 3 // 5 lookup tables!
  42. UINT wDitherMethod = (UINT)-1;
  43. LPVOID Dither16InitScale(void);
  44. LPVOID Dither16InitLookup(void);
  45. int giDitherTableUsage = 0;
  46. LPVOID glpDitherTable;
  47. static void Get775Colors(LPBITMAPINFOHEADER lpbi);
  48. //////////////////////////////////////////////////////////////////////////////
  49. //
  50. //
  51. //////////////////////////////////////////////////////////////////////////////
  52. void FAR PASCAL Dither24C(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  53. void FAR PASCAL Dither24S(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  54. void FAR PASCAL Dither32C(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  55. void FAR PASCAL Dither32S(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  56. void FAR PASCAL Dither16C(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  57. void FAR PASCAL Dither16T(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  58. void FAR PASCAL Dither16L(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  59. void FAR PASCAL Dither16S(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  60. //////////////////////////////////////////////////////////////////////////////
  61. //
  62. // DitherTableInit()
  63. //
  64. //////////////////////////////////////////////////////////////////////////////
  65. static LPVOID DitherTableInit()
  66. {
  67. // no need to re-init table.
  68. if (glpDitherTable || wDitherMethod != (UINT)-1)
  69. {
  70. giDitherTableUsage++;
  71. return glpDitherTable;
  72. }
  73. //
  74. // choose a dither method
  75. //
  76. if (wDitherMethod == -1)
  77. {
  78. wDitherMethod = DITHER_DEFAULT;
  79. }
  80. #ifdef DEBUG
  81. wDitherMethod = (int)GetProfileInt(TEXT("DrawDib"), TEXT("DitherMethod"), (UINT)wDitherMethod);
  82. #endif
  83. switch (wDitherMethod)
  84. {
  85. default:
  86. case DITHER_TABLEC:
  87. case DITHER_TABLE:
  88. break;
  89. #ifndef WIN32
  90. case DITHER_SCALE:
  91. glpDitherTable = Dither16InitScale();
  92. if (glpDitherTable == NULL)
  93. wDitherMethod = DITHER_TABLE;
  94. break;
  95. case DITHER_LOOKUP:
  96. glpDitherTable = Dither16InitLookup();
  97. if (glpDitherTable == NULL)
  98. wDitherMethod = DITHER_TABLE;
  99. break;
  100. #endif // WIN32
  101. }
  102. giDitherTableUsage = 1;
  103. return glpDitherTable;
  104. }
  105. //////////////////////////////////////////////////////////////////////////////
  106. //
  107. // DitherTableFree()
  108. //
  109. //////////////////////////////////////////////////////////////////////////////
  110. void FAR PASCAL DitherTableFree()
  111. {
  112. if (giDitherTableUsage == 0 || --giDitherTableUsage > 0)
  113. return;
  114. if (glpDitherTable)
  115. {
  116. GlobalFreePtr(glpDitherTable);
  117. glpDitherTable = NULL;
  118. wDitherMethod = (UINT)-1;
  119. }
  120. }
  121. //////////////////////////////////////////////////////////////////////////////
  122. //
  123. // DitherInit()
  124. //
  125. //////////////////////////////////////////////////////////////////////////////
  126. LPVOID FAR PASCAL Dither8Init(LPBITMAPINFOHEADER lpbi, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR *lpDitherProc, LPVOID lpDitherTable)
  127. {
  128. return DitherDeviceInit(lpbi, lpbiOut, lpDitherProc, lpDitherTable);
  129. }
  130. //////////////////////////////////////////////////////////////////////////////
  131. //
  132. // DitherInit()
  133. //
  134. //////////////////////////////////////////////////////////////////////////////
  135. LPVOID FAR PASCAL Dither16Init(LPBITMAPINFOHEADER lpbi, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR *lpDitherProc, LPVOID lpDitherTable)
  136. {
  137. Get775Colors(lpbiOut);
  138. //
  139. // choose a dither method
  140. //
  141. if (lpDitherTable == NULL)
  142. lpDitherTable = DitherTableInit();
  143. switch (wDitherMethod)
  144. {
  145. default:
  146. case DITHER_TABLEC:
  147. *lpDitherProc = Dither16C;
  148. break;
  149. #ifndef WIN32
  150. case DITHER_TABLE:
  151. *lpDitherProc = Dither16T;
  152. break;
  153. case DITHER_SCALE:
  154. *lpDitherProc = Dither16S;
  155. break;
  156. case DITHER_LOOKUP:
  157. *lpDitherProc = Dither16L;
  158. break;
  159. #endif // WIN32
  160. }
  161. return lpDitherTable;
  162. }
  163. //////////////////////////////////////////////////////////////////////////////
  164. //
  165. // DitherTerm()
  166. //
  167. //////////////////////////////////////////////////////////////////////////////
  168. void FAR PASCAL Dither16Term(LPVOID lpDitherTable)
  169. {
  170. DitherTableFree();
  171. }
  172. //////////////////////////////////////////////////////////////////////////////
  173. //
  174. // Dither24Init()
  175. //
  176. //////////////////////////////////////////////////////////////////////////////
  177. LPVOID FAR PASCAL Dither24Init(LPBITMAPINFOHEADER lpbi, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR *lpDitherProc, LPVOID lpDitherTable)
  178. {
  179. Get775Colors(lpbiOut);
  180. //
  181. // choose a dither method
  182. //
  183. if (lpDitherTable == NULL)
  184. lpDitherTable = DitherTableInit();
  185. switch (wDitherMethod)
  186. {
  187. default:
  188. case DITHER_TABLE:
  189. case DITHER_TABLEC:
  190. *lpDitherProc = Dither24C;
  191. break;
  192. #ifndef WIN32
  193. case DITHER_SCALE:
  194. *lpDitherProc = Dither24S;
  195. break;
  196. #endif // WIN32
  197. }
  198. return lpDitherTable;
  199. }
  200. //////////////////////////////////////////////////////////////////////////////
  201. //
  202. // Dither24Term()
  203. //
  204. //////////////////////////////////////////////////////////////////////////////
  205. void FAR PASCAL Dither24Term(LPVOID lpDitherTable)
  206. {
  207. DitherTableFree();
  208. }
  209. //////////////////////////////////////////////////////////////////////////////
  210. //
  211. // Dither32Init()
  212. //
  213. //////////////////////////////////////////////////////////////////////////////
  214. LPVOID FAR PASCAL Dither32Init(LPBITMAPINFOHEADER lpbi, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR *lpDitherProc, LPVOID lpDitherTable)
  215. {
  216. // no need to re-init table.
  217. Get775Colors(lpbiOut);
  218. //
  219. // choose a dither method
  220. //
  221. if (lpDitherTable == NULL)
  222. lpDitherTable = DitherTableInit();
  223. switch (wDitherMethod)
  224. {
  225. default:
  226. case DITHER_TABLE:
  227. case DITHER_TABLEC:
  228. *lpDitherProc = Dither32C;
  229. break;
  230. #ifndef WIN32
  231. case DITHER_SCALE:
  232. *lpDitherProc = Dither32S;
  233. break;
  234. #endif // WIN32
  235. }
  236. return lpDitherTable;
  237. }
  238. //////////////////////////////////////////////////////////////////////////////
  239. //
  240. // Dither32Term()
  241. //
  242. //////////////////////////////////////////////////////////////////////////////
  243. void FAR PASCAL Dither32Term(LPVOID lpDitherTable)
  244. {
  245. DitherTableFree();
  246. }
  247. //////////////////////////////////////////////////////////////////////////////
  248. //
  249. // Dither16InitScale()
  250. //
  251. //////////////////////////////////////////////////////////////////////////////
  252. LPVOID Dither16InitScale()
  253. {
  254. LPVOID p;
  255. LPBYTE pbLookup;
  256. LPWORD pwScale;
  257. UINT r,g,b;
  258. p = GlobalAllocPtr(GMEM_MOVEABLE|GMEM_SHARE, 32768l*2+64000);
  259. if (p == NULL)
  260. return NULL;
  261. pwScale = (LPWORD)p;
  262. for (r=0; r<32; r++)
  263. for (g=0; g<32; g++)
  264. for (b=0; b<32; b++)
  265. *pwScale++ = 1600 * r + 40 * g + b;
  266. /* should this be WORD or UINT ? */
  267. pbLookup = (LPBYTE)(((WORD _huge *)p) + 32768l);
  268. for (r=0; r<40; r++)
  269. for (g=0; g<40; g++)
  270. for (b=0; b<40; b++)
  271. *pbLookup++ = lookup775[35*rlevel[r] + 5*glevel[g] + blevel[b]];
  272. return p;
  273. }
  274. //////////////////////////////////////////////////////////////////////////////
  275. //
  276. // Dither16InitLookup()
  277. //
  278. //////////////////////////////////////////////////////////////////////////////
  279. LPVOID Dither16InitLookup()
  280. {
  281. LPVOID p;
  282. BYTE _huge *pb;
  283. UINT r,g,b,i,j;
  284. p = GlobalAllocPtr(GHND|GMEM_SHARE, 32768l*5);
  285. if (p == NULL)
  286. return NULL;
  287. pb = (BYTE _huge *)p;
  288. for (i=0; i<5; i++) {
  289. j = ((i < 3) ? i*2 : i*2-1);
  290. for (r=0; r<32; r++) {
  291. for (g=0; g<32; g++) {
  292. for (b=0; b<32; b++) {
  293. *pb++ = lookup775[rlevel[r+i]*35 + glevel[g+i]*5 + blevel[b+j]];
  294. }
  295. }
  296. }
  297. }
  298. return p;
  299. }
  300. //////////////////////////////////////////////////////////////////////////////
  301. //
  302. // GetDithColors() get the dither palette
  303. //
  304. //////////////////////////////////////////////////////////////////////////////
  305. static void Get775Colors(LPBITMAPINFOHEADER lpbi)
  306. {
  307. LPRGBQUAD prgb = (LPRGBQUAD)(((LPBYTE)lpbi) + (UINT)lpbi->biSize);
  308. int i;
  309. for (i=0; i<256; i++)
  310. {
  311. prgb[i].rgbRed = dpal775[i][0];
  312. prgb[i].rgbGreen = dpal775[i][1];
  313. prgb[i].rgbBlue = dpal775[i][2];
  314. prgb[i].rgbReserved = 0;
  315. }
  316. lpbi->biClrUsed = 256;
  317. }
  318. #if 0
  319. //////////////////////////////////////////////////////////////////////////////
  320. //
  321. // CreateDith775Palette() create the dither palette
  322. //
  323. //////////////////////////////////////////////////////////////////////////////
  324. HPALETTE FAR CreateDith775Palette()
  325. {
  326. int i;
  327. HDC hdc;
  328. HPALETTE hpal;
  329. struct {
  330. WORD palVersion;
  331. WORD palNumEntries;
  332. PALETTEENTRY palPalEntry[256];
  333. } pal;
  334. pal.palVersion = 0x300;
  335. pal.palNumEntries = 256;
  336. for (i=0; i<(int)pal.palNumEntries; i++)
  337. {
  338. pal.palPalEntry[i].peRed = dpal775[i][0];
  339. pal.palPalEntry[i].peGreen = dpal775[i][1];
  340. pal.palPalEntry[i].peBlue = dpal775[i][2];
  341. pal.palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  342. }
  343. #ifndef OLDDITHER
  344. //
  345. // our palette is built assuming the "cosmic" colors at the
  346. // beging and the end. so put the real mcoy there!
  347. //
  348. hdc = GetDC(NULL);
  349. if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  350. {
  351. GetSystemPaletteEntries(hdc, 0, 10, &pal.palPalEntry[0]);
  352. GetSystemPaletteEntries(hdc, 246, 10, &pal.palPalEntry[246]);
  353. }
  354. ReleaseDC(NULL, hdc);
  355. #endif
  356. hpal = CreatePalette((LPLOGPALETTE)&pal);
  357. return hpal;
  358. }
  359. #endif
  360. //////////////////////////////////////////////////////////////////////////////
  361. //
  362. // Dither24TC - dither from 24 to 8 using the Table method in 'C' Code
  363. //
  364. //////////////////////////////////////////////////////////////////////////////
  365. void FAR PASCAL Dither24C(
  366. LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest
  367. LPVOID lpDst, // --> to destination bits
  368. int DstX, // Destination origin - x coordinate
  369. int DstY, // Destination origin - y coordinate
  370. int DstXE, // x extent of the BLT
  371. int DstYE, // y extent of the BLT
  372. LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source
  373. LPVOID lpSrc, // --> to source bits
  374. int SrcX, // Source origin - x coordinate
  375. int SrcY, // Source origin - y coordinate
  376. LPVOID lpDitherTable) // dither table.
  377. {
  378. int x,y;
  379. int r,g,b;
  380. UINT wWidthSrc;
  381. UINT wWidthDst;
  382. BYTE _huge *pbS;
  383. BYTE _huge *pbD;
  384. if (biDst->biBitCount != 8 || biSrc->biBitCount != 24)
  385. return;
  386. DstXE &= ~3;
  387. wWidthSrc = ((UINT)biSrc->biWidth*3+3)&~3;
  388. wWidthDst = ((UINT)biDst->biWidth+3)&~3;
  389. pbD = (BYTE _huge *)lpDst + DstX + (DWORD)(UINT)DstY * (DWORD)wWidthDst;
  390. pbS = (BYTE _huge *)lpSrc + SrcX*3 + (DWORD)(UINT)SrcY * (DWORD)wWidthSrc;
  391. wWidthSrc -= DstXE*3;
  392. wWidthDst -= DstXE;
  393. #define GET24() \
  394. b = (int)*pbS++; \
  395. g = (int)*pbS++; \
  396. r = (int)*pbS++;
  397. #define DITHER24(mr, mg, mb) \
  398. GET24(); *pbD++ = (BYTE)lookup775[ rdith775[r + mr] + gdith775[g + mg] + ((b + mb) >> 6) ];
  399. for (y=0; y<DstYE; y++) {
  400. switch (y & 3) {
  401. case 0:
  402. for (x=0; x<DstXE; x+=4)
  403. {
  404. DITHER24( 1, 1, 2);
  405. DITHER24( 17, 17, 26);
  406. DITHER24( 25, 25, 38);
  407. DITHER24( 41, 41, 62);
  408. }
  409. break;
  410. case 1:
  411. for (x=0; x<DstXE; x+=4)
  412. {
  413. DITHER24( 31, 31, 46);
  414. DITHER24( 36, 36, 54);
  415. DITHER24( 7, 7, 10);
  416. DITHER24( 12, 12, 18);
  417. }
  418. break;
  419. case 2:
  420. for (x=0; x<DstXE; x+=4)
  421. {
  422. DITHER24( 20, 20, 30);
  423. DITHER24( 4, 4, 6);
  424. DITHER24( 39, 39, 58);
  425. DITHER24( 23, 23, 34);
  426. }
  427. break;
  428. case 3:
  429. for (x=0; x<DstXE; x+=4)
  430. {
  431. DITHER24( 33, 33, 50);
  432. DITHER24( 28, 28, 42);
  433. DITHER24( 15, 15, 22);
  434. DITHER24( 9, 9, 14);
  435. }
  436. break;
  437. } /*switch*/
  438. pbS += wWidthSrc;
  439. pbD += wWidthDst;
  440. }
  441. }
  442. //////////////////////////////////////////////////////////////////////////////
  443. //
  444. // Dither32C - dither from 32 to 8 using the Table method in 'C' Code
  445. //
  446. //////////////////////////////////////////////////////////////////////////////
  447. void FAR PASCAL Dither32C(
  448. LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest
  449. LPVOID lpDst, // --> to destination bits
  450. int DstX, // Destination origin - x coordinate
  451. int DstY, // Destination origin - y coordinate
  452. int DstXE, // x extent of the BLT
  453. int DstYE, // y extent of the BLT
  454. LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source
  455. LPVOID lpSrc, // --> to source bits
  456. int SrcX, // Source origin - x coordinate
  457. int SrcY, // Source origin - y coordinate
  458. LPVOID lpDitherTable) // dither table.
  459. {
  460. int x,y;
  461. int r,g,b;
  462. UINT wWidthSrc;
  463. UINT wWidthDst;
  464. BYTE _huge *pbS;
  465. BYTE _huge *pbD;
  466. if (biDst->biBitCount != 8 || biSrc->biBitCount != 32)
  467. return;
  468. DstXE &= ~3;
  469. wWidthSrc = ((UINT)biSrc->biWidth*4+3)&~3;
  470. wWidthDst = ((UINT)biDst->biWidth+3)&~3;
  471. pbD = (BYTE _huge *)lpDst + DstX + (DWORD)(UINT)DstY * (DWORD)wWidthDst;
  472. pbS = (BYTE _huge *)lpSrc + SrcX*4 + (DWORD)(UINT)SrcY * (DWORD)wWidthSrc;
  473. wWidthSrc -= DstXE*4;
  474. wWidthDst -= DstXE;
  475. #define GET32() \
  476. b = (int)*pbS++; \
  477. g = (int)*pbS++; \
  478. r = (int)*pbS++; \
  479. pbS++;
  480. #define DITHER32(mr, mg, mb) \
  481. GET32(); *pbD++ = (BYTE)lookup775[ rdith775[r + mr] + gdith775[g + mg] + ((b + mb) >> 6) ];
  482. for (y=0; y<DstYE; y++) {
  483. switch (y & 3) {
  484. case 0:
  485. for (x=0; x<DstXE; x+=4)
  486. {
  487. DITHER32( 1, 1, 2);
  488. DITHER32( 17, 17, 26);
  489. DITHER32( 25, 25, 38);
  490. DITHER32( 41, 41, 62);
  491. }
  492. break;
  493. case 1:
  494. for (x=0; x<DstXE; x+=4)
  495. {
  496. DITHER32( 31, 31, 46);
  497. DITHER32( 36, 36, 54);
  498. DITHER32( 7, 7, 10);
  499. DITHER32( 12, 12, 18);
  500. }
  501. break;
  502. case 2:
  503. for (x=0; x<DstXE; x+=4)
  504. {
  505. DITHER32( 20, 20, 30);
  506. DITHER32( 4, 4, 6);
  507. DITHER32( 39, 39, 58);
  508. DITHER32( 23, 23, 34);
  509. }
  510. break;
  511. case 3:
  512. for (x=0; x<DstXE; x+=4)
  513. {
  514. DITHER32( 33, 33, 50);
  515. DITHER32( 28, 28, 42);
  516. DITHER32( 15, 15, 22);
  517. DITHER32( 9, 9, 14);
  518. }
  519. break;
  520. } /*switch*/
  521. pbS += wWidthSrc;
  522. pbD += wWidthDst;
  523. }
  524. }
  525. //////////////////////////////////////////////////////////////////////////////
  526. //
  527. // Dither16TC - dither from 16 to 8 using the Table method in 'C' Code
  528. //
  529. //////////////////////////////////////////////////////////////////////////////
  530. void FAR PASCAL Dither16C(
  531. LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest
  532. LPVOID lpDst, // --> to destination bits
  533. int DstX, // Destination origin - x coordinate
  534. int DstY, // Destination origin - y coordinate
  535. int DstXE, // x extent of the BLT
  536. int DstYE, // y extent of the BLT
  537. LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source
  538. LPVOID lpSrc, // --> to source bits
  539. int SrcX, // Source origin - x coordinate
  540. int SrcY, // Source origin - y coordinate
  541. LPVOID lpDitherTable) // dither table.
  542. {
  543. int x,y;
  544. int r,g,b;
  545. WORD w;
  546. UINT wWidthSrc;
  547. UINT wWidthDst;
  548. BYTE _huge *pbS;
  549. BYTE _huge *pbD;
  550. if (biDst->biBitCount != 8 || biSrc->biBitCount != 16)
  551. return;
  552. DstXE = DstXE & ~3; // round down!
  553. wWidthSrc = ((UINT)biSrc->biWidth*2+3)&~3;
  554. wWidthDst = ((UINT)biDst->biWidth+3)&~3;
  555. pbD = (BYTE _huge *)lpDst + DstX + (DWORD)(UINT)DstY * (DWORD)wWidthDst;
  556. pbS = (BYTE _huge *)lpSrc + SrcX*2 + (DWORD)(UINT)SrcY * (DWORD)wWidthSrc;
  557. wWidthSrc -= DstXE*2;
  558. wWidthDst -= DstXE;
  559. #define GET16() \
  560. w = *((WORD _huge *)pbS)++; \
  561. r = (int)((w >> 7) & 0xF8); \
  562. g = (int)((w >> 2) & 0xF8); \
  563. b = (int)((w << 3) & 0xF8);
  564. #define DITHER16(mr, mg, mb) \
  565. GET16(); *pbD++ = (BYTE)lookup775[ rdith775[r + mr] + gdith775[g + mg] + ((b + mb) >> 6)];
  566. for (y=0; y<DstYE; y++) {
  567. switch (y & 3) {
  568. case 0:
  569. for (x=0; x<DstXE; x+=4)
  570. {
  571. DITHER16( 1, 1, 2);
  572. DITHER16( 17, 17, 26);
  573. DITHER16( 25, 25, 38);
  574. DITHER16( 41, 41, 62);
  575. }
  576. break;
  577. case 1:
  578. for (x=0; x<DstXE; x+=4)
  579. {
  580. DITHER16( 31, 31, 46);
  581. DITHER16( 36, 36, 54);
  582. DITHER16( 7, 7, 10);
  583. DITHER16( 12, 12, 18);
  584. }
  585. break;
  586. case 2:
  587. for (x=0; x<DstXE; x+=4)
  588. {
  589. DITHER16( 20, 20, 30);
  590. DITHER16( 4, 4, 6);
  591. DITHER16( 39, 39, 58);
  592. DITHER16( 23, 23, 34);
  593. }
  594. break;
  595. case 3:
  596. for (x=0; x<DstXE; x+=4)
  597. {
  598. DITHER16( 33, 33, 50);
  599. DITHER16( 28, 28, 42);
  600. DITHER16( 15, 15, 22);
  601. DITHER16( 9, 9, 14);
  602. }
  603. break;
  604. } /*switch*/
  605. pbS += wWidthSrc;
  606. pbD += wWidthDst;
  607. }
  608. }
  609. //////////////////////////////////////////////////////////////////////////////
  610. //
  611. //////////////////////////////////////////////////////////////////////////////
  612. #if 0
  613. //
  614. // this is the original code
  615. //
  616. //
  617. void Dith775ScanLine(Rbuf, Gbuf, Bbuf, n, row, paloffset)
  618. DWORD n; // pixels per row
  619. int *Rbuf, *Gbuf, *Bbuf;
  620. int row; // distance from top of image
  621. WORD *paloffset;
  622. {
  623. int i;
  624. // DITHER(x,y,rgb)
  625. switch (row & 3)
  626. {
  627. case 0:
  628. for (i=0; i<n; i+=4)
  629. {
  630. paloffset[i] = lookup775[ rdith775[Rbuf[i] + 1] + gdith775[Gbuf[i] + 1] + ((Bbuf[i] + 2) >> 6) ];
  631. paloffset[i+1] = lookup775[ rdith775[Rbuf[i+1] + 17] + gdith775[Gbuf[i+1] + 17] + ((Bbuf[i+1] + 26) >> 6) ];
  632. paloffset[i+2] = lookup775[ rdith775[Rbuf[i+2] + 25] + gdith775[Gbuf[i+2] + 25] + ((Bbuf[i+2] + 38) >> 6) ];
  633. paloffset[i+3] = lookup775[ rdith775[Rbuf[i+3] + 41] + gdith775[Gbuf[i+3] + 41] + ((Bbuf[i+3] + 62) >> 6) ];
  634. }
  635. break;
  636. case 1:
  637. for (i=0; i<n; i+=4)
  638. {
  639. paloffset[i] = lookup775[ rdith775[Rbuf[i] + 31] + gdith775[Gbuf[i] + 31] + ((Bbuf[i] + 46) >> 6) ];
  640. paloffset[i+1] = lookup775[ rdith775[Rbuf[i+1] + 36] + gdith775[Gbuf[i+1] + 36] + ((Bbuf[i+1] + 54) >> 6) ];
  641. paloffset[i+2] = lookup775[ rdith775[Rbuf[i+2] + 7] + gdith775[Gbuf[i+2] + 7] + ((Bbuf[i+2] + 10) >> 6) ];
  642. paloffset[i+3] = lookup775[ rdith775[Rbuf[i+3] + 12] + gdith775[Gbuf[i+3] + 12] + ((Bbuf[i+3] + 18) >> 6) ];
  643. }
  644. break;
  645. case 2:
  646. for (i=0; i<n; i+=4)
  647. {
  648. paloffset[i] = lookup775[ rdith775[Rbuf[i] + 20] + gdith775[Gbuf[i] + 20] + ((Bbuf[i] + 30) >> 6) ];
  649. paloffset[i+1] = lookup775[ rdith775[Rbuf[i+1] + 4] + gdith775[Gbuf[i+1] + 4] + ((Bbuf[i+1] + 6) >> 6) ];
  650. paloffset[i+2] = lookup775[ rdith775[Rbuf[i+2] + 39] + gdith775[Gbuf[i+2] + 39] + ((Bbuf[i+2] + 58) >> 6) ];
  651. paloffset[i+3] = lookup775[ rdith775[Rbuf[i+3] + 23] + gdith775[Gbuf[i+3] + 23] + ((Bbuf[i+3] + 34) >> 6) ];
  652. }
  653. break;
  654. case 3:
  655. for (i=0; i<n; i+=4)
  656. {
  657. paloffset[i] = lookup775[ rdith775[Rbuf[i] + 33] + gdith775[Gbuf[i] + 33] + ((Bbuf[i] + 50) >> 6) ];
  658. paloffset[i+1] = lookup775[ rdith775[Rbuf[i+1] + 28] + gdith775[Gbuf[i+1] + 28] + ((Bbuf[i+1] + 42) >> 6) ];
  659. paloffset[i+2] = lookup775[ rdith775[Rbuf[i+2] + 15] + gdith775[Gbuf[i+2] + 15] + ((Bbuf[i+2] + 22) >> 6) ];
  660. paloffset[i+3] = lookup775[ rdith775[Rbuf[i+3] + 9] + gdith775[Gbuf[i+3] + 9] + ((Bbuf[i+3] + 14) >> 6) ];
  661. }
  662. break;
  663. } /*switch*/
  664. }
  665. #endif
  666. #if 0
  667. {
  668. HPALETTE hpalT;
  669. HWND hwnd;
  670. BYTE xlat[256];
  671. int fh;
  672. static BOOL fHack = TRUE;
  673. OFSTRUCT of;
  674. char buf[80];
  675. //
  676. // convert palette to a palette that mappes 1:1 to the system
  677. // palette, this will allow us to draw faster
  678. //
  679. hwnd = GetActiveWindow();
  680. hdc = GetDC(hwnd);
  681. if (fHack && (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE))
  682. {
  683. fHack = FALSE;
  684. for (i=0; i<(int)pal.palNumEntries; i++)
  685. {
  686. pal.palPalEntry[i].peRed = (BYTE)0;
  687. pal.palPalEntry[i].peGreen = (BYTE)0;
  688. pal.palPalEntry[i].peBlue = (BYTE)0;
  689. pal.palPalEntry[i].peFlags = (BYTE)PC_RESERVED;
  690. }
  691. hpalT = CreatePalette((LPLOGPALETTE)&pal);
  692. hpalT = SelectPalette(hdc, hpalT, FALSE);
  693. RealizePalette(hdc);
  694. hpalT = SelectPalette(hdc, hpalT, FALSE);
  695. DeleteObject(hpalT);
  696. hpalT = SelectPalette(hdc, hpal, FALSE);
  697. RealizePalette(hdc);
  698. GetSystemPaletteEntries(hdc, 0, 256, pal.palPalEntry);
  699. SelectPalette(hdc, hpalT, FALSE);
  700. PostMessage(hwnd, WM_QUERYNEWPALETTE, 0, 0);
  701. for (i=0; i<256; i++)
  702. {
  703. // this wont work right for dup's in the palette
  704. j = GetNearestPaletteIndex(hpal,RGB(pal.palPalEntry[i].peRed,
  705. pal.palPalEntry[i].peGreen,pal.palPalEntry[i].peBlue));
  706. xlat[j] = (BYTE)i;
  707. }
  708. SetPaletteEntries(hpal, 0, 256, pal.palPalEntry);
  709. for (i=0; i < sizeof(lookup775)/sizeof(lookup775[0]); i++)
  710. lookup775[i] = xlat[lookup775[i]];
  711. //
  712. // dump the new palette and lookup table out.
  713. //
  714. fh = OpenFile("c:/foo775.h", &of, OF_CREATE|OF_READWRITE);
  715. if (fh != -1)
  716. {
  717. wsprintf(buf, "BYTE lookup775[245] = {\r\n");
  718. _lwrite(fh, buf, lstrlen(buf));
  719. for (i=0; i < sizeof(lookup775)/sizeof(lookup775[0]); i++) {
  720. wsprintf(buf, "%3d,", lookup775[i]);
  721. if (i % 16 == 0 && i != 0)
  722. _lwrite(fh, "\r\n", 2);
  723. _lwrite(fh, buf, lstrlen(buf));
  724. }
  725. wsprintf(buf, "}\r\n\r\nint dpal775[256][3] = {\r\n");
  726. _lwrite(fh, buf, lstrlen(buf));
  727. for (i=0; i < 256; i++) {
  728. wsprintf(buf, "{0x%02x, 0x%02x, 0x%02x},",
  729. pal.palPalEntry[i].peRed,
  730. pal.palPalEntry[i].peGreen,
  731. pal.palPalEntry[i].peBlue);
  732. if (i % 4 == 0 && i != 0)
  733. _lwrite(fh, "\r\n", 2);
  734. _lwrite(fh, buf, lstrlen(buf));
  735. }
  736. wsprintf(buf, "}\r\n");
  737. _lwrite(fh, buf, lstrlen(buf));
  738. _lclose(fh);
  739. }
  740. }
  741. ReleaseDC(hwnd, hdc);
  742. }
  743. #endif