/******************************Module*Header*******************************\ * Module Name: image.c * * DIB file (.BMP) utility functions. * * Copyright (c) 1994-1995 Microsoft Corporation * \**************************************************************************/ #include #include #include #include #include #include "image.h" /******************************Public*Routine******************************\ * bVerifyDIB * * Stripped down version of tkDIBImageLoadAW that verifies that a bitmap * file is valid and, if so, returns the bitmap dimensions. * * Returns: * TRUE if valid bitmap file; otherwise, FALSE. * \**************************************************************************/ BOOL bVerifyDIB(TCHAR *fileName, ULONG *pWidth, ULONG *pHeight) { BOOL bRet = FALSE; BITMAPFILEHEADER *pbmf; // Ptr to file header BITMAPINFOHEADER *pbmihFile; // Ptr to file's info header (if it exists) BITMAPCOREHEADER *pbmchFile; // Ptr to file's core header (if it exists) // These need to be cleaned up when we exit: HANDLE hFile = INVALID_HANDLE_VALUE; // File handle HANDLE hMap = (HANDLE) NULL; // Mapping object handle PVOID pvFile = (PVOID) NULL; // Ptr to mapped file // Map the DIB file into memory. hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) goto bVerifyDIB_cleanup; hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (!hMap) goto bVerifyDIB_cleanup; pvFile = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); if (!pvFile) goto bVerifyDIB_cleanup; // Check the file header. If the BFT_BITMAP magic number is there, // then the file format is a BITMAPFILEHEADER followed immediately // by either a BITMAPINFOHEADER or a BITMAPCOREHEADER. The bitmap // bits, in this case, are located at the offset bfOffBits from the // BITMAPFILEHEADER. // // Otherwise, this may be a raw BITMAPINFOHEADER or BITMAPCOREHEADER // followed immediately with the color table and the bitmap bits. pbmf = (BITMAPFILEHEADER *) pvFile; if ( pbmf->bfType == BFT_BITMAP ) pbmihFile = (BITMAPINFOHEADER *) ((PBYTE) pbmf + SIZEOF_BITMAPFILEHEADER); else pbmihFile = (BITMAPINFOHEADER *) pvFile; // Get the width and height from whatever header we have. // // We distinguish between BITMAPINFO and BITMAPCORE cases based upon // BITMAPINFOHEADER.biSize. // Note: need to use safe READDWORD macro because pbmihFile may // have only WORD alignment if it follows a BITMAPFILEHEADER. switch (READDWORD(&pbmihFile->biSize)) { case sizeof(BITMAPINFOHEADER): *pWidth = READDWORD(&pbmihFile->biWidth); *pHeight = READDWORD(&pbmihFile->biHeight); bRet = TRUE; break; case sizeof(BITMAPCOREHEADER): pbmchFile = (BITMAPCOREHEADER *) pbmihFile; // Convert BITMAPCOREHEADER to BITMAPINFOHEADER. *pWidth = (DWORD) pbmchFile->bcWidth; *pHeight = (DWORD) pbmchFile->bcHeight; bRet = TRUE; break; default: break; } bVerifyDIB_cleanup: if (pvFile) UnmapViewOfFile(pvFile); if (hMap) CloseHandle(hMap); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return bRet; }