4 * This package provides a routine to read a DIB file and set up the
5 * device dependent version of the image.
7 * This file has been modified for use with "Angband 2.8.2"
11 * (C) Copyright Microsoft Corp. 1993. All rights reserved.
13 * You have a royalty-free right to use, modify, reproduce and
14 * distribute the Sample Files (and/or any modified version) in
15 * any way you find useful, provided that you agree that
16 * Microsoft has no warranty obligations or liability for any
17 * Sample Application Files which are modified.
26 * Extract the "WIN32" flag from the compiler
28 #if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
35 * Make sure "huge" is legal XXX XXX XXX
39 # define huge /* oops */
44 * Needed for lcc-win32
52 * Number of bytes to be read during each read operation
57 * Private routine to read more than 64K at a time
59 * Reads data in steps of 32k till all the data has been read.
61 * Returns number of bytes requested, or zero if something went wrong.
63 static DWORD PASCAL lread(int fh, VOID FAR *pv, DWORD ul)
68 while (ul > (DWORD)MAXREAD)
70 if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
75 if (_lread(fh, (LPSTR)hp, (WORD)ul) != ul)
82 * Given a BITMAPINFOHEADER, create a palette based on the color table.
84 * Returns the handle of a palette, or zero if something went wrong.
86 static HPALETTE PASCAL NEAR MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
94 * since biClrUsed field was filled during the loading of the DIB,
95 * we know it contains the number of colors in the color table.
97 if (lpInfo->biClrUsed)
99 npPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
100 (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
104 npPal->palVersion = 0x300;
105 npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
107 /* get pointer to the color table */
108 lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);
110 /* copy colors from the color table to the LogPalette structure */
111 for (i = 0; i < (WORD)lpInfo->biClrUsed; i++, lpRGB++)
113 npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
114 npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
115 npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
116 npPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
119 hLogPal = CreatePalette((LPLOGPALETTE)npPal);
120 LocalFree((HANDLE)npPal);
125 * 24-bit DIB with no color table. return default palette. Another
126 * option would be to create a 256 color "rainbow" palette to provide
127 * some good color choices.
131 return(GetStockObject(DEFAULT_PALETTE));
137 * Given a DIB, create a bitmap and corresponding palette to be used for a
138 * device-dependent representation of the image.
140 * Returns TRUE on success (phPal and phBitmap are filled with appropriate
141 * handles. Caller is responsible for freeing objects) and FALSE on failure
142 * (unable to create objects, both pointer are invalid).
144 static BOOL NEAR PASCAL MakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
145 HPALETTE * phPal, HBITMAP * phBitmap)
147 LPBITMAPINFOHEADER lpInfo;
150 HPALETTE hPalette, hOldPal;
153 lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
154 if ((hPalette = MakeDIBPalette(lpInfo)) != 0)
156 /* Need to realize palette for converting DIB to bitmap. */
157 hOldPal = SelectPalette(hDC, hPalette, TRUE);
160 lpBits = ((LPSTR)lpInfo + (WORD)lpInfo->biSize +
161 (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD));
162 hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
163 (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
165 SelectPalette(hDC, hOldPal, TRUE);
170 DeleteObject(hPalette);
185 * Reads a DIB from a file, obtains a handle to its BITMAPINFO struct, and
186 * loads the DIB. Once the DIB is loaded, the function also creates a bitmap
187 * and palette out of the DIB for a device-dependent form.
189 * Returns TRUE if the DIB is loaded and the bitmap/palette created, in which
190 * case, the DIBINIT structure pointed to by pInfo is filled with the appropriate
191 * handles, and FALSE if something went wrong.
193 BOOL ReadDIB(HWND hWnd, LPSTR lpFileName, DIBINIT *pInfo)
196 LPBITMAPINFOHEADER lpbi;
204 BOOL bCoreHead = FALSE;
206 /* Open the file and get a handle to it's BITMAPINFO */
207 fh = OpenFile(lpFileName, &of, OF_READ);
210 wsprintf(str, "Can't open file '%s'", (LPSTR)lpFileName);
211 MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK);
215 pInfo->hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
216 256 * sizeof(RGBQUAD)));
221 lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
223 /* read the BITMAPFILEHEADER */
224 if (sizeof (bf) != _lread(fh, (LPSTR)&bf, sizeof(bf)))
228 if (bf.bfType != 0x4d42)
231 if (sizeof(BITMAPCOREHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
234 if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
236 lpbi->biSize = sizeof(BITMAPINFOHEADER);
237 lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
238 lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
239 lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
240 lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
245 /* get to the start of the header and read INFOHEADER */
246 _llseek(fh, sizeof(BITMAPFILEHEADER), SEEK_SET);
247 if (sizeof(BITMAPINFOHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
251 if (!(nNumColors = (WORD)lpbi->biClrUsed))
253 /* no color table for 24-bit, default size otherwise */
254 if (lpbi->biBitCount != 24)
255 nNumColors = 1 << lpbi->biBitCount;
258 /* fill in some default values if they are zero */
259 if (lpbi->biClrUsed == 0)
260 lpbi->biClrUsed = nNumColors;
262 if (lpbi->biSizeImage == 0)
264 lpbi->biSizeImage = (((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
268 /* otherwise wouldn't work with 16 color bitmaps -- S.K. */
269 else if ((nNumColors == 16) && (lpbi->biSizeImage > bf.bfSize))
271 lpbi->biSizeImage /= 2;
274 /* get a proper-sized buffer for header, color table and bits */
275 GlobalUnlock(pInfo->hDIB);
276 pInfo->hDIB = GlobalReAlloc(pInfo->hDIB, lpbi->biSize +
277 nNumColors * sizeof(RGBQUAD) +
278 lpbi->biSizeImage, 0);
280 /* can't resize buffer for loading */
284 lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
286 /* read the color table */
289 _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
295 RGBTRIPLE FAR *pTriple;
297 _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
299 pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
300 pTriple = (RGBTRIPLE FAR *) pQuad;
301 for (i = nNumColors - 1; i >= 0; i--)
303 pQuad[i].rgbRed = pTriple[i].rgbtRed;
304 pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
305 pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
306 pQuad[i].rgbReserved = 0;
310 /* offset to the bits from start of DIB header */
311 offBits = (WORD)lpbi->biSize + nNumColors * sizeof(RGBQUAD);
313 if (bf.bfOffBits != 0L)
315 _llseek(fh,bf.bfOffBits,SEEK_SET);
318 /* Use local version of '_lread()' above */
319 if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
321 GlobalUnlock(pInfo->hDIB);
324 if (!MakeBitmapAndPalette(hDC, pInfo->hDIB, &((HPALETTE)pInfo->hPalette),
325 &((HBITMAP)pInfo->hBitmap)))
339 GlobalUnlock(pInfo->hDIB);
341 GlobalFree(pInfo->hDIB);