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.

1247 lines
35 KiB

  1. /**************************************************************************
  2. *
  3. * SETDI.C - contains routines for doing a SetDIBits() into a bitmap.
  4. *
  5. **************************************************************************/
  6. #include <windows.h>
  7. #include <windowsx.h>
  8. #include "lockbm.h"
  9. #include "setdi.h"
  10. #define NAKED
  11. /**************************************************************************
  12. *
  13. * format conversion functions.
  14. *
  15. * special functions....
  16. * copy_8_8 (no translate)
  17. * dither_8_8 (dither from 8bpp to fixed color device (like VGA, SVGA...)
  18. *
  19. **************************************************************************/
  20. extern CONVERTPROC copy_8_8, dither_8_8;
  21. extern CONVERTPROC convert_8_8, convert_8_16, convert_8_24, convert_8_32, convert_8_VGA, convert_8_565, convert_8_RGB, convert_8_RGBX;
  22. extern CONVERTPROC convert_16_8, convert_16_16, convert_16_24, convert_16_32, convert_16_VGA, convert_16_565, convert_16_RGB, convert_16_RGBX;
  23. extern CONVERTPROC convert_24_8, convert_24_16, convert_24_24, convert_24_32, convert_24_VGA, convert_24_565, convert_24_RGB, convert_24_RGBX;
  24. extern CONVERTPROC convert_32_8, convert_32_16, convert_32_24, convert_32_32, convert_32_VGA, convert_32_565, convert_32_RGB, convert_32_RGBX;
  25. static INITPROC init_8_8, init_8_16, init_8_24, init_8_32, init_8_VGA, init_8_565, init_8_RGB, init_8_RGBX;
  26. static INITPROC init_16_8, init_16_16, init_16_24, init_16_32, init_16_VGA, init_16_565, init_16_RGB, init_16_RGBX;
  27. static INITPROC init_24_8, init_24_16, init_24_24, init_24_32, init_24_VGA, init_24_565, init_24_RGB, init_24_RGBX;
  28. static INITPROC init_32_8, init_32_16, init_32_24, init_32_32, init_32_VGA, init_32_565, init_32_RGB, init_32_RGBX;
  29. INITPROC init_setdi;
  30. static CONVERTPROC convert_setdi;
  31. static FREEPROC free_common;
  32. static LPVOID init_dither_8_8(HDC hdc, LPBITMAPINFOHEADER lpbi);
  33. /**************************************************************************
  34. *
  35. * some conversions we dont do
  36. *
  37. **************************************************************************/
  38. #define convert_8_VGA NULL
  39. #define convert_16_VGA NULL
  40. #define convert_24_VGA NULL
  41. #define convert_32_VGA NULL
  42. #define convert_8_32 NULL
  43. #define convert_16_32 NULL
  44. #define convert_24_32 NULL
  45. #define convert_32_32 NULL
  46. #define convert_8_RGBX NULL
  47. #define convert_16_RGBX NULL
  48. #define convert_24_RGBX NULL
  49. #define convert_32_RGBX NULL
  50. #define convert_8_RGB NULL
  51. #define convert_16_RGB NULL
  52. #define convert_24_RGB NULL
  53. #define convert_32_RGB NULL
  54. #define convert_16_8 NULL // not now later!
  55. #define convert_24_8 NULL
  56. #define convert_32_8 NULL
  57. /**************************************************************************
  58. *
  59. * format conversion tables...
  60. *
  61. * BITMAP types
  62. *
  63. * 8 0
  64. * 16 1
  65. * 24 2
  66. * 32 3
  67. * VGA 4
  68. * 16 565 5
  69. * 24 RGB 6
  70. * 32 RGB 7
  71. *
  72. **************************************************************************/
  73. static PCONVERTPROC ConvertProcTable[4][8] = {
  74. {convert_8_8, convert_8_16, convert_8_24, convert_8_32, convert_8_VGA, convert_8_565, convert_8_RGB, convert_8_RGBX},
  75. {convert_16_8, convert_16_16, convert_16_24, convert_16_32, convert_16_VGA, convert_16_565, convert_16_RGB, convert_16_RGBX},
  76. {convert_24_8, convert_24_16, convert_24_24, convert_24_32, convert_24_VGA, convert_24_565, convert_24_RGB, convert_24_RGBX},
  77. {convert_32_8, convert_32_16, convert_32_24, convert_32_32, convert_32_VGA, convert_32_565, convert_32_RGB, convert_32_RGBX},
  78. };
  79. static PINITPROC InitProcTable[4][8] = {
  80. {init_8_8, init_8_16, init_8_24, init_8_32, init_8_VGA, init_8_565, init_8_RGB, init_8_RGBX},
  81. {init_16_8, init_16_16, init_16_24, init_16_32, init_16_VGA, init_16_565, init_16_RGB, init_16_RGBX},
  82. {init_24_8, init_24_16, init_24_24, init_24_32, init_24_VGA, init_24_565, init_24_RGB, init_24_RGBX},
  83. {init_32_8, init_32_16, init_32_24, init_32_32, init_32_VGA, init_32_565, init_32_RGB, init_32_RGBX},
  84. };
  85. /**************************************************************************
  86. **************************************************************************/
  87. #define RGB555(r,g,b) (\
  88. (((WORD)(r) >> 3) << 10) | \
  89. (((WORD)(g) >> 3) << 5) | \
  90. (((WORD)(b) >> 3) << 0) )
  91. #define RGB565(r,g,b) (\
  92. (((WORD)(r) >> 3) << 11) | \
  93. (((WORD)(g) >> 2) << 5) | \
  94. (((WORD)(b) >> 3) << 0) )
  95. /**************************************************************************
  96. **************************************************************************/
  97. #ifdef DEBUG
  98. static
  99. #else
  100. __inline
  101. #endif
  102. LONG BitmapXY(IBITMAP *pbm, int x, int y)
  103. {
  104. LONG offset = pbm->bmOffset;
  105. //!!! wrong!!! but y for bitmaps is always zero....
  106. // if (pbm->bmFillBytes)
  107. // offset += (y / pbm->bmScanSegment) * pbm->bmFillBytes;
  108. offset += y * (long)pbm->bmNextScan;
  109. offset += x * pbm->bmBitsPixel / 8;
  110. return offset;
  111. }
  112. /**************************************************************************
  113. * @doc INTERNAL SetBitmapBegin
  114. *
  115. * @api BOOL | SetBitmapBegin | prepare to do a SetDIBits() into a bitmap
  116. *
  117. * @rdesc Returns TRUE if success.
  118. *
  119. **************************************************************************/
  120. BOOL FAR SetBitmapBegin(
  121. PSETDI psd,
  122. HDC hdc, //
  123. HBITMAP hbm, // bitmap to set into
  124. LPBITMAPINFOHEADER lpbi, // --> BITMAPINFO of source
  125. UINT DibUsage)
  126. {
  127. BITMAP bm;
  128. SetBitmapEnd(psd); // free and old stuff
  129. GetObject(hbm, sizeof(bm), &bm);
  130. psd->hbm = hbm;
  131. // psd->hdc = hdc;
  132. // psd->hpal = hpal;
  133. psd->DibUsage= DibUsage;
  134. psd->color_convert = NULL;
  135. psd->convert = NULL;
  136. psd->size = sizeof(SETDI);
  137. if (!GetBitmapDIB(lpbi, NULL, &psd->bmSrc, sizeof(psd->bmSrc)))
  138. return FALSE;
  139. //
  140. // make sure we can lock the bitmap
  141. //
  142. if (GetBitmap(hbm, &psd->bmDst, sizeof(psd->bmDst)) &&
  143. psd->bmDst.bmFillBytes <= 0 &&
  144. psd->bmSrc.bmType > 0 && psd->bmSrc.bmType <= 4 &&
  145. psd->bmDst.bmType > 0 && psd->bmDst.bmType <= 8)
  146. {
  147. psd->init = InitProcTable[psd->bmSrc.bmType-1][psd->bmDst.bmType-1];
  148. psd->convert = ConvertProcTable[psd->bmSrc.bmType-1][psd->bmDst.bmType-1];
  149. psd->free = free_common;
  150. }
  151. //
  152. // if we cant convert ourself try SetDIBits()
  153. //
  154. if (psd->convert == NULL)
  155. {
  156. psd->convert = convert_setdi;
  157. psd->init = init_setdi;
  158. psd->free = NULL;
  159. }
  160. if (psd->init)
  161. {
  162. psd->hdc = hdc;
  163. if (!psd->init(psd))
  164. {
  165. psd->hdc = 0;
  166. psd->size = 0;
  167. psd->convert = NULL;
  168. return FALSE;
  169. }
  170. psd->hdc = NULL;
  171. psd->hpal = NULL;
  172. }
  173. return TRUE;
  174. }
  175. /**************************************************************************
  176. * @doc INTERNAL SetBitmapColorChange
  177. *
  178. * @api BOOL | SetBitmapColorChange | re-init the color conversion
  179. *
  180. * @rdesc Returns TRUE if success.
  181. *
  182. **************************************************************************/
  183. void FAR SetBitmapColorChange(PSETDI psd, HDC hdc, HPALETTE hpal)
  184. {
  185. if (psd->size != sizeof(SETDI))
  186. return;
  187. if (hdc == NULL)
  188. return;
  189. if (psd->free) //!!! ack?
  190. psd->free(psd);
  191. psd->hdc = hdc;
  192. psd->hpal = hpal;
  193. if (psd->init)
  194. psd->init(psd);
  195. psd->hdc = NULL;
  196. psd->hpal = NULL;
  197. }
  198. /**************************************************************************
  199. * @doc INTERNAL SetBitmapEnd
  200. *
  201. * @api void | SetBitmapEnd | clean out a SETDI structure
  202. *
  203. **************************************************************************/
  204. void FAR SetBitmapEnd(PSETDI psd)
  205. {
  206. if (psd->size != sizeof(SETDI))
  207. return;
  208. if (psd->free)
  209. psd->free(psd);
  210. psd->size = 0;
  211. psd->convert = NULL;
  212. psd->init = NULL;
  213. psd->free = NULL;
  214. }
  215. /**************************************************************************
  216. * @doc INTERNAL SetBitmap
  217. *
  218. * @api BOOL | SetBitmap | convert DIB bits to bitmaps bits.
  219. *
  220. **************************************************************************/
  221. BOOL FAR SetBitmap(PSETDI psd, int DstX, int DstY, int DstDX, int DstDY, LPVOID lpBits, int SrcX, int SrcY, int SrcDX, int SrcDY)
  222. {
  223. if (psd->size != sizeof(SETDI))
  224. return FALSE;
  225. psd->convert(
  226. psd->bmDst.bmBits, // --> dst.
  227. BitmapXY(&psd->bmDst, DstX, DstY), // offset to start at
  228. psd->bmDst.bmNextScan, // dst_next_scan.
  229. psd->bmDst.bmFillBytes, // fill bytes
  230. lpBits, // --> Src.
  231. BitmapXY(&psd->bmSrc, SrcX, SrcY), // offset to start at
  232. psd->bmSrc.bmNextScan, // Src_next_scan.
  233. DstDX,
  234. DstDY,
  235. psd->color_convert);
  236. return TRUE;
  237. }
  238. /**************************************************************************
  239. *
  240. * cleanup stuff
  241. *
  242. **************************************************************************/
  243. static BOOL free_common(PSETDI psd)
  244. {
  245. //
  246. // clean up what we did
  247. //
  248. if (psd->color_convert != NULL)
  249. GlobalFreePtr(psd->color_convert);
  250. psd->color_convert = NULL;
  251. return TRUE;
  252. }
  253. /**************************************************************************
  254. *
  255. * GetPaletteTranslate
  256. *
  257. * get the palette to physical translate table.
  258. *
  259. * does this by calling GDI, this should always work.
  260. * this only works on a palette device.
  261. *
  262. **************************************************************************/
  263. BOOL GetPaletteTranslate(HDC hdc, LPBYTE pb)
  264. {
  265. int i;
  266. int n;
  267. DWORD rgb;
  268. DWORD *prgb;
  269. prgb = (DWORD *)LocalAlloc(LPTR, 256 * sizeof(DWORD));
  270. if (prgb == NULL)
  271. return TRUE;
  272. GetSystemPaletteEntries(hdc, 0, 256,(PALETTEENTRY FAR *)prgb);
  273. for (n=0; n<256; n++) //!!! is this needed.
  274. prgb[n] &= 0x00FFFFFF;
  275. for (i=0; i<256; i++)
  276. {
  277. //
  278. // GDI will figure out what physical color this palette
  279. // index is mapped to.
  280. //
  281. rgb = GetNearestColor(hdc, PALETTEINDEX(i)) & 0x00FFFFFF;
  282. //
  283. // quick check for identity map.
  284. //
  285. if (prgb[i] == rgb)
  286. {
  287. pb[i] = (BYTE)i;
  288. continue;
  289. }
  290. //
  291. // now we have to find the rgb in the physical palette
  292. //
  293. for (n=0; n<256; n++)
  294. if (prgb[n] == rgb)
  295. break;
  296. //
  297. // our search should never fail, because GDI gave us a RGB
  298. // in the palette.
  299. //
  300. if (n == 256) //!!! should never happen
  301. n = 0;
  302. pb[i] = (BYTE)n;
  303. }
  304. LocalFree((HLOCAL)prgb);
  305. return TRUE;
  306. }
  307. /**************************************************************************
  308. *
  309. * @doc INTERNAL GetPaletteMap
  310. *
  311. * @api BOOL | GetPhysPaletteMap | gets the physical mapping for a DIB
  312. *
  313. * returns TRUE if the mapping is a 1:1 mapping, FALSE otherwise
  314. *
  315. **************************************************************************/
  316. BOOL GetPhysDibPaletteMap(HDC hdc, LPBITMAPINFOHEADER lpbi, UINT Usage, LPBYTE pb)
  317. {
  318. int i;
  319. int n;
  320. BYTE ab[256];
  321. //
  322. // this will give us the palette to physical mapping.
  323. //
  324. GetPaletteTranslate(hdc, ab);
  325. if (Usage == DIB_PAL_COLORS)
  326. {
  327. WORD FAR *pw = (WORD FAR *)(lpbi+1);
  328. for (i=0; i<256; i++)
  329. pb[i] = ab[pw[i]];
  330. }
  331. else
  332. {
  333. ; //!!! should never happen with current code
  334. }
  335. //
  336. // test for 1:1 translate
  337. //
  338. n = (int)lpbi->biClrUsed ? (int)lpbi->biClrUsed : 256;
  339. for (i=0; i<n; i++)
  340. {
  341. if (pb[i] != i)
  342. {
  343. //
  344. // some ET4000 drivers have the same color (128,128,128)
  345. // at index 7 and at index 248.
  346. //
  347. // we should detect a identity palette in this case.
  348. //
  349. if (i == 248 && pb[i] == 7)
  350. {
  351. pb[i] = 248;
  352. continue;
  353. }
  354. break;
  355. }
  356. }
  357. return i == n;
  358. }
  359. /**************************************************************************
  360. *
  361. * @doc INTERNAL
  362. *
  363. * @api void | GetDibPaletteMap | gets the mapping of a DIB color table
  364. * in foreground palette index's
  365. *
  366. **************************************************************************/
  367. BOOL GetDibPaletteMap(HDC hdc, LPBITMAPINFOHEADER lpbi, UINT Usage, LPBYTE pb)
  368. {
  369. HBITMAP hbm;
  370. int i;
  371. int n;
  372. LONG biWidth = lpbi->biWidth;
  373. LONG biHeight = lpbi->biHeight;
  374. n = (int)lpbi->biClrUsed ? (int)lpbi->biClrUsed : 256;
  375. for (i=0; i<n; i++)
  376. pb[i] = i;
  377. for (; i<256; i++)
  378. pb[i] = 0;
  379. if (lpbi->biBitCount != 8)
  380. return FALSE;
  381. hbm = CreateCompatibleBitmap(hdc,256,1);
  382. lpbi->biWidth = 256;
  383. lpbi->biHeight = 1;
  384. SetDIBits(hdc, hbm, 0, 1, pb, (LPBITMAPINFO)lpbi, Usage);
  385. GetBitmapBits(hbm, 256, pb);
  386. DeleteObject(hbm);
  387. lpbi->biWidth = biWidth;
  388. lpbi->biHeight = biHeight;
  389. //
  390. // test for 1:1 translate
  391. //
  392. for (i=0; i<n; i++)
  393. {
  394. if (pb[i] != i)
  395. {
  396. //
  397. // some ET4000 drivers have the same color (128,128,128)
  398. // at index 7 and at index 248.
  399. //
  400. // we should detect a identity palette in this case.
  401. //
  402. if (i == 248 && pb[i] == 7)
  403. {
  404. pb[i] = 248;
  405. continue;
  406. }
  407. break;
  408. }
  409. }
  410. return i == n;
  411. }
  412. /**************************************************************************
  413. *
  414. * convert for SetDIBits
  415. *
  416. **************************************************************************/
  417. void FAR PASCAL convert_setdi(
  418. LPVOID pd, // --> dst.
  419. LONG dd, // offset to start at
  420. LONG nd, // dst_next_scan.
  421. LONG fd, // dst fill bytes
  422. LPVOID ps, // --> source.
  423. LONG ds, // offset to start at
  424. LONG ns, // src_next_scan.
  425. LONG dx, // pixel count.
  426. LONG dy, // scan count.
  427. LPVOID pc) // pixel convert table.
  428. {
  429. PSETDI psd = (PSETDI)(LONG)pd;
  430. LPBITMAPINFOHEADER lpbi;
  431. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  432. lpbi->biHeight = dy;
  433. SetDIBits(
  434. psd->hdc,
  435. psd->hbm,
  436. 0,(int)dy,
  437. ((BYTE _huge *)ps) + ds - dd,
  438. (LPBITMAPINFO)lpbi,
  439. psd->DibUsage);
  440. lpbi->biHeight = psd->bmSrc.bmHeight;
  441. }
  442. /**************************************************************************
  443. *
  444. * init stuff for SetDIBits
  445. *
  446. **************************************************************************/
  447. BOOL init_setdi(PSETDI psd)
  448. {
  449. UINT u;
  450. HDC hdc;
  451. LPBYTE p;
  452. LPBITMAPINFOHEADER lpbi;
  453. // test to see if SetDIBits() works.
  454. // !!! we should check for 16 or a 32bit DIB and do the escape.
  455. // !!! on a palette device we need to build a palette map!!!
  456. if (psd->bmSrc.bmBitsPixel == 16 ||
  457. psd->bmSrc.bmBitsPixel == 32)
  458. return FALSE;
  459. // convert_setdi will need this.
  460. psd->bmDst.bmBits = (LPVOID)(UINT)psd;
  461. psd->bmDst.bmOffset = 0;
  462. psd->bmDst.bmBitsPixel = psd->bmSrc.bmBitsPixel;
  463. if (psd->hdc && psd->hpal)
  464. {
  465. // map colors to current palette!!!!!!!!!!!!!!!!!!!!!!!!!!
  466. //set this to be the BITMAPINFO + color map.
  467. psd->color_convert = 0;
  468. }
  469. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  470. lpbi->biHeight = 1;
  471. p = (LPBYTE)GlobalAllocPtr(GHND,psd->bmSrc.bmWidthBytes);
  472. hdc = GetDC(NULL);
  473. u = SetDIBits(
  474. hdc,
  475. psd->hbm,0,1,p,
  476. (LPBITMAPINFO)psd->bmSrc.bmBitmapInfo,
  477. psd->DibUsage);
  478. ReleaseDC(NULL, hdc);
  479. lpbi->biHeight = psd->bmSrc.bmHeight;
  480. GlobalFreePtr(p);
  481. return u == 1;
  482. }
  483. /**************************************************************************
  484. *
  485. * init stuff for 8bpp bitmaps
  486. *
  487. **************************************************************************/
  488. static BOOL init_8_8(PSETDI psd)
  489. {
  490. LPBITMAPINFOHEADER lpbi;
  491. //
  492. // if we are mapping from one DIB to another figure this out
  493. //
  494. if (psd->hdc == NULL || psd->bmDst.bmBitmapInfo != 0)
  495. {
  496. // we assume this routine will not be used for color matching
  497. // from DIB to DIB, so give up.
  498. psd->convert = copy_8_8;
  499. return TRUE;
  500. }
  501. //
  502. // we are mapping to a device (HDC)
  503. //
  504. // we need to compute a 8-->8 conversion table, from the source colors
  505. // (in psd->lpbiSrc) to the colors on the device.
  506. //
  507. // how we do this depends on weather the device is a palette device or not.
  508. //
  509. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  510. if (GetDeviceCaps(psd->hdc, RASTERCAPS) & RC_PALETTE)
  511. {
  512. if (psd->hpal == NULL)
  513. {
  514. // no palette to match to yet
  515. psd->convert = copy_8_8;
  516. return TRUE;
  517. }
  518. if (psd->color_convert == NULL)
  519. psd->color_convert = GlobalAllocPtr(GHND, 256);
  520. //
  521. // we can do this one of two ways,
  522. //
  523. // we can always convert to the palette foreground mapping, or
  524. //
  525. // we can convert to the current colors always (using this method
  526. // we will need to recompute the xlat table on every palette
  527. // change)
  528. //
  529. // lets convert to the current device colors. (this may cause
  530. // problems we will check on later...)
  531. //
  532. #ifdef NAKED
  533. if (GetPhysDibPaletteMap(psd->hdc, lpbi, psd->DibUsage, psd->color_convert))
  534. #else
  535. if (GetDibPaletteMap(psd->hdc, lpbi, psd->DibUsage, psd->color_convert))
  536. #endif
  537. psd->convert = copy_8_8;
  538. else
  539. psd->convert = convert_8_8;
  540. }
  541. else
  542. {
  543. // !!!we should check for solid colors (ie no dither needed) and also
  544. // check for 1:1 (no translate)
  545. if (psd->color_convert == NULL) //!!!
  546. psd->color_convert = init_dither_8_8(psd->hdc, lpbi);
  547. psd->convert = dither_8_8;
  548. //!!! we need to give the device colors to the caller
  549. }
  550. return TRUE;
  551. }
  552. static BOOL init_16_8(PSETDI psd)
  553. {
  554. return FALSE; // we dont handle dither yet!
  555. }
  556. static BOOL init_24_8(PSETDI psd)
  557. {
  558. return FALSE; // we dont handle dither yet!
  559. }
  560. static BOOL init_32_8(PSETDI psd)
  561. {
  562. return FALSE; // we dont handle dither yet!
  563. }
  564. /**************************************************************************
  565. *
  566. * init stuff for 16bpp bitmaps
  567. *
  568. **************************************************************************/
  569. static BOOL init_8_16(PSETDI psd)
  570. {
  571. WORD FAR*pw;
  572. int i;
  573. int n;
  574. LPRGBQUAD prgb;
  575. LPBITMAPINFOHEADER lpbi;
  576. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  577. if (psd->color_convert == NULL) //!!!
  578. psd->color_convert = GlobalAllocPtr(GHND, 256*2);
  579. n = (lpbi->biClrUsed == 0) ? 256 : (int)lpbi->biClrUsed;
  580. prgb = (LPRGBQUAD)((LPBYTE)lpbi + (int)lpbi->biSize);
  581. pw = psd->color_convert;
  582. for (i=0; i<n; i++)
  583. pw[i] = RGB555(prgb[i].rgbRed, prgb[i].rgbGreen, prgb[i].rgbBlue);
  584. for (; i<256; i++)
  585. pw[i] = 0;
  586. return TRUE;
  587. }
  588. static BOOL init_16_16(PSETDI psd)
  589. {
  590. return TRUE;
  591. }
  592. static BOOL init_24_16(PSETDI psd)
  593. {
  594. return TRUE;
  595. }
  596. static BOOL init_32_16(PSETDI psd)
  597. {
  598. return TRUE;
  599. }
  600. /**************************************************************************
  601. *
  602. * init stuff for 24bpp bitmaps
  603. *
  604. **************************************************************************/
  605. static BOOL init_8_24(PSETDI psd)
  606. {
  607. DWORD FAR*pd;
  608. int i;
  609. int n;
  610. LPRGBQUAD prgb;
  611. LPBITMAPINFOHEADER lpbi;
  612. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  613. if (psd->color_convert == NULL) //!!!
  614. psd->color_convert = GlobalAllocPtr(GHND, 256*4);
  615. n = (lpbi->biClrUsed == 0) ? 256 : (int)lpbi->biClrUsed;
  616. prgb = (LPRGBQUAD)((LPBYTE)lpbi + (int)lpbi->biSize);
  617. pd = psd->color_convert;
  618. for (i=0; i<n; i++)
  619. pd[i] = RGB(prgb[i].rgbBlue, prgb[i].rgbGreen, prgb[i].rgbRed);
  620. for (; i<256; i++)
  621. pd[i] = 0;
  622. return TRUE;
  623. }
  624. static BOOL init_16_24(PSETDI psd)
  625. {
  626. return TRUE;
  627. }
  628. static BOOL init_24_24(PSETDI psd)
  629. {
  630. return TRUE;
  631. }
  632. static BOOL init_32_24(PSETDI psd)
  633. {
  634. return TRUE;
  635. }
  636. /**************************************************************************
  637. *
  638. * init stuff for 32bpp bitmaps
  639. *
  640. **************************************************************************/
  641. static BOOL init_8_32(PSETDI psd)
  642. {
  643. return FALSE;
  644. ////return init_8_24(psd);
  645. }
  646. static BOOL init_16_32(PSETDI psd)
  647. {
  648. return FALSE;
  649. }
  650. static BOOL init_24_32(PSETDI psd)
  651. {
  652. return FALSE;
  653. }
  654. static BOOL init_32_32(PSETDI psd)
  655. {
  656. return FALSE;
  657. }
  658. /**************************************************************************
  659. *
  660. * init stuff for VGA bitmaps
  661. *
  662. **************************************************************************/
  663. static BOOL init_8_VGA(PSETDI psd)
  664. {
  665. return FALSE;
  666. }
  667. static BOOL init_16_VGA(PSETDI psd)
  668. {
  669. return FALSE;
  670. }
  671. static BOOL init_24_VGA(PSETDI psd)
  672. {
  673. return FALSE;
  674. }
  675. static BOOL init_32_VGA(PSETDI psd)
  676. {
  677. return FALSE;
  678. }
  679. /**************************************************************************
  680. *
  681. * init stuff for RGB 565 bitmaps
  682. *
  683. **************************************************************************/
  684. static BOOL init_8_565(PSETDI psd)
  685. {
  686. WORD FAR*pw;
  687. int i;
  688. int n;
  689. LPRGBQUAD prgb;
  690. LPBITMAPINFOHEADER lpbi;
  691. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  692. if (psd->color_convert == NULL) //!!!
  693. psd->color_convert = GlobalAllocPtr(GHND, 256*2);
  694. n = (lpbi->biClrUsed == 0) ? 256 : (int)lpbi->biClrUsed;
  695. prgb = (LPRGBQUAD)((LPBYTE)lpbi + (int)lpbi->biSize);
  696. pw = psd->color_convert;
  697. for (i=0; i<n; i++)
  698. pw[i] = RGB565(prgb[i].rgbRed, prgb[i].rgbGreen, prgb[i].rgbBlue);
  699. for (; i<256; i++)
  700. pw[i] = 0;
  701. return TRUE;
  702. }
  703. static BOOL init_16_565(PSETDI psd)
  704. {
  705. return TRUE;
  706. }
  707. static BOOL init_24_565(PSETDI psd)
  708. {
  709. return TRUE;
  710. }
  711. static BOOL init_32_565(PSETDI psd)
  712. {
  713. return TRUE;
  714. }
  715. /**************************************************************************
  716. *
  717. * init stuff for RGB 24bpp bitmaps
  718. *
  719. **************************************************************************/
  720. static BOOL init_8_RGB(PSETDI psd)
  721. {
  722. DWORD FAR *pd;
  723. int i;
  724. int n;
  725. LPRGBQUAD prgb;
  726. LPBITMAPINFOHEADER lpbi;
  727. lpbi = (LPBITMAPINFOHEADER)psd->bmSrc.bmBitmapInfo;
  728. if (psd->color_convert == NULL) //!!!
  729. psd->color_convert = GlobalAllocPtr(GHND, 256*4);
  730. n = (lpbi->biClrUsed == 0) ? 256 : (int)lpbi->biClrUsed;
  731. prgb = (LPRGBQUAD)((LPBYTE)lpbi + (int)lpbi->biSize);
  732. pd = psd->color_convert;
  733. for (i=0; i<n; i++)
  734. pd[i] = RGB(prgb[i].rgbRed, prgb[i].rgbGreen, prgb[i].rgbBlue);
  735. for (; i<256; i++)
  736. pd[i] = 0;
  737. return TRUE;
  738. }
  739. static BOOL init_16_RGB(PSETDI psd)
  740. {
  741. return FALSE;
  742. }
  743. static BOOL init_24_RGB(PSETDI psd)
  744. {
  745. return FALSE;
  746. }
  747. static BOOL init_32_RGB(PSETDI psd)
  748. {
  749. return FALSE;
  750. }
  751. /**************************************************************************
  752. *
  753. * init stuff for RGB 32bpp bitmaps
  754. *
  755. **************************************************************************/
  756. static BOOL init_8_RGBX(PSETDI psd)
  757. {
  758. return init_8_RGB(psd);
  759. }
  760. static BOOL init_16_RGBX(PSETDI psd)
  761. {
  762. return FALSE;
  763. }
  764. static BOOL init_24_RGBX(PSETDI psd)
  765. {
  766. return FALSE;
  767. }
  768. static BOOL init_32_RGBX(PSETDI psd)
  769. {
  770. return FALSE;
  771. }
  772. /**************************************************************************
  773. *
  774. * init_dither_8_8
  775. *
  776. * initialize a dither table that maps a 8 bit color to the device's dither
  777. *
  778. * pel = dither_table[y&7][pel][x&7]
  779. *
  780. **************************************************************************/
  781. static LPVOID init_dither_8_8(HDC hdc, LPBITMAPINFOHEADER lpbi)
  782. {
  783. HBRUSH hbr;
  784. HDC hdcMem;
  785. // HDC hdc;
  786. HBITMAP hbm;
  787. HBITMAP hbmT;
  788. int i;
  789. int nColors;
  790. LPRGBQUAD prgb;
  791. LPVOID lpDitherTable;
  792. struct {
  793. BITMAPINFOHEADER bi;
  794. RGBQUAD rgb[256];
  795. } dib;
  796. lpDitherTable = GlobalAllocPtr(GHND, 256*8*8);
  797. if (lpDitherTable == NULL)
  798. return (LPVOID)-1;
  799. hdc = GetDC(NULL);
  800. hdcMem = CreateCompatibleDC(hdc);
  801. hbm = CreateCompatibleBitmap(hdc, 256*8, 8);
  802. hbmT = SelectObject(hdcMem, hbm);
  803. if ((nColors = (int)lpbi->biClrUsed) == 0)
  804. nColors = 1 << (int)lpbi->biBitCount;
  805. prgb = (LPRGBQUAD)(lpbi+1);
  806. for (i=0; i<nColors; i++)
  807. {
  808. hbr = CreateSolidBrush(RGB(prgb[i].rgbRed,prgb[i].rgbGreen,prgb[i].rgbBlue));
  809. hbr = SelectObject(hdcMem, hbr);
  810. PatBlt(hdcMem, i*8, 0, 8, 8, PATCOPY);
  811. hbr = SelectObject(hdcMem, hbr);
  812. DeleteObject(hbr);
  813. }
  814. #ifdef XDEBUG
  815. for (i=0; i<16; i++)
  816. BitBlt(hdc,0,i*8,16*8,8,hdcMem,i*(16*8),0,SRCCOPY);
  817. #endif
  818. dib.bi.biSize = sizeof(BITMAPINFOHEADER);
  819. dib.bi.biPlanes = 1;
  820. dib.bi.biBitCount = 8;
  821. dib.bi.biWidth = 256*8;
  822. dib.bi.biHeight = 8;
  823. dib.bi.biCompression = BI_RGB;
  824. dib.bi.biSizeImage = 256*8*8;
  825. dib.bi.biXPelsPerMeter = 0;
  826. dib.bi.biYPelsPerMeter = 0;
  827. dib.bi.biClrUsed = 0;
  828. dib.bi.biClrImportant = 0;
  829. GetDIBits(hdc, hbm, 0, 8, lpDitherTable, (LPBITMAPINFO)&dib, DIB_RGB_COLORS);
  830. SelectObject(hdcMem, hbmT);
  831. DeleteDC(hdcMem);
  832. DeleteObject(hbm);
  833. ReleaseDC(NULL, hdc);
  834. return (LPVOID)lpDitherTable;
  835. }
  836. #ifdef WIN32 // Provide some dummy entry points as a temporary measure for NT
  837. void FAR PASCAL convert_16_16
  838. (LPVOID pd, // --> dst.
  839. LONG dd, // offset to start at
  840. LONG nd, // dst_next_scan.
  841. LONG fd, // dst fill bytes
  842. LPVOID ps, // --> source.
  843. LONG ds, // offset to start at
  844. LONG ns, // src_next_scan.
  845. LONG dx, // pixel count.
  846. LONG dy, // scan count.
  847. LPVOID pc) // pixel convert table.
  848. {
  849. return;
  850. }
  851. void FAR PASCAL convert_16_24
  852. (LPVOID pd, // --> dst.
  853. LONG dd, // offset to start at
  854. LONG nd, // dst_next_scan.
  855. LONG fd, // dst fill bytes
  856. LPVOID ps, // --> source.
  857. LONG ds, // offset to start at
  858. LONG ns, // src_next_scan.
  859. LONG dx, // pixel count.
  860. LONG dy, // scan count.
  861. LPVOID pc) // pixel convert table.
  862. {
  863. return;
  864. }
  865. void FAR PASCAL convert_16_565
  866. (LPVOID pd, // --> dst.
  867. LONG dd, // offset to start at
  868. LONG nd, // dst_next_scan.
  869. LONG fd, // dst fill bytes
  870. LPVOID ps, // --> source.
  871. LONG ds, // offset to start at
  872. LONG ns, // src_next_scan.
  873. LONG dx, // pixel count.
  874. LONG dy, // scan count.
  875. LPVOID pc) // pixel convert table.
  876. {
  877. return;
  878. }
  879. void FAR PASCAL convert_24_16
  880. (LPVOID pd, // --> dst.
  881. LONG dd, // offset to start at
  882. LONG nd, // dst_next_scan.
  883. LONG fd, // dst fill bytes
  884. LPVOID ps, // --> source.
  885. LONG ds, // offset to start at
  886. LONG ns, // src_next_scan.
  887. LONG dx, // pixel count.
  888. LONG dy, // scan count.
  889. LPVOID pc) // pixel convert table.
  890. {
  891. return;
  892. }
  893. void FAR PASCAL convert_24_24
  894. (LPVOID pd, // --> dst.
  895. LONG dd, // offset to start at
  896. LONG nd, // dst_next_scan.
  897. LONG fd, // dst fill bytes
  898. LPVOID ps, // --> source.
  899. LONG ds, // offset to start at
  900. LONG ns, // src_next_scan.
  901. LONG dx, // pixel count.
  902. LONG dy, // scan count.
  903. LPVOID pc) // pixel convert table.
  904. {
  905. return;
  906. }
  907. void FAR PASCAL convert_24_565
  908. (LPVOID pd, // --> dst.
  909. LONG dd, // offset to start at
  910. LONG nd, // dst_next_scan.
  911. LONG fd, // dst fill bytes
  912. LPVOID ps, // --> source.
  913. LONG ds, // offset to start at
  914. LONG ns, // src_next_scan.
  915. LONG dx, // pixel count.
  916. LONG dy, // scan count.
  917. LPVOID pc) // pixel convert table.
  918. {
  919. return;
  920. }
  921. void FAR PASCAL convert_32_16
  922. (LPVOID pd, // --> dst.
  923. LONG dd, // offset to start at
  924. LONG nd, // dst_next_scan.
  925. LONG fd, // dst fill bytes
  926. LPVOID ps, // --> source.
  927. LONG ds, // offset to start at
  928. LONG ns, // src_next_scan.
  929. LONG dx, // pixel count.
  930. LONG dy, // scan count.
  931. LPVOID pc) // pixel convert table.
  932. {
  933. return;
  934. }
  935. void FAR PASCAL convert_32_24
  936. (LPVOID pd, // --> dst.
  937. LONG dd, // offset to start at
  938. LONG nd, // dst_next_scan.
  939. LONG fd, // dst fill bytes
  940. LPVOID ps, // --> source.
  941. LONG ds, // offset to start at
  942. LONG ns, // src_next_scan.
  943. LONG dx, // pixel count.
  944. LONG dy, // scan count.
  945. LPVOID pc) // pixel convert table.
  946. {
  947. return;
  948. }
  949. void FAR PASCAL convert_32_565
  950. (LPVOID pd, // --> dst.
  951. LONG dd, // offset to start at
  952. LONG nd, // dst_next_scan.
  953. LONG fd, // dst fill bytes
  954. LPVOID ps, // --> source.
  955. LONG ds, // offset to start at
  956. LONG ns, // src_next_scan.
  957. LONG dx, // pixel count.
  958. LONG dy, // scan count.
  959. LPVOID pc) // pixel convert table.
  960. {
  961. return;
  962. }
  963. void FAR PASCAL convert_8_16
  964. (LPVOID pd, // --> dst.
  965. LONG dd, // offset to start at
  966. LONG nd, // dst_next_scan.
  967. LONG fd, // dst fill bytes
  968. LPVOID ps, // --> source.
  969. LONG ds, // offset to start at
  970. LONG ns, // src_next_scan.
  971. LONG dx, // pixel count.
  972. LONG dy, // scan count.
  973. LPVOID pc) // pixel convert table.
  974. {
  975. return;
  976. }
  977. void FAR PASCAL convert_8_24
  978. (LPVOID pd, // --> dst.
  979. LONG dd, // offset to start at
  980. LONG nd, // dst_next_scan.
  981. LONG fd, // dst fill bytes
  982. LPVOID ps, // --> source.
  983. LONG ds, // offset to start at
  984. LONG ns, // src_next_scan.
  985. LONG dx, // pixel count.
  986. LONG dy, // scan count.
  987. LPVOID pc) // pixel convert table.
  988. {
  989. return;
  990. }
  991. void FAR PASCAL convert_8_565
  992. (LPVOID pd, // --> dst.
  993. LONG dd, // offset to start at
  994. LONG nd, // dst_next_scan.
  995. LONG fd, // dst fill bytes
  996. LPVOID ps, // --> source.
  997. LONG ds, // offset to start at
  998. LONG ns, // src_next_scan.
  999. LONG dx, // pixel count.
  1000. LONG dy, // scan count.
  1001. LPVOID pc) // pixel convert table.
  1002. {
  1003. return;
  1004. }
  1005. void FAR PASCAL convert_8_8
  1006. (LPVOID pd, // --> dst.
  1007. LONG dd, // offset to start at
  1008. LONG nd, // dst_next_scan.
  1009. LONG fd, // dst fill bytes
  1010. LPVOID ps, // --> source.
  1011. LONG ds, // offset to start at
  1012. LONG ns, // src_next_scan.
  1013. LONG dx, // pixel count.
  1014. LONG dy, // scan count.
  1015. LPVOID pc) // pixel convert table.
  1016. {
  1017. return;
  1018. }
  1019. void FAR PASCAL copy_8_8
  1020. (LPVOID pd, // --> dst.
  1021. LONG dd, // offset to start at
  1022. LONG nd, // dst_next_scan.
  1023. LONG fd, // dst fill bytes
  1024. LPVOID ps, // --> source.
  1025. LONG ds, // offset to start at
  1026. LONG ns, // src_next_scan.
  1027. LONG dx, // pixel count.
  1028. LONG dy, // scan count.
  1029. LPVOID pc) // pixel convert table.
  1030. {
  1031. return;
  1032. }
  1033. void FAR PASCAL dither_8_8
  1034. (LPVOID pd, // --> dst.
  1035. LONG dd, // offset to start at
  1036. LONG nd, // dst_next_scan.
  1037. LONG fd, // dst fill bytes
  1038. LPVOID ps, // --> source.
  1039. LONG ds, // offset to start at
  1040. LONG ns, // src_next_scan.
  1041. LONG dx, // pixel count.
  1042. LONG dy, // scan count.
  1043. LPVOID pc) // pixel convert table.
  1044. {
  1045. return;
  1046. }
  1047. #endif