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.

377 lines
7.5 KiB

  1. /*****************************************************************************
  2. Description:
  3. Handles Device Independent Bitmap.
  4. PaletteSize() - Calculates the palette size in bytes
  5. of given DIB
  6. DibNumColors() - Determines the number of colors in DIB
  7. BitmapFromDib() - Creates a DDB given a global handle to
  8. a block in CF_DIB format.
  9. DibFromBitmap() - Creates a DIB repr. the DDB passed in.
  10. *****************************************************************************/
  11. #include <windows.h>
  12. #include "dib.h"
  13. static HCURSOR hcurSave;
  14. /*
  15. *
  16. * FUNCTION : PaletteSize(VOID FAR * pv)
  17. *
  18. * PURPOSE : Calculates the palette size in bytes. If the info. block
  19. * is of the BITMAPCOREHEADER type, the number of colors is
  20. * multiplied by 3 to give the palette size, otherwise the
  21. * number of colors is multiplied by 4. *
  22. *
  23. * RETURNS : Palette size in number of bytes.
  24. *
  25. */
  26. WORD PaletteSize (
  27. VOID FAR * pv)
  28. {
  29. LPBITMAPINFOHEADER lpbi;
  30. WORD NumColors;
  31. lpbi = (LPBITMAPINFOHEADER)pv;
  32. NumColors = DibNumColors(lpbi);
  33. if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
  34. return NumColors * sizeof(RGBTRIPLE);
  35. else
  36. return NumColors * sizeof(RGBQUAD);
  37. }
  38. /*
  39. *
  40. * FUNCTION : DibNumColors(VOID FAR * pv)
  41. *
  42. * PURPOSE : Determines the number of colors in the DIB by looking at
  43. * the BitCount filed in the info block.
  44. *
  45. * RETURNS : The number of colors in the DIB.
  46. *
  47. */
  48. WORD DibNumColors (
  49. VOID FAR * pv)
  50. {
  51. int bits;
  52. LPBITMAPINFOHEADER lpbi;
  53. LPBITMAPCOREHEADER lpbc;
  54. lpbi = ((LPBITMAPINFOHEADER)pv);
  55. lpbc = ((LPBITMAPCOREHEADER)pv);
  56. /* With the BITMAPINFO format headers, the size of the palette
  57. * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
  58. * is dependent on the bits per pixel ( = 2 raised to the power of
  59. * bits/pixel).
  60. */
  61. if (lpbi->biSize != sizeof(BITMAPCOREHEADER))
  62. {
  63. if (lpbi->biClrUsed != 0)
  64. return (WORD)lpbi->biClrUsed;
  65. bits = lpbi->biBitCount;
  66. }
  67. else
  68. bits = lpbc->bcBitCount;
  69. switch (bits)
  70. {
  71. case 1:
  72. return 2;
  73. case 4:
  74. return 16;
  75. case 8:
  76. return 256;
  77. default:
  78. /* A 24 bitcount DIB has no color table */
  79. return 0;
  80. }
  81. }
  82. /*
  83. *
  84. * FUNCTION : DibFromBitmap()
  85. *
  86. * PURPOSE : Will create a global memory block in DIB format that
  87. * represents the Device-dependent bitmap (DDB) passed in.
  88. *
  89. * RETURNS : A handle to the DIB
  90. *
  91. */
  92. HANDLE DibFromBitmap (
  93. HBITMAP hbm,
  94. DWORD biStyle,
  95. WORD biBits,
  96. HPALETTE hpal)
  97. {
  98. BITMAP bm;
  99. BITMAPINFOHEADER bi;
  100. BITMAPINFOHEADER FAR *lpbi;
  101. DWORD dwLen;
  102. HANDLE hdib;
  103. HANDLE h;
  104. HDC hdc;
  105. if (!hbm)
  106. return NULL;
  107. if (hpal == NULL)
  108. {
  109. hpal = GetStockObject(DEFAULT_PALETTE);
  110. }
  111. if (!GetObject(hbm,sizeof(bm),(LPSTR)&bm))
  112. return NULL;
  113. if (biBits == 0)
  114. biBits = bm.bmPlanes * bm.bmBitsPixel;
  115. // make sure we have the right # of bits
  116. if (biBits <= 1)
  117. biBits = 1;
  118. else if (biBits <= 4)
  119. biBits = 4;
  120. else if (biBits <= 8)
  121. biBits = 8;
  122. else
  123. biBits = 24;
  124. bi.biSize = sizeof(BITMAPINFOHEADER);
  125. bi.biWidth = bm.bmWidth;
  126. bi.biHeight = bm.bmHeight;
  127. bi.biPlanes = 1;
  128. bi.biBitCount = biBits;
  129. bi.biCompression = biStyle;
  130. bi.biSizeImage = 0;
  131. bi.biXPelsPerMeter = 0;
  132. bi.biYPelsPerMeter = 0;
  133. bi.biClrUsed = 0;
  134. bi.biClrImportant = 0;
  135. dwLen = bi.biSize + PaletteSize (&bi);
  136. hdc = GetDC(NULL);
  137. hpal = SelectPalette (hdc, hpal, FALSE);
  138. RealizePalette (hdc);
  139. hdib = GlobalAlloc (GHND, dwLen);
  140. if (!hdib)
  141. {
  142. SelectPalette (hdc,hpal,FALSE);
  143. ReleaseDC (NULL,hdc);
  144. return NULL;
  145. }
  146. lpbi = (VOID FAR *)GlobalLock(hdib);
  147. *lpbi = bi;
  148. /* call GetDIBits with a NULL lpBits param, so it will calculate the
  149. * biSizeImage field for us
  150. */
  151. GetDIBits (hdc,
  152. hbm,
  153. 0,
  154. (WORD)bi.biHeight,
  155. NULL,
  156. (LPBITMAPINFO)lpbi,
  157. DIB_RGB_COLORS);
  158. bi = *lpbi;
  159. GlobalUnlock(hdib);
  160. // If the driver did not fill in the biSizeImage field, make one up
  161. if (bi.biSizeImage == 0)
  162. {
  163. bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
  164. if (biStyle != BI_RGB)
  165. bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  166. }
  167. // realloc the buffer big enough to hold all the bits
  168. dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
  169. if (h = GlobalReAlloc (hdib,dwLen,0))
  170. hdib = h;
  171. else
  172. {
  173. GlobalFree(hdib);
  174. hdib = NULL;
  175. SelectPalette(hdc,hpal,FALSE);
  176. ReleaseDC(NULL,hdc);
  177. return hdib;
  178. }
  179. /* call GetDIBits with a NON-NULL lpBits param, and actualy get the
  180. * bits this time
  181. */
  182. lpbi = (VOID FAR *)GlobalLock(hdib);
  183. if (0 == GetDIBits (hdc,
  184. hbm,
  185. 0,
  186. (WORD)bi.biHeight,
  187. (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
  188. (LPBITMAPINFO)lpbi,
  189. DIB_RGB_COLORS))
  190. {
  191. GlobalUnlock (hdib);
  192. hdib = NULL;
  193. SelectPalette (hdc, hpal, FALSE);
  194. ReleaseDC (NULL, hdc);
  195. return NULL;
  196. }
  197. bi = *lpbi;
  198. GlobalUnlock (hdib);
  199. SelectPalette (hdc, hpal, FALSE);
  200. ReleaseDC (NULL, hdc);
  201. return hdib;
  202. }
  203. /*
  204. *
  205. * FUNCTION : BitmapFromDib(HANDLE hdib, HPALETTE hpal)
  206. *
  207. * PURPOSE : Will create a DDB (Device Dependent Bitmap) given a global
  208. * handle to a memory block in CF_DIB format
  209. *
  210. * RETURNS : A handle to the DDB.
  211. *
  212. */
  213. HBITMAP BitmapFromDib (
  214. HANDLE hdib,
  215. HPALETTE hpal)
  216. {
  217. LPBITMAPINFOHEADER lpbi;
  218. HPALETTE hpalT;
  219. HDC hdc;
  220. HBITMAP hbm = NULL;
  221. StartWait();
  222. if (!hdib)
  223. goto done;
  224. lpbi = (VOID FAR *)GlobalLock (hdib);
  225. if (!lpbi)
  226. goto done;
  227. hdc = GetDC (NULL);
  228. if (hpal)
  229. {
  230. hpalT = SelectPalette (hdc, hpal, FALSE);
  231. RealizePalette (hdc);
  232. }
  233. hbm = CreateDIBitmap (hdc,
  234. (LPBITMAPINFOHEADER)lpbi,
  235. (LONG)CBM_INIT,
  236. (LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
  237. (LPBITMAPINFO)lpbi,
  238. DIB_RGB_COLORS);
  239. if (hpal)
  240. SelectPalette (hdc, hpalT, FALSE);
  241. ReleaseDC (NULL, hdc);
  242. GlobalUnlock (hdib);
  243. done:
  244. EndWait();
  245. return hbm;
  246. }