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.

571 lines
17 KiB

  1. /*---------------------------------------------------------------------------
  2. **
  3. **-------------------------------------------------------------------------*/
  4. #include <pch.h>
  5. #include "dibutil.h"
  6. HANDLE ReadDIBFile(HANDLE hfile);
  7. /*************************************************************************
  8. *
  9. * GetDeviceNumColors()
  10. *
  11. * Purpose: Determines how many colors the video device supports
  12. *
  13. * Returns: (int) Number of colors supported
  14. *
  15. * History: Date Author Reason
  16. * 2/28/97 hanumany Created
  17. *
  18. *
  19. *
  20. *************************************************************************/
  21. UINT GetDeviceNumColors(HDC hdc)
  22. {
  23. static UINT iNumColors = 0;
  24. if(!iNumColors)
  25. iNumColors = GetDeviceCaps(hdc, NUMCOLORS);
  26. return iNumColors;
  27. }
  28. HANDLE LoadDIB(LPTSTR lpFileName)
  29. {
  30. HANDLE hDIB = NULL;
  31. HANDLE hFile;
  32. /*
  33. * Set the cursor to a hourglass, in case the loading operation
  34. * takes more than a sec, the user will know what's going on.
  35. */
  36. SetCursor(LoadCursor(NULL, IDC_WAIT));
  37. hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  38. if (hFile != INVALID_HANDLE_VALUE)
  39. {
  40. hDIB = ReadDIBFile(hFile);
  41. CloseHandle(hFile);
  42. }
  43. SetCursor(LoadCursor(NULL, IDC_ARROW));
  44. return hDIB;
  45. }
  46. /*
  47. * Dib Header Marker - used in writing DIBs to files
  48. */
  49. #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
  50. HANDLE ReadDIBFile(HANDLE hFile)
  51. {
  52. BITMAPFILEHEADER bmfHeader;
  53. DWORD dwBitsSize;
  54. DWORD dwRead;
  55. HANDLE hDIB;
  56. /*
  57. * get length of DIB in bytes for use when reading
  58. */
  59. dwBitsSize = GetFileSize(hFile, NULL);
  60. /*
  61. * Go read the DIB file header and check if it's valid.
  62. */
  63. if ((ReadFile(hFile, (LPVOID)&bmfHeader, sizeof(bmfHeader), &dwRead, NULL) == 0) ||
  64. (sizeof (bmfHeader) != dwRead))
  65. {
  66. return NULL;
  67. }
  68. if (bmfHeader.bfType != DIB_HEADER_MARKER)
  69. {
  70. return NULL;
  71. }
  72. /*
  73. * Allocate memory for DIB
  74. */
  75. hDIB = (HANDLE) HeapAlloc(GetProcessHeap(), 0, dwBitsSize);
  76. if (hDIB == NULL)
  77. {
  78. return NULL;
  79. }
  80. /*
  81. * Go read the bits.
  82. */
  83. if ((ReadFile(hFile, (LPVOID)hDIB, dwBitsSize - sizeof(BITMAPFILEHEADER), &dwRead, NULL) == 0) ||
  84. (dwBitsSize - sizeof(BITMAPFILEHEADER)!= dwRead))
  85. {
  86. HeapFree(GetProcessHeap(), 0, hDIB);
  87. return NULL;
  88. }
  89. return hDIB;
  90. }
  91. /*************************************************************************
  92. *
  93. * DIBNumColors()
  94. *
  95. * Parameter:
  96. *
  97. * LPBYTE lpDIB - pointer to packed-DIB memory block
  98. *
  99. * Return Value:
  100. *
  101. * WORD - number of colors in the color table
  102. *
  103. * Description:
  104. *
  105. * This function calculates the number of colors in the DIB's color table
  106. * by finding the bits per pixel for the DIB (whether Win3.0 or OS/2-style
  107. * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256,
  108. * if 24, no colors in color table.
  109. *
  110. * History: Date Author Reason
  111. * 6/01/91 Garrett McAuliffe Created
  112. * 9/15/91 Patrick Schreiber Added header and comments
  113. *
  114. ************************************************************************/
  115. WORD DIBNumColors(LPBYTE lpDIB)
  116. {
  117. WORD wBitCount; // DIB bit count
  118. /* If this is a Windows-style DIB, the number of colors in the
  119. * color table can be less than the number of bits per pixel
  120. * allows for (i.e. lpbi->biClrUsed can be set to some value).
  121. * If this is the case, return the appropriate value.
  122. */
  123. if (IS_WIN30_DIB(lpDIB))
  124. {
  125. DWORD dwClrUsed;
  126. dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
  127. if (dwClrUsed)
  128. {
  129. return (WORD)dwClrUsed;
  130. }
  131. }
  132. /* Calculate the number of colors in the color table based on
  133. * the number of bits per pixel for the DIB.
  134. */
  135. if (IS_WIN30_DIB(lpDIB))
  136. wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
  137. else
  138. wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
  139. /* return number of colors based on bits per pixel */
  140. switch (wBitCount)
  141. {
  142. case 1:
  143. return 2;
  144. case 4:
  145. return 16;
  146. case 8:
  147. return 256;
  148. default:
  149. return 0;
  150. }
  151. }
  152. //-------------------------------------------------------------------------
  153. // B U I L D P A L E T T E
  154. //
  155. // Creates an HPALETTE from a bitmap in a DC
  156. //-------------------------------------------------------------------------
  157. HPALETTE BuildPalette(HDC hdc)
  158. {
  159. DWORD adw[257];
  160. int i,n;
  161. n = GetDIBColorTable(hdc, 0, 256, (LPRGBQUAD)&adw[1]);
  162. if (n == 0)
  163. return CreateHalftonePalette(hdc);
  164. for (i=1; i<=n; i++)
  165. {
  166. adw[i] = RGB(GetBValue(adw[i]),GetGValue(adw[i]),GetRValue(adw[i]));
  167. }
  168. adw[0] = MAKELONG(0x300, n);
  169. return CreatePalette((LPLOGPALETTE)&adw[0]);
  170. }
  171. /*************************************************************************
  172. *
  173. * CreateDIBPalette()
  174. *
  175. * Parameter:
  176. *
  177. * HDIB hDIB - specifies the DIB
  178. *
  179. * Return Value:
  180. *
  181. * HPALETTE - specifies the palette
  182. *
  183. * Description:
  184. *
  185. * This function creates a palette from a DIB by allocating memory for the
  186. * logical palette, reading and storing the colors from the DIB's color table
  187. * into the logical palette, creating a palette from this logical palette,
  188. * and then returning the palette's handle. This allows the DIB to be
  189. * displayed using the best possible colors (important for DIBs with 256 or
  190. * more colors).
  191. *
  192. * History: Date Author Reason
  193. * 6/01/91 Garrett McAuliffe Created
  194. * 9/15/91 Patrick Schreiber Added header and comments
  195. * 10/08/97 hanumany check GlobalLock return code
  196. *
  197. ************************************************************************/
  198. HPALETTE CreateDIBPalette(HDIB hDIB)
  199. {
  200. LPLOGPALETTE lpPal = NULL; // pointer to a logical palette
  201. HANDLE hLogPal = NULL; // handle to a logical palette
  202. HPALETTE hPal = NULL; // handle to a palette
  203. int i = 0, wNumColors = 0; // loop index, number of colors in color table
  204. LPBYTE lpbi = NULL; // pointer to packed-DIB
  205. LPBITMAPINFO lpbmi = NULL; // pointer to BITMAPINFO structure (Win3.0)
  206. LPBITMAPCOREINFO lpbmc = NULL; // pointer to BITMAPCOREINFO structure (OS/2)
  207. BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0 DIB
  208. /* if handle to DIB is invalid, return NULL */
  209. if (!hDIB)
  210. return NULL;
  211. /* get pointer to BITMAPINFO (Win 3.0) */
  212. lpbmi = (LPBITMAPINFO)hDIB;
  213. /* get pointer to BITMAPCOREINFO (OS/2 1.x) */
  214. lpbmc = (LPBITMAPCOREINFO)hDIB;
  215. /* get the number of colors in the DIB */
  216. wNumColors = DIBNumColors(hDIB);
  217. /* is this a Win 3.0 DIB? */
  218. bWinStyleDIB = IS_WIN30_DIB(hDIB);
  219. if (wNumColors)
  220. {
  221. /* allocate memory block for logical palette */
  222. lpPal = (HANDLE) HeapAlloc(GetProcessHeap(), 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * wNumColors);
  223. /* if not enough memory, clean up and return NULL */
  224. if (!lpPal)
  225. {
  226. return NULL;
  227. }
  228. /* set version and number of palette entries */
  229. lpPal->palVersion = PALVERSION;
  230. lpPal->palNumEntries = (WORD)wNumColors;
  231. /* store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
  232. * into palette
  233. */
  234. for (i = 0; i < wNumColors; i++)
  235. {
  236. if (bWinStyleDIB)
  237. {
  238. lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
  239. lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
  240. lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
  241. lpPal->palPalEntry[i].peFlags = 0;
  242. }
  243. else
  244. {
  245. lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
  246. lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
  247. lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
  248. lpPal->palPalEntry[i].peFlags = 0;
  249. }
  250. }
  251. /* create the palette and get handle to it */
  252. hPal = CreatePalette(lpPal);
  253. }
  254. /* clean up */
  255. HeapFree(GetProcessHeap(), 0, lpPal);
  256. /* return handle to DIB's palette */
  257. return hPal;
  258. }
  259. WORD PaletteSize(LPBYTE lpDIB)
  260. {
  261. /* calculate the size required by the palette */
  262. if (IS_WIN30_DIB (lpDIB))
  263. return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
  264. else
  265. return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
  266. }
  267. /*************************************************************************
  268. *
  269. * FindDIBBits()
  270. *
  271. * Parameter:
  272. *
  273. * LPBYTE lpDIB - pointer to packed-DIB memory block
  274. *
  275. * Return Value:
  276. *
  277. * LPBYTE - pointer to the DIB bits
  278. *
  279. * Description:
  280. *
  281. * This function calculates the address of the DIB's bits and returns a
  282. * pointer to the DIB bits.
  283. *
  284. * History: Date Author Reason
  285. * 6/01/91 Garrett McAuliffe Created
  286. * 9/15/91 Patrick Schreiber Added header and comments
  287. *
  288. ************************************************************************/
  289. LPBYTE FindDIBBits(LPBYTE lpDIB)
  290. {
  291. return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
  292. }
  293. /*************************************************************************
  294. *
  295. * DIBToBitmap()
  296. *
  297. * Parameters:
  298. *
  299. * HDIB hDIB - specifies the DIB to convert
  300. *
  301. * HPALETTE hPal - specifies the palette to use with the bitmap
  302. *
  303. * Return Value:
  304. *
  305. * HBITMAP - identifies the device-dependent bitmap
  306. *
  307. * Description:
  308. *
  309. * This function creates a bitmap from a DIB using the specified palette.
  310. * If no palette is specified, default is used.
  311. *
  312. * NOTE:
  313. *
  314. * The bitmap returned from this funciton is always a bitmap compatible
  315. * with the screen (e.g. same bits/pixel and color planes) rather than
  316. * a bitmap with the same attributes as the DIB. This behavior is by
  317. * design, and occurs because this function calls CreateDIBitmap to
  318. * do its work, and CreateDIBitmap always creates a bitmap compatible
  319. * with the hDC parameter passed in (because it in turn calls
  320. * CreateCompatibleBitmap).
  321. *
  322. * So for instance, if your DIB is a monochrome DIB and you call this
  323. * function, you will not get back a monochrome HBITMAP -- you will
  324. * get an HBITMAP compatible with the screen DC, but with only 2
  325. * colors used in the bitmap.
  326. *
  327. * If your application requires a monochrome HBITMAP returned for a
  328. * monochrome DIB, use the function SetDIBits().
  329. *
  330. * Also, the DIBpassed in to the function is not destroyed on exit. This
  331. * must be done later, once it is no longer needed.
  332. *
  333. * History: Date Author Reason
  334. * 6/01/91 Garrett McAuliffe Created
  335. * 9/15/91 Patrick Schreiber Added header and comments
  336. * 3/27/92 Mark Bader Added comments about resulting
  337. * bitmap format
  338. * 10/08/97 hanumany check GlobalLock return code.
  339. *
  340. ************************************************************************/
  341. HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal)
  342. {
  343. LPBYTE lpDIBHdr, lpDIBBits; // pointer to DIB header, pointer to DIB bits
  344. HBITMAP hBitmap; // handle to device-dependent bitmap
  345. HDC hDC; // handle to DC
  346. HPALETTE hOldPal = NULL; // handle to a palette
  347. /* if invalid handle, return NULL */
  348. if (!hDIB)
  349. return NULL;
  350. /* get a pointer to the DIB bits */
  351. lpDIBBits = FindDIBBits(hDIB);
  352. /* get a DC */
  353. hDC = GetDC(NULL);
  354. if (!hDC)
  355. {
  356. return NULL;
  357. }
  358. /* select and realize palette */
  359. if (hPal)
  360. hOldPal = SelectPalette(hDC, hPal, FALSE);
  361. RealizePalette(hDC);
  362. /* create bitmap from DIB info. and bits */
  363. hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)hDIB, CBM_INIT,
  364. (LPCVOID)lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
  365. /* restore previous palette */
  366. if (hOldPal)
  367. SelectPalette(hDC, hOldPal, FALSE);
  368. /* clean up */
  369. ReleaseDC(NULL, hDC);
  370. /* return handle to the bitmap */
  371. return hBitmap;
  372. }
  373. WORD DestroyDIB(HDIB hDib)
  374. {
  375. HeapFree(GetProcessHeap(), 0, hDib);
  376. return 0;
  377. }
  378. /******************************************************************
  379. *
  380. * DrawBitmap()
  381. *
  382. * This function paints the given bitmap at the given coordinates.
  383. *
  384. ******************************************************************/
  385. void DrawBitmap (HDC hdc, HBITMAP hBitmap, int xStart, int yStart)
  386. {
  387. BITMAP bm;
  388. HDC hdcMem;
  389. POINT ptSize, ptOrg;
  390. HBITMAP hBitmapOld = NULL;
  391. if (hBitmap == NULL) {
  392. return;
  393. }
  394. hdcMem = CreateCompatibleDC (hdc);
  395. if (hdcMem == NULL)
  396. {
  397. return;
  398. }
  399. SetBkMode(hdcMem, TRANSPARENT);
  400. hBitmapOld = SelectObject(hdcMem, hBitmap);
  401. SetMapMode(hdcMem, GetMapMode(hdc));
  402. GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bm);
  403. ptSize.x = bm.bmWidth;
  404. ptSize.y = bm.bmHeight;
  405. DPtoLP(hdc, &ptSize, 1);
  406. ptOrg.x = 0;
  407. ptOrg.y = 0;
  408. DPtoLP(hdcMem, &ptOrg, 1);
  409. BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, ptOrg.x, ptOrg.y, SRCCOPY);
  410. SelectObject(hdcMem, hBitmapOld);
  411. DeleteDC(hdcMem);
  412. }
  413. /******************************************************************
  414. *
  415. * DrawTransparentBitmap()
  416. *
  417. * This function paints the given bitmap at the given coordinates.
  418. * and allow for one transparent color
  419. *
  420. ******************************************************************/
  421. void DrawTransparentBitmap(
  422. HDC hdc,
  423. HBITMAP hBitmap,
  424. int xStart,
  425. int yStart,
  426. COLORREF cTransparentColor )
  427. {
  428. BITMAP bm;
  429. COLORREF cColor;
  430. HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
  431. HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
  432. HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
  433. POINT ptSize;
  434. COLORREF cTransparentColor2;
  435. hdcTemp = CreateCompatibleDC(hdc);
  436. SelectObject(hdcTemp, hBitmap);
  437. cTransparentColor2 = GetPixel(hdcTemp, 0, 0);
  438. if (cTransparentColor2 == CLR_INVALID)
  439. {
  440. cTransparentColor2 = cTransparentColor;
  441. }
  442. GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
  443. ptSize.x = bm.bmWidth;
  444. ptSize.y = bm.bmHeight;
  445. DPtoLP(hdcTemp, &ptSize, 1);
  446. hdcBack = CreateCompatibleDC(hdc);
  447. hdcObject = CreateCompatibleDC(hdc);
  448. hdcMem = CreateCompatibleDC(hdc);
  449. hdcSave = CreateCompatibleDC(hdc);
  450. bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
  451. bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
  452. bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
  453. bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
  454. bmBackOld = SelectObject(hdcBack, bmAndBack);
  455. bmObjectOld = SelectObject(hdcObject, bmAndObject);
  456. bmMemOld = SelectObject(hdcMem, bmAndMem);
  457. bmSaveOld = SelectObject(hdcSave, bmSave);
  458. SetMapMode(hdcTemp, GetMapMode(hdc));
  459. BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
  460. cColor = SetBkColor(hdcTemp, cTransparentColor2);
  461. BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
  462. SRCCOPY);
  463. SetBkColor(hdcTemp, cColor);
  464. BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
  465. NOTSRCCOPY);
  466. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart,
  467. SRCCOPY);
  468. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
  469. BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
  470. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
  471. BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,
  472. SRCCOPY);
  473. BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
  474. DeleteObject(SelectObject(hdcBack, bmBackOld));
  475. DeleteObject(SelectObject(hdcObject, bmObjectOld));
  476. DeleteObject(SelectObject(hdcMem, bmMemOld));
  477. DeleteObject(SelectObject(hdcSave, bmSaveOld));
  478. DeleteDC(hdcMem);
  479. DeleteDC(hdcBack);
  480. DeleteDC(hdcObject);
  481. DeleteDC(hdcSave);
  482. DeleteDC(hdcTemp);
  483. }