00001 /*------------------------------------------------------------------------------ 00002 DIBCLASS.CPP -- © Adam King, 2000 00003 00004 Description: Class to store a Device-Independent Bitmap (DIB) 00005 00006 Notes: Some of this code was adapted from original code © Charles Petzold, 1992 00007 00008 ------------------------------------------------------------------------------*/ 00009 #define STRICT 00010 #include <windows.h> 00011 #include <windowsx.h> 00012 #pragma hdrstop 00013 #include <mem.h> 00014 00015 #include "dibclass.h" 00016 00017 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 00018 00019 00020 //------------------------------------------------------------------------------ 00021 // The DIB class 00022 //------------------------------------------------------------------------------ 00023 DIB::DIB() 00024 { 00025 // memset(this, 0, sizeof(DIB)); 00026 } 00027 00028 //------------------------------------------------------------------------------ 00029 // Clear all information from the DIB class, freeing any alocated memory 00030 //------------------------------------------------------------------------------ 00031 void DIB::Clear() 00032 { 00033 if(lpDib != NULL) 00034 GlobalFreePtr(lpDib); 00035 } 00036 00037 // Utility function to extract the Header Size from the DIB memory block 00038 DWORD DIB::GetDibInfoHeaderSize() 00039 { 00040 return (lpDib) ? ((LPBITMAPINFOHEADER)lpDib)->biSize : 0; 00041 } 00042 00043 // Utility function to extract the Width of the DIB 00044 DWORD DIB::GetDibWidth() 00045 { 00046 LPBITMAPINFOHEADER lpbmi; 00047 LPBITMAPCOREHEADER lpbmc; 00048 00049 lpbmi = (LPBITMAPINFOHEADER)lpDib; 00050 lpbmc = (LPBITMAPCOREHEADER)lpDib; 00051 00052 if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) 00053 return lpbmi->biWidth; 00054 else 00055 return (DWORD) lpbmc->bcWidth; 00056 } 00057 00058 // Utility function to extract the Height of the DIB 00059 DWORD DIB::GetDibHeight() 00060 { 00061 LPBITMAPINFOHEADER lpbmi; 00062 LPBITMAPCOREHEADER lpbmc; 00063 00064 lpbmi = (LPBITMAPINFOHEADER)lpDib; 00065 lpbmc = (LPBITMAPCOREHEADER)lpDib; 00066 00067 if(lpbmi->biSize == sizeof(BITMAPINFOHEADER)) 00068 return lpbmi->biHeight; 00069 else 00070 return (DWORD)lpbmc->bcHeight; 00071 } 00072 00073 // Read a DIB from a file into memory 00074 LPBITMAPINFO DIB::ReadDib(LPCSTR szFileName) 00075 { 00076 BITMAPFILEHEADER bmfh; 00077 DWORD dwDibSize, dwOffset, dwHeaderSize; 00078 HFILE hFile; 00079 WORD wDibRead; 00080 OFSTRUCT ofs; 00081 00082 if (-1 == (hFile = OpenFile(szFileName, &ofs, OF_READ | OF_SHARE_DENY_WRITE))) 00083 return NULL; 00084 00085 if(lpDib != NULL) 00086 { 00087 GlobalFreePtr(lpDib); 00088 lpDib = NULL; 00089 } 00090 00091 if(_lread(hFile, (LPSTR)&bmfh, sizeof(bmfh)) != sizeof(bmfh) || 00092 bmfh.bfType != * (WORD *) "BM") 00093 { 00094 _lclose (hFile); 00095 return NULL; 00096 } 00097 00098 if(lpDib != NULL) 00099 { 00100 GlobalFreePtr(lpDib); 00101 lpDib = NULL; 00102 } 00103 00104 dwDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER); 00105 00106 lpDib = (LPBITMAPINFO)GlobalAllocPtr(GMEM_MOVEABLE, dwDibSize); 00107 00108 if(lpDib == NULL) 00109 { 00110 _lclose (hFile); 00111 return NULL; 00112 } 00113 00114 dwOffset = 0 ; 00115 00116 while (dwDibSize > 0) 00117 { 00118 wDibRead = (WORD) MIN(32768ul, dwDibSize); 00119 00120 if (wDibRead != _lread (hFile, (LPSTR) (lpDib + dwOffset), wDibRead)) 00121 { 00122 _lclose (hFile); 00123 GlobalFreePtr (lpDib); 00124 return NULL; 00125 } 00126 00127 dwDibSize -= wDibRead; 00128 dwOffset += wDibRead; 00129 } 00130 00131 _lclose (hFile); 00132 00133 dwHeaderSize = GetDibInfoHeaderSize(); 00134 00135 // Check if header is legal 00136 if(dwHeaderSize < 12 || (dwHeaderSize > 12 && dwHeaderSize < 16)) 00137 { 00138 GlobalFreePtr (lpDib); 00139 return NULL; 00140 } 00141 00142 return lpDib; 00143 } 00144