3 * @brief Windows用ビットマップファイル読み込み処理パッケージ /
4 * This package provides a routine to read a DIB file and set up the 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.
19 * mind.cとあるが実際には超能力者、練気術師、狂戦士、鏡使い、忍者までの
28 * Extract the "WIN32" flag from the compiler
30 #if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
37 * Needed for lcc-win32
44 * 一度にファイルから読み込むデータ量 / Number of bytes to be read during each read operation
48 void global_free(DIBINIT *pInfo, INT_PTR *fh, BOOL unlock_needed);
51 * todo コードが古すぎる。何とかしたい
52 * @brief 32KBのデータ読み取りを繰り返すことで、64KB以上のデータを一度に読み取るサブルーチン
53 * Private routine to read more than 64K at a time Reads data in steps of 32k till all the data has been read.
58 * 取得できたデータ量をバイトで返す。0ならば何らかのエラー。
59 * Returns number of bytes requested, or zero if something went wrong.
61 static DWORD PASCAL lread(int fh, void *pv, DWORD ul)
66 while (ul > (DWORD)MAXREAD)
68 if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
73 if (_lread(fh, (LPSTR)hp, (WORD)ul) != ul)
80 * @brief BITMAPINFOHEADERを取得してカラーテーブルを基本としたパレットを作成する。
81 * Given a BITMAPINFOHEADER, create a palette based on the color table.
82 * @param lpInfo BITMAPINFOHEADERのポインタ
84 * パレットの参照を返す。NULLならばエラー。
85 * Returns the handle of a palette, or zero if something went wrong.
87 static HPALETTE PASCAL MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
95 * since biClrUsed field was filled during the loading of the DIB,
96 * we know it contains the number of colors in the color table.
98 if (lpInfo->biClrUsed)
100 npPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
101 (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
105 npPal->palVersion = 0x300;
106 npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
108 /* get pointer to the color table */
109 lpRGB = (RGBQUAD*)((LPSTR)lpInfo + lpInfo->biSize);
111 /* copy colors from the color table to the LogPalette structure */
112 for (i = 0; i < (WORD)lpInfo->biClrUsed; i++, lpRGB++)
114 npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
115 npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
116 npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
117 npPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
120 hLogPal = CreatePalette((LPLOGPALETTE)npPal);
121 LocalFree((HANDLE)npPal);
126 * 24-bit DIB with no color table. return default palette. Another
127 * option would be to create a 256 color "rainbow" palette to provide
128 * some good color choices.
132 return(GetStockObject(DEFAULT_PALETTE));
139 * ビットマップファイルを受け取り、画像のデバイス依存の描画のために使われる共通パレットとビットマップを作成する
140 * Given a DIB, create a bitmap and corresponding palette to be used for a
141 * device-dependent representation of the image.
142 * @param hDC デバイスコンテキストハンドル
143 * @param hDIB ビットマップ画像ハンドル
144 * @param phPal パレット取得ハンドル
145 * @param phBitmap ビットマップ取得ハンドル
147 * 成功したならばTRUEを返す。失敗の場合FALSE。
148 * Returns TRUE on success (phPal and phBitmap are filled with appropriate
149 * handles. Caller is responsible for freeing objects) and FALSE on failure
150 * (unable to create objects, both pointer are invalid).
152 static BOOL PASCAL MakeBitmapAndPalette(HDC hDC, HANDLE hDIB, HPALETTE * phPal, HBITMAP * phBitmap)
154 LPBITMAPINFOHEADER lpInfo;
157 HPALETTE hPalette, hOldPal;
160 lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
161 if ((hPalette = MakeDIBPalette(lpInfo)) != 0)
163 /* Need to realize palette for converting DIB to bitmap. */
164 hOldPal = SelectPalette(hDC, hPalette, TRUE);
167 lpBits = ((LPSTR)lpInfo + (WORD)lpInfo->biSize +
168 (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD));
169 hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
170 (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
172 SelectPalette(hDC, hOldPal, TRUE);
177 DeleteObject(hPalette);
193 * ビットマップファイルを読み込み、BITMAPINFO構造体にハンドルを取得する。
194 * Reads a DIB from a file, obtains a handle to its BITMAPINFO struct, and
195 * loads the DIB. Once the DIB is loaded, the function also creates a bitmap
196 * and palette out of the DIB for a device-dependent form.
197 * device-dependent representation of the image.
198 * @param hWnd ウィンドウハンドル
199 * @param lpFileName 読み込むビットマップファイル
200 * @param pInfo 取得情報を補完するビットマップ情報構造体ポインタ
202 * Returns TRUE if the DIB is loaded and the bitmap/palette created, in which
203 * case, the DIBINIT structure pointed to by pInfo is filled with the appropriate
204 * handles, and FALSE if something went wrong.
206 * Reads a DIB from a file, obtains a handle to its BITMAPINFO struct, and
207 * loads the DIB. Once the DIB is loaded, the function also creates a bitmap
208 * and palette out of the DIB for a device-dependent form.
210 BOOL ReadDIB(HWND hWnd, LPSTR lpFileName, DIBINIT *pInfo)
212 LPBITMAPINFOHEADER lpbi;
220 BOOL bCoreHead = FALSE;
222 /* Open the file and get a handle to it's BITMAPINFO */
223 INT_PTR fh = OpenFile(lpFileName, &of, OF_READ);
226 wsprintf(str, "Can't open file '%s'", (LPSTR)lpFileName);
227 MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK);
231 pInfo->hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
232 256 * sizeof(RGBQUAD)));
237 lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
239 BOOL is_read_error = sizeof(bf) != _lread(fh, (LPSTR)&bf, sizeof(bf));
240 is_read_error |= bf.bfType != 0x4d42;
241 is_read_error |= sizeof(BITMAPCOREHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER));
244 global_free(pInfo, &fh, TRUE);
248 if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
250 lpbi->biSize = sizeof(BITMAPINFOHEADER);
251 lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
252 lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
253 lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
254 lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
259 /* get to the start of the header and read INFOHEADER */
260 _llseek(fh, sizeof(BITMAPFILEHEADER), SEEK_SET);
261 if (sizeof(BITMAPINFOHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
263 global_free(pInfo, &fh, TRUE);
268 nNumColors = (WORD)lpbi->biClrUsed;
271 /* no color table for 24-bit, default size otherwise */
272 if (lpbi->biBitCount != 24)
273 nNumColors = 1 << lpbi->biBitCount;
276 /* fill in some default values if they are zero */
277 if (lpbi->biClrUsed == 0)
278 lpbi->biClrUsed = nNumColors;
280 if (lpbi->biSizeImage == 0)
282 lpbi->biSizeImage = (((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
286 /* otherwise wouldn't work with 16 color bitmaps -- S.K. */
287 else if ((nNumColors == 16) && (lpbi->biSizeImage > bf.bfSize))
289 lpbi->biSizeImage /= 2;
292 /* get a proper-sized buffer for header, color table and bits */
293 GlobalUnlock(pInfo->hDIB);
294 pInfo->hDIB = GlobalReAlloc(pInfo->hDIB, lpbi->biSize +
295 nNumColors * sizeof(RGBQUAD) +
296 lpbi->biSizeImage, 0);
298 /* can't resize buffer for loading */
301 global_free(pInfo, &fh, FALSE);
305 lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
307 /* read the color table */
310 _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
318 _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
320 pQuad = (RGBQUAD*)((LPSTR)lpbi + lpbi->biSize);
321 pTriple = (RGBTRIPLE*) pQuad;
322 for (i = nNumColors - 1; i >= 0; i--)
324 pQuad[i].rgbRed = pTriple[i].rgbtRed;
325 pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
326 pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
327 pQuad[i].rgbReserved = 0;
331 /* offset to the bits from start of DIB header */
332 offBits = (WORD)lpbi->biSize + nNumColors * sizeof(RGBQUAD);
334 if (bf.bfOffBits != 0L)
336 _llseek(fh,bf.bfOffBits,SEEK_SET);
339 /* Use local version of '_lread()' above */
340 if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
342 GlobalUnlock(pInfo->hDIB);
345 if (!MakeBitmapAndPalette(hDC, pInfo->hDIB, &((HPALETTE)pInfo->hPalette),
346 &((HBITMAP)pInfo->hBitmap)))
349 global_free(pInfo, &fh, FALSE);
360 GlobalUnlock(pInfo->hDIB);
361 GlobalFree(pInfo->hDIB);
369 void global_free(DIBINIT *pInfo, INT_PTR *fh, BOOL unlock_needed)
373 GlobalUnlock(pInfo->hDIB);
376 GlobalFree(pInfo->hDIB);