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 * Needed for lcc-win32
35 * 一度にファイルから読み込むデータ量 / Number of bytes to be read during each read operation
39 void global_free(DIBINIT *pInfo, INT_PTR *fh, BOOL unlock_needed);
42 * todo コードが古すぎる。何とかしたい
43 * @brief 32KBのデータ読み取りを繰り返すことで、64KB以上のデータを一度に読み取るサブルーチン
44 * Private routine to read more than 64K at a time Reads data in steps of 32k till all the data has been read.
49 * 取得できたデータ量をバイトで返す。0ならば何らかのエラー。
50 * Returns number of bytes requested, or zero if something went wrong.
52 static DWORD PASCAL lread(int fh, void *pv, DWORD ul)
57 while (ul > (DWORD)MAXREAD)
59 if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
64 if (_lread(fh, (LPSTR)hp, (WORD)ul) != ul)
71 * @brief BITMAPINFOHEADERを取得してカラーテーブルを基本としたパレットを作成する。
72 * Given a BITMAPINFOHEADER, create a palette based on the color table.
73 * @param lpInfo BITMAPINFOHEADERのポインタ
75 * パレットの参照を返す。NULLならばエラー。
76 * Returns the handle of a palette, or zero if something went wrong.
78 static HPALETTE PASCAL MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
86 * since biClrUsed field was filled during the loading of the DIB,
87 * we know it contains the number of colors in the color table.
89 if (lpInfo->biClrUsed)
91 npPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
92 (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
96 npPal->palVersion = 0x300;
97 npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
99 /* get pointer to the color table */
100 lpRGB = (RGBQUAD*)((LPSTR)lpInfo + lpInfo->biSize);
102 /* copy colors from the color table to the LogPalette structure */
103 for (i = 0; i < (WORD)lpInfo->biClrUsed; i++, lpRGB++)
105 npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
106 npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
107 npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
108 npPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
111 hLogPal = CreatePalette((LPLOGPALETTE)npPal);
112 LocalFree((HANDLE)npPal);
117 * 24-bit DIB with no color table. return default palette. Another
118 * option would be to create a 256 color "rainbow" palette to provide
119 * some good color choices.
123 return(GetStockObject(DEFAULT_PALETTE));
130 * ビットマップファイルを受け取り、画像のデバイス依存の描画のために使われる共通パレットとビットマップを作成する
131 * Given a DIB, create a bitmap and corresponding palette to be used for a
132 * device-dependent representation of the image.
133 * @param hDC デバイスコンテキストハンドル
134 * @param hDIB ビットマップ画像ハンドル
135 * @param phPal パレット取得ハンドル
136 * @param phBitmap ビットマップ取得ハンドル
138 * 成功したならばTRUEを返す。失敗の場合FALSE。
139 * Returns TRUE on success (phPal and phBitmap are filled with appropriate
140 * handles. Caller is responsible for freeing objects) and FALSE on failure
141 * (unable to create objects, both pointer are invalid).
143 static BOOL PASCAL MakeBitmapAndPalette(HDC hDC, HANDLE hDIB, HPALETTE * phPal, HBITMAP * phBitmap)
145 LPBITMAPINFOHEADER lpInfo;
148 HPALETTE hPalette, hOldPal;
151 lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
152 if ((hPalette = MakeDIBPalette(lpInfo)) != 0)
154 /* Need to realize palette for converting DIB to bitmap. */
155 hOldPal = SelectPalette(hDC, hPalette, TRUE);
158 lpBits = ((LPSTR)lpInfo + (WORD)lpInfo->biSize +
159 (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD));
160 hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
161 (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
163 SelectPalette(hDC, hOldPal, TRUE);
168 DeleteObject(hPalette);
184 * ビットマップファイルを読み込み、BITMAPINFO構造体にハンドルを取得する。
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.
188 * device-dependent representation of the image.
189 * @param hWnd ウィンドウハンドル
190 * @param lpFileName 読み込むビットマップファイル
191 * @param pInfo 取得情報を補完するビットマップ情報構造体ポインタ
193 * Returns TRUE if the DIB is loaded and the bitmap/palette created, in which
194 * case, the DIBINIT structure pointed to by pInfo is filled with the appropriate
195 * handles, and FALSE if something went wrong.
197 * Reads a DIB from a file, obtains a handle to its BITMAPINFO struct, and
198 * loads the DIB. Once the DIB is loaded, the function also creates a bitmap
199 * and palette out of the DIB for a device-dependent form.
201 BOOL ReadDIB(HWND hWnd, LPSTR lpFileName, DIBINIT *pInfo)
203 LPBITMAPINFOHEADER lpbi;
211 BOOL bCoreHead = FALSE;
213 /* Open the file and get a handle to it's BITMAPINFO */
214 INT_PTR fh = OpenFile(lpFileName, &of, OF_READ);
217 wsprintf(str, "Can't open file '%s'", (LPSTR)lpFileName);
218 MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK);
222 pInfo->hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
223 256 * sizeof(RGBQUAD)));
228 lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
230 BOOL is_read_error = sizeof(bf) != _lread(fh, (LPSTR)&bf, sizeof(bf));
231 is_read_error |= bf.bfType != 0x4d42;
232 is_read_error |= sizeof(BITMAPCOREHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER));
235 global_free(pInfo, &fh, TRUE);
239 if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
241 lpbi->biSize = sizeof(BITMAPINFOHEADER);
242 lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
243 lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
244 lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
245 lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
250 /* get to the start of the header and read INFOHEADER */
251 _llseek(fh, sizeof(BITMAPFILEHEADER), SEEK_SET);
252 if (sizeof(BITMAPINFOHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
254 global_free(pInfo, &fh, TRUE);
259 nNumColors = (WORD)lpbi->biClrUsed;
262 /* no color table for 24-bit, default size otherwise */
263 if (lpbi->biBitCount != 24)
264 nNumColors = 1 << lpbi->biBitCount;
267 /* fill in some default values if they are zero */
268 if (lpbi->biClrUsed == 0)
269 lpbi->biClrUsed = nNumColors;
271 if (lpbi->biSizeImage == 0)
273 lpbi->biSizeImage = (((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
277 /* otherwise wouldn't work with 16 color bitmaps -- S.K. */
278 else if ((nNumColors == 16) && (lpbi->biSizeImage > bf.bfSize))
280 lpbi->biSizeImage /= 2;
283 /* get a proper-sized buffer for header, color table and bits */
284 GlobalUnlock(pInfo->hDIB);
285 pInfo->hDIB = GlobalReAlloc(pInfo->hDIB, lpbi->biSize +
286 nNumColors * sizeof(RGBQUAD) +
287 lpbi->biSizeImage, 0);
289 /* can't resize buffer for loading */
292 global_free(pInfo, &fh, FALSE);
296 lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
298 /* read the color table */
301 _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
309 _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
311 pQuad = (RGBQUAD*)((LPSTR)lpbi + lpbi->biSize);
312 pTriple = (RGBTRIPLE*) pQuad;
313 for (i = nNumColors - 1; i >= 0; i--)
315 pQuad[i].rgbRed = pTriple[i].rgbtRed;
316 pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
317 pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
318 pQuad[i].rgbReserved = 0;
322 /* offset to the bits from start of DIB header */
323 offBits = (WORD)lpbi->biSize + nNumColors * sizeof(RGBQUAD);
325 if (bf.bfOffBits != 0L)
327 _llseek(fh,bf.bfOffBits,SEEK_SET);
330 /* Use local version of '_lread()' above */
331 if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
333 GlobalUnlock(pInfo->hDIB);
336 if (!MakeBitmapAndPalette(hDC, pInfo->hDIB, &((HPALETTE)pInfo->hPalette),
337 &((HBITMAP)pInfo->hBitmap)))
340 global_free(pInfo, &fh, FALSE);
351 GlobalUnlock(pInfo->hDIB);
352 GlobalFree(pInfo->hDIB);
360 void global_free(DIBINIT *pInfo, INT_PTR *fh, BOOL unlock_needed)
364 GlobalUnlock(pInfo->hDIB);
367 GlobalFree(pInfo->hDIB);