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