PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/IronHellsOgre/src/ironhells/angband/readdib.c

#
C | 365 lines | 235 code | 49 blank | 81 comment | 44 complexity | ea3cadfca4e0816f8f6888178bbec27c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, Apache-2.0
  1. /* $Id: readdib.c 182 2004-09-10 14:57:20Z cipher $ */
  2. /*
  3. * This package provides a routine to read a DIB file and set up the
  4. * device dependent version of the image.
  5. *
  6. * This file has been modified for use with "Angband 2.9.2"
  7. *
  8. * COPYRIGHT:
  9. *
  10. * (C) Copyright Microsoft Corp. 1993. All rights reserved.
  11. *
  12. * You have a royalty-free right to use, modify, reproduce and
  13. * distribute the Sample Files (and/or any modified version) in
  14. * any way you find useful, provided that you agree that
  15. * Microsoft has no warranty obligations or liability for any
  16. * Sample Application Files which are modified.
  17. */
  18. #ifdef __win32__
  19. #include <windows.h>
  20. #include "readdib.h"
  21. /*
  22. * Extract the "WIN32" flag from the compiler
  23. */
  24. #if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
  25. # ifndef WIN32
  26. # define WIN32
  27. # endif
  28. #endif
  29. /*
  30. * Needed for lcc-win32
  31. */
  32. #ifndef SEEK_SET
  33. #define SEEK_SET 0
  34. #endif
  35. /*
  36. * Number of bytes to be read during each read operation
  37. */
  38. #define MAXREAD 32768
  39. /*
  40. * Private routine to read more than 64K at a time
  41. *
  42. * Reads data in steps of 32k till all the data has been read.
  43. *
  44. * Returns number of bytes requested, or zero if something went wrong.
  45. */
  46. static DWORD PASCAL
  47. lread(HFILE fh,
  48. VOID FAR * pv,
  49. DWORD ul)
  50. {
  51. DWORD ulT = ul;
  52. BYTE *hp = pv;
  53. while(ul > (DWORD) MAXREAD)
  54. {
  55. if(_lread(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
  56. return 0;
  57. ul -= MAXREAD;
  58. hp += MAXREAD;
  59. }
  60. if(_lread(fh, (LPSTR) hp, (WORD) ul) != (WORD) ul)
  61. return 0;
  62. return ulT;
  63. }
  64. /*
  65. * Given a BITMAPINFOHEADER, create a palette based on the color table.
  66. *
  67. * Returns the handle of a palette, or zero if something went wrong.
  68. */
  69. static HPALETTE PASCAL NEAR
  70. MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
  71. {
  72. PLOGPALETTE npPal;
  73. RGBQUAD FAR *lpRGB;
  74. HPALETTE hLogPal;
  75. DWORD i;
  76. /*
  77. * since biClrUsed field was filled during the loading of the DIB,
  78. * we know it contains the number of colors in the color table.
  79. */
  80. if(lpInfo->biClrUsed)
  81. {
  82. npPal = (PLOGPALETTE) LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
  83. (WORD) lpInfo->biClrUsed *
  84. sizeof(PALETTEENTRY));
  85. if(!npPal)
  86. return (FALSE);
  87. npPal->palVersion = 0x300;
  88. npPal->palNumEntries = (WORD) lpInfo->biClrUsed;
  89. /* get pointer to the color table */
  90. lpRGB = (RGBQUAD FAR *) ((LPSTR) lpInfo + lpInfo->biSize);
  91. /* copy colors from the color table to the LogPalette structure */
  92. for(i = 0; i < lpInfo->biClrUsed; i++, lpRGB++)
  93. {
  94. npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
  95. npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
  96. npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
  97. npPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  98. }
  99. hLogPal = CreatePalette((LPLOGPALETTE) npPal);
  100. LocalFree((HANDLE) npPal);
  101. return (hLogPal);
  102. }
  103. /*
  104. * 24-bit DIB with no color table. return default palette. Another
  105. * option would be to create a 256 color "rainbow" palette to provide
  106. * some good color choices.
  107. */
  108. else
  109. {
  110. return (GetStockObject(DEFAULT_PALETTE));
  111. }
  112. }
  113. /*
  114. * Given a DIB, create a bitmap and corresponding palette to be used for a
  115. * device-dependent representation of the image.
  116. *
  117. * Returns TRUE on success (phPal and phBitmap are filled with appropriate
  118. * handles. Caller is responsible for freeing objects) and FALSE on failure
  119. * (unable to create objects, both pointer are invalid).
  120. */
  121. static BOOL NEAR PASCAL
  122. MakeBitmapAndPalette(HDC hDC,
  123. HANDLE hDIB,
  124. HPALETTE * phPal,
  125. HBITMAP * phBitmap)
  126. {
  127. LPBITMAPINFOHEADER lpInfo;
  128. BOOL result = FALSE;
  129. HBITMAP hBitmap;
  130. HPALETTE hPalette, hOldPal;
  131. LPSTR lpBits;
  132. lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
  133. if((hPalette = MakeDIBPalette(lpInfo)) != 0)
  134. {
  135. /* Need to realize palette for converting DIB to bitmap. */
  136. hOldPal = SelectPalette(hDC, hPalette, TRUE);
  137. RealizePalette(hDC);
  138. lpBits = ((LPSTR) lpInfo + (WORD) lpInfo->biSize +
  139. (WORD) lpInfo->biClrUsed * sizeof(RGBQUAD));
  140. hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
  141. (LPBITMAPINFO) lpInfo, DIB_RGB_COLORS);
  142. SelectPalette(hDC, hOldPal, TRUE);
  143. RealizePalette(hDC);
  144. if(!hBitmap)
  145. {
  146. DeleteObject(hPalette);
  147. }
  148. else
  149. {
  150. *phBitmap = hBitmap;
  151. *phPal = hPalette;
  152. result = TRUE;
  153. }
  154. }
  155. return (result);
  156. }
  157. /*
  158. * Reads a DIB from a file, obtains a handle to its BITMAPINFO struct, and
  159. * loads the DIB. Once the DIB is loaded, the function also creates a bitmap
  160. * and palette out of the DIB for a device-dependent form.
  161. *
  162. * Returns TRUE if the DIB is loaded and the bitmap/palette created, in which
  163. * case, the DIBINIT structure pointed to by pInfo is filled with the appropriate
  164. * handles, and FALSE if something went wrong.
  165. */
  166. BOOL
  167. ReadDIB(HWND hWnd,
  168. LPSTR lpFileName,
  169. DIBINIT * pInfo)
  170. {
  171. HFILE fh;
  172. LPBITMAPINFOHEADER lpbi;
  173. OFSTRUCT of;
  174. BITMAPFILEHEADER bf;
  175. WORD nNumColors;
  176. BOOL result = FALSE;
  177. DWORD offBits;
  178. HDC hDC;
  179. BOOL bCoreHead = FALSE;
  180. /* Open the file and get a handle to it's BITMAPINFO */
  181. fh = OpenFile(lpFileName, &of, OF_READ);
  182. if(fh == -1)
  183. return (FALSE);
  184. pInfo->hDIB = GlobalAlloc(GHND, (DWORD) (sizeof(BITMAPINFOHEADER) +
  185. 256 * sizeof(RGBQUAD)));
  186. if(!pInfo->hDIB)
  187. return (FALSE);
  188. lpbi = (LPBITMAPINFOHEADER) GlobalLock(pInfo->hDIB);
  189. /* read the BITMAPFILEHEADER */
  190. if(sizeof(bf) != _lread(fh, (LPSTR) & bf, sizeof(bf)))
  191. goto ErrExit;
  192. /* 'BM' */
  193. if(bf.bfType != 0x4d42)
  194. goto ErrExit;
  195. if(sizeof(BITMAPCOREHEADER) !=
  196. _lread(fh, (LPSTR) lpbi, sizeof(BITMAPCOREHEADER)))
  197. goto ErrExit;
  198. if(lpbi->biSize == sizeof(BITMAPCOREHEADER))
  199. {
  200. lpbi->biSize = sizeof(BITMAPINFOHEADER);
  201. lpbi->biBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;
  202. lpbi->biPlanes = ((LPBITMAPCOREHEADER) lpbi)->bcPlanes;
  203. lpbi->biHeight = ((LPBITMAPCOREHEADER) lpbi)->bcHeight;
  204. lpbi->biWidth = ((LPBITMAPCOREHEADER) lpbi)->bcWidth;
  205. bCoreHead = TRUE;
  206. }
  207. else
  208. {
  209. /* get to the start of the header and read INFOHEADER */
  210. _llseek(fh, sizeof(BITMAPFILEHEADER), SEEK_SET);
  211. if(sizeof(BITMAPINFOHEADER) !=
  212. _lread(fh, (LPSTR) lpbi, sizeof(BITMAPINFOHEADER)))
  213. goto ErrExit;
  214. }
  215. if(!(nNumColors = (WORD) lpbi->biClrUsed))
  216. {
  217. /* no color table for 24-bit, default size otherwise */
  218. if(lpbi->biBitCount != 24)
  219. nNumColors = 1 << lpbi->biBitCount;
  220. }
  221. /* fill in some default values if they are zero */
  222. if(lpbi->biClrUsed == 0)
  223. lpbi->biClrUsed = nNumColors;
  224. if(lpbi->biSizeImage == 0)
  225. {
  226. lpbi->biSizeImage =
  227. (((((lpbi->biWidth * (DWORD) lpbi->biBitCount) +
  228. 31) & ~31) >> 3) * lpbi->biHeight);
  229. }
  230. /* otherwise wouldn't work with 16 color bitmaps -- S.K. */
  231. else if((nNumColors == 16) && (lpbi->biSizeImage > bf.bfSize))
  232. {
  233. lpbi->biSizeImage /= 2;
  234. }
  235. /* get a proper-sized buffer for header, color table and bits */
  236. GlobalUnlock(pInfo->hDIB);
  237. pInfo->hDIB = GlobalReAlloc(pInfo->hDIB, lpbi->biSize +
  238. nNumColors * sizeof(RGBQUAD) +
  239. lpbi->biSizeImage, 0);
  240. /* can't resize buffer for loading */
  241. if(!pInfo->hDIB)
  242. goto ErrExit2;
  243. lpbi = (LPBITMAPINFOHEADER) GlobalLock(pInfo->hDIB);
  244. /* read the color table */
  245. if(!bCoreHead)
  246. {
  247. _lread(fh, (LPSTR) (lpbi) + lpbi->biSize,
  248. nNumColors * sizeof(RGBQUAD));
  249. }
  250. else
  251. {
  252. signed int i;
  253. RGBQUAD FAR *pQuad;
  254. RGBTRIPLE FAR *pTriple;
  255. _lread(fh, (LPSTR) (lpbi) + lpbi->biSize,
  256. nNumColors * sizeof(RGBTRIPLE));
  257. pQuad = (RGBQUAD FAR *) ((LPSTR) lpbi + lpbi->biSize);
  258. pTriple = (RGBTRIPLE FAR *) pQuad;
  259. for(i = nNumColors - 1; i >= 0; i--)
  260. {
  261. pQuad[i].rgbRed = pTriple[i].rgbtRed;
  262. pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
  263. pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
  264. pQuad[i].rgbReserved = 0;
  265. }
  266. }
  267. /* offset to the bits from start of DIB header */
  268. offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD);
  269. if(bf.bfOffBits != 0L)
  270. {
  271. _llseek(fh, bf.bfOffBits, SEEK_SET);
  272. }
  273. /* Use local version of '_lread()' above */
  274. if(lpbi->biSizeImage ==
  275. lread(fh, (LPSTR) lpbi + offBits, lpbi->biSizeImage))
  276. {
  277. GlobalUnlock(pInfo->hDIB);
  278. hDC = GetDC(hWnd);
  279. if(!MakeBitmapAndPalette(hDC, pInfo->hDIB, &(pInfo->hPalette),
  280. &(pInfo->hBitmap)))
  281. {
  282. ReleaseDC(hWnd, hDC);
  283. goto ErrExit2;
  284. }
  285. else
  286. {
  287. ReleaseDC(hWnd, hDC);
  288. result = TRUE;
  289. }
  290. }
  291. else
  292. {
  293. ErrExit:
  294. GlobalUnlock(pInfo->hDIB);
  295. ErrExit2:
  296. GlobalFree(pInfo->hDIB);
  297. }
  298. _lclose(fh);
  299. return (result);
  300. }
  301. /* Free a DIB */
  302. void
  303. FreeDIB(DIBINIT * dib)
  304. {
  305. /* Free the bitmap stuff */
  306. if(dib->hPalette)
  307. DeleteObject(dib->hPalette);
  308. if(dib->hBitmap)
  309. DeleteObject(dib->hBitmap);
  310. if(dib->hDIB)
  311. GlobalFree(dib->hDIB);
  312. dib->hPalette = NULL;
  313. dib->hBitmap = NULL;
  314. dib->hDIB = NULL;
  315. }
  316. #endif /* __win32__ */