Source code of Windows XP (NT5)
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.

266 lines
9.5 KiB

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