cdib.cpp
上传用户:zhaobiao
上传日期:2013-10-27
资源大小:92k
文件大小:17k
源码类别:

OpenCV

开发平台:

Visual C++

  1. // cdib.cpp
  2. // new version for WIN32
  3. #include "stdafx.h"
  4. #include "cdib.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. IMPLEMENT_SERIAL(CDib, CObject, 0);
  11. CDib::CDib()
  12. {
  13. m_hFile = NULL;
  14. m_hBitmap = NULL;
  15. m_hPalette = NULL;
  16. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  17. Empty();
  18. }
  19. CDib::CDib(CSize size, int nBitCount)
  20. {
  21. m_hFile = NULL;
  22. m_hBitmap = NULL;
  23. m_hPalette = NULL;
  24. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  25. Empty();
  26. ComputePaletteSize(nBitCount);
  27. m_lpBMIH = (LPBITMAPINFOHEADER) new 
  28. char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];
  29. m_nBmihAlloc = crtAlloc;
  30. m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
  31. m_lpBMIH->biWidth = size.cx;
  32. m_lpBMIH->biHeight = size.cy;
  33. m_lpBMIH->biPlanes = 1;
  34. m_lpBMIH->biBitCount = nBitCount;
  35. m_lpBMIH->biCompression = BI_RGB;
  36. m_lpBMIH->biSizeImage = 0;
  37. m_lpBMIH->biXPelsPerMeter = 0;
  38. m_lpBMIH->biYPelsPerMeter = 0;
  39. m_lpBMIH->biClrUsed = m_nColorTableEntries;
  40. m_lpBMIH->biClrImportant = m_nColorTableEntries;
  41. ComputeMetrics();
  42. memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);
  43. m_lpImage = NULL;  // no data yet
  44. }
  45. CDib::CDib(CSize size, int nBitCount,LPBYTE lpimage)
  46. {
  47. m_hFile = NULL;
  48. m_hBitmap = NULL;
  49. m_hPalette = NULL;
  50. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  51. Empty();
  52. ComputePaletteSize(nBitCount);
  53. m_lpBMIH = (LPBITMAPINFOHEADER) new 
  54. char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];
  55. m_nBmihAlloc = crtAlloc;
  56. m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
  57. m_lpBMIH->biWidth = size.cx;
  58. m_lpBMIH->biHeight = size.cy;
  59. m_lpBMIH->biPlanes = 1;
  60. m_lpBMIH->biBitCount = nBitCount;
  61. m_lpBMIH->biCompression = BI_RGB;
  62. m_lpBMIH->biSizeImage = 0;
  63. m_lpBMIH->biXPelsPerMeter = 0;
  64. m_lpBMIH->biYPelsPerMeter = 0;
  65. m_lpBMIH->biClrUsed = m_nColorTableEntries;
  66. m_lpBMIH->biClrImportant = m_nColorTableEntries;
  67. ComputeMetrics();
  68. memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);
  69. m_lpImage = lpimage;  // no data yet
  70. }
  71. CDib::~CDib()
  72. {
  73. Empty();
  74. }
  75. CSize CDib::GetDimensions()
  76. {
  77. if(m_lpBMIH == NULL) return CSize(0, 0);
  78. return CSize((int) m_lpBMIH->biWidth, (int) m_lpBMIH->biHeight);
  79. }
  80. BOOL CDib::AttachMapFile(const char* strPathname, BOOL bShare) // for reading
  81. {
  82. // if we open the same file twice, Windows treats it as 2 separate files
  83. // doesn't work with rare BMP files where # palette entries > biClrUsed
  84. HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ,
  85. bShare ? FILE_SHARE_READ : 0,
  86. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  87. ASSERT(hFile != INVALID_HANDLE_VALUE);
  88. DWORD dwFileSize = ::GetFileSize(hFile, NULL);
  89. HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
  90. DWORD dwErr = ::GetLastError();
  91. if(hMap == NULL)
  92. {
  93. AfxMessageBox("Empty bitmap file");
  94. return FALSE;
  95. }
  96. LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file
  97. ASSERT(lpvFile != NULL);
  98. if(((LPBITMAPFILEHEADER) lpvFile)->bfType != 0x4d42)
  99. {
  100. AfxMessageBox("Invalid bitmap file");
  101. DetachMapFile();
  102. return FALSE;
  103. }
  104. AttachMemory((LPBYTE) lpvFile + sizeof(BITMAPFILEHEADER));
  105. m_lpvFile = lpvFile;
  106. m_hFile = hFile;
  107. m_hMap = hMap;
  108. return TRUE;
  109. }
  110. BOOL CDib::CopyToMapFile(const char* strPathname)
  111. {
  112. // copies DIB to a new file, releases prior pointers
  113. // if you previously used CreateSection, the HBITMAP will be NULL (and unusable)
  114. BITMAPFILEHEADER bmfh;
  115. bmfh.bfType = 0x4d42;  // 'BM'
  116. bmfh.bfSize = m_dwSizeImage + sizeof(BITMAPINFOHEADER) +
  117. sizeof(RGBQUAD) * m_nColorTableEntries + sizeof(BITMAPFILEHEADER);
  118. // meaning of bfSize open to interpretation
  119. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  120. bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  121. sizeof(RGBQUAD) * m_nColorTableEntries;
  122. HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 0, NULL,
  123. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  124. ASSERT(hFile != INVALID_HANDLE_VALUE);
  125. int nSize =  sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  126. sizeof(RGBQUAD) * m_nColorTableEntries +  m_dwSizeImage;
  127. HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, nSize, NULL);
  128. DWORD dwErr = ::GetLastError();
  129. ASSERT(hMap != NULL);
  130. LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file
  131. ASSERT(lpvFile != NULL);
  132. LPBYTE lpbCurrent = (LPBYTE) lpvFile;
  133. memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // file header
  134. lpbCurrent += sizeof(BITMAPFILEHEADER);
  135. LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent;
  136. memcpy(lpbCurrent, m_lpBMIH,
  137. sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries); // info
  138. lpbCurrent += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
  139. memcpy(lpbCurrent, m_lpImage, m_dwSizeImage); // bit image
  140. DWORD dwSizeImage = m_dwSizeImage;
  141. Empty();
  142. m_dwSizeImage = dwSizeImage;
  143. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  144. m_lpBMIH = lpBMIH;
  145. m_lpImage = lpbCurrent;
  146. m_hFile = hFile;
  147. m_hMap = hMap;
  148. m_lpvFile = lpvFile;
  149. ComputePaletteSize(m_lpBMIH->biBitCount);
  150. ComputeMetrics();
  151. MakePalette();
  152. return TRUE;
  153. }
  154. BOOL CDib::AttachMemory(LPVOID lpvMem, BOOL bMustDelete, HGLOBAL hGlobal)
  155. {
  156. // assumes contiguous BITMAPINFOHEADER, color table, image
  157. // color table could be zero length
  158. Empty();
  159. m_hGlobal = hGlobal;
  160. if(bMustDelete == FALSE)
  161. {
  162. m_nBmihAlloc = noAlloc;
  163. }
  164. else
  165. {
  166. m_nBmihAlloc = ((hGlobal == NULL) ? crtAlloc : heapAlloc);
  167. }
  168. try
  169. {
  170. m_lpBMIH = (LPBITMAPINFOHEADER) lpvMem;
  171. ComputeMetrics();
  172. ComputePaletteSize(m_lpBMIH->biBitCount);
  173. m_lpImage = (LPBYTE) m_lpvColorTable + sizeof(RGBQUAD) * m_nColorTableEntries;
  174. MakePalette();
  175. }
  176. catch(CException* pe)
  177. {
  178. AfxMessageBox("AttachMemory error");
  179. pe->Delete();
  180. return FALSE;
  181. }
  182. return TRUE;
  183. }
  184. UINT CDib::UsePalette(CDC* pDC, BOOL bBackground /* = FALSE */)
  185. {
  186. if(m_hPalette == NULL) return 0;
  187. HDC hdc = pDC->GetSafeHdc();
  188. ::SelectPalette(hdc, m_hPalette, bBackground);
  189. return ::RealizePalette(hdc);
  190. }
  191. BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)
  192. {
  193. if(m_lpBMIH == NULL) return FALSE;
  194. if(m_hPalette != NULL)
  195. {
  196. ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
  197. }
  198. pDC->SetStretchBltMode(COLORONCOLOR);
  199. ::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,
  200. 0, 0, m_lpBMIH->biWidth, m_lpBMIH->biHeight,
  201. m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);
  202. return TRUE;
  203. }
  204. HBITMAP CDib::CreateSection(CDC* pDC /* = NULL */)
  205. {
  206. if(m_lpBMIH == NULL) return NULL;
  207. if(m_lpImage != NULL) return NULL; // can only do this if image doesn't exist
  208. m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
  209. DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
  210. ASSERT(m_lpImage != NULL);
  211. return m_hBitmap;
  212. }
  213. BOOL CDib::MakePalette()
  214. {
  215. // makes a logical palette (m_hPalette) from the DIB's color table
  216. // this palette will be selected and realized prior to drawing the DIB
  217. if(m_nColorTableEntries == 0) return FALSE;
  218. if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
  219. TRACE("CDib::MakePalette -- m_nColorTableEntries = %dn", m_nColorTableEntries);
  220. LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
  221. m_nColorTableEntries * sizeof(PALETTEENTRY)];
  222. pLogPal->palVersion = 0x300;
  223. pLogPal->palNumEntries = m_nColorTableEntries;
  224. LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;
  225. for(int i = 0; i < m_nColorTableEntries; i++)
  226. {
  227. pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
  228. pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
  229. pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
  230. pLogPal->palPalEntry[i].peFlags = 0;
  231. pDibQuad++;
  232. }
  233. m_hPalette = ::CreatePalette(pLogPal);
  234. delete pLogPal;
  235. return TRUE;
  236. }
  237. BOOL CDib::SetSystemPalette(CDC* pDC)
  238. {
  239. // if the DIB doesn't have a color table, we can use the system's halftone palette
  240. if(m_nColorTableEntries != 0) return FALSE;
  241. m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());
  242. return TRUE;
  243. }
  244. HBITMAP CDib::CreateBitmap(CDC* pDC)
  245. {
  246.     if (m_dwSizeImage == 0) return NULL;
  247.     HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), m_lpBMIH,
  248.             CBM_INIT, m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS);
  249.     ASSERT(hBitmap != NULL);
  250.     return hBitmap;
  251. }
  252. BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */)
  253. {
  254. // 1. makes GDI bitmap from existing DIB
  255. // 2. makes a new DIB from GDI bitmap with compression
  256. // 3. cleans up the original DIB
  257. // 4. puts the new DIB in the object
  258. if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FALSE;
  259. // compression supported only for 4 bpp and 8 bpp DIBs
  260. if(m_hBitmap) return FALSE; // can't compress a DIB Section!
  261. TRACE("Compress: original palette size = %dn", m_nColorTableEntries); 
  262. HDC hdc = pDC->GetSafeHdc();
  263. HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE);
  264. HBITMAP hBitmap;  // temporary
  265. if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE;
  266. int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
  267. LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  268. memcpy(lpBMIH, m_lpBMIH, nSize);  // new header
  269. if(bCompress)
  270. {
  271. switch (lpBMIH->biBitCount)
  272. {
  273. case 4:
  274. lpBMIH->biCompression = BI_RLE4;
  275. break;
  276. case 8:
  277. lpBMIH->biCompression = BI_RLE8;
  278. break;
  279. default:
  280. ASSERT(FALSE);
  281. }
  282. // calls GetDIBits with null data pointer to get size of compressed DIB
  283. if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,
  284. NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS))
  285. {
  286. AfxMessageBox("Unable to compress this DIB");
  287. // probably a problem with the color table
  288.   ::DeleteObject(hBitmap);
  289. delete [] lpBMIH;
  290. ::SelectPalette(hdc, hOldPalette, FALSE);
  291. return FALSE; 
  292. }
  293. if (lpBMIH->biSizeImage == 0)
  294. {
  295. AfxMessageBox("Driver can't do compression");
  296.   ::DeleteObject(hBitmap);
  297. delete [] lpBMIH;
  298. ::SelectPalette(hdc, hOldPalette, FALSE);
  299. return FALSE; 
  300. }
  301. else
  302. {
  303. m_dwSizeImage = lpBMIH->biSizeImage;
  304. }
  305. }
  306. else
  307. {
  308. lpBMIH->biCompression = BI_RGB; // decompress
  309. // figure the image size from the bitmap width and height
  310. DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32;
  311. if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32)
  312. {
  313. dwBytes++;
  314. }
  315. dwBytes *= 4;
  316. m_dwSizeImage = dwBytes * lpBMIH->biHeight; // no compression
  317. lpBMIH->biSizeImage = m_dwSizeImage;
  318. // second GetDIBits call to make DIB
  319. LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage];
  320. VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,
  321.      lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS));
  322.     TRACE("dib successfully created - height = %dn", lpBMIH->biHeight);
  323. ::DeleteObject(hBitmap);
  324. Empty();
  325. m_nBmihAlloc = m_nImageAlloc = crtAlloc;
  326. m_lpBMIH = lpBMIH;
  327. m_lpImage = lpImage;
  328. ComputeMetrics();
  329. ComputePaletteSize(m_lpBMIH->biBitCount);
  330. MakePalette();
  331. ::SelectPalette(hdc, hOldPalette, FALSE);
  332. TRACE("Compress: new palette size = %dn", m_nColorTableEntries); 
  333. return TRUE;
  334. }
  335. BOOL CDib::Read(CFile* pFile)
  336. {
  337. // 1. read file header to get size of info hdr + color table
  338. // 2. read info hdr (to get image size) and color table
  339. // 3. read image
  340. // can't use bfSize in file header
  341. // 清除DIB
  342. Empty();
  343. int nCount, nSize;
  344. BITMAPFILEHEADER bmfh;
  345. // 尝试读取BMP文件
  346. try
  347. {
  348. // 读BMP文件头
  349. nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  350. // 判断读取文件头的大小是否
  351. if(nCount != sizeof(BITMAPFILEHEADER))
  352. {
  353. // 读文件出错
  354. throw new CException;
  355. }
  356. // 判断是否是"BM"
  357. if(bmfh.bfType != 0x4d42)
  358. {
  359. // 不是BMP文件,抛出异常
  360. throw new CException;
  361. }
  362. nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
  363. m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  364. m_nBmihAlloc = m_nImageAlloc = crtAlloc;
  365. nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
  366. ComputeMetrics();
  367. ComputePaletteSize(m_lpBMIH->biBitCount);
  368. MakePalette();
  369. m_lpImage = (LPBYTE) new char[m_dwSizeImage];
  370. nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
  371. }
  372. catch(CException* pe)
  373. {
  374. AfxMessageBox("Read error");
  375. pe->Delete();
  376. return FALSE;
  377. }
  378. return TRUE;
  379. }
  380. BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */)
  381. {
  382. // new function reads BMP from disk and creates a DIB section
  383. //    allows modification of bitmaps from disk
  384. // 1. read file header to get size of info hdr + color table
  385. // 2. read info hdr (to get image size) and color table
  386. // 3. create DIB section based on header parms
  387. // 4. read image into memory that CreateDibSection allocates
  388. Empty();
  389. int nCount, nSize;
  390. BITMAPFILEHEADER bmfh;
  391. try
  392. {
  393. nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  394. if(nCount != sizeof(BITMAPFILEHEADER))
  395. {
  396. throw new CException;
  397. }
  398. if(bmfh.bfType != 0x4d42)
  399. {
  400. throw new CException;
  401. }
  402. nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
  403. m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  404. m_nBmihAlloc = crtAlloc;
  405. m_nImageAlloc = noAlloc;
  406. nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
  407. if(m_lpBMIH->biCompression != BI_RGB)
  408. {
  409. throw new CException;
  410. }
  411. ComputeMetrics();
  412. ComputePaletteSize(m_lpBMIH->biBitCount);
  413. MakePalette();
  414. UsePalette(pDC);
  415. m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
  416. DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
  417. ASSERT(m_lpImage != NULL);
  418. nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
  419. }
  420. catch(CException* pe)
  421. {
  422. AfxMessageBox("ReadSection error");
  423. pe->Delete();
  424. return FALSE;
  425. }
  426. return TRUE;
  427. }
  428. BOOL CDib::Write(CFile* pFile)
  429. {
  430. BITMAPFILEHEADER bmfh;
  431. bmfh.bfType = 0x4d42;  // 'BM'
  432. int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
  433. bmfh.bfSize = 0;
  434. // bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage;
  435. // meaning of bfSize open to interpretation (bytes, words, dwords?) -- we won't use it
  436. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  437. bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  438. sizeof(RGBQUAD) * m_nColorTableEntries;
  439. try
  440. {
  441. pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  442. pFile->Write((LPVOID) m_lpBMIH,  nSizeHdr);
  443. pFile->Write((LPVOID) m_lpImage, m_dwSizeImage);
  444. }
  445. catch(CException* pe)
  446. {
  447. pe->Delete();
  448. AfxMessageBox("write error");
  449. return FALSE;
  450. }
  451. return TRUE;
  452. }
  453. void CDib::Serialize(CArchive& ar)
  454. {
  455. DWORD dwPos;
  456. dwPos = ar.GetFile()->GetPosition();
  457. TRACE("CDib::Serialize -- pos = %dn", dwPos);
  458. ar.Flush();
  459. dwPos = ar.GetFile()->GetPosition();
  460. TRACE("CDib::Serialize -- pos = %dn", dwPos);
  461. if(ar.IsStoring())
  462. {
  463. Write(ar.GetFile());
  464. }
  465. else
  466. {
  467. Read(ar.GetFile());
  468. }
  469. }
  470. // helper functions
  471. void CDib::ComputePaletteSize(int nBitCount)
  472. {
  473. if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0))
  474. {
  475. switch(nBitCount)
  476. {
  477. case 1:
  478. m_nColorTableEntries = 2;
  479. break;
  480. case 4:
  481. m_nColorTableEntries = 16;
  482. break;
  483. case 8:
  484. m_nColorTableEntries = 256;
  485. break;
  486. case 16:
  487. case 24:
  488. case 32:
  489. m_nColorTableEntries = 0;
  490. break;
  491. default:
  492. ASSERT(FALSE);
  493. }
  494. }
  495. else
  496. {
  497. m_nColorTableEntries = m_lpBMIH->biClrUsed;
  498. }
  499. ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256)); 
  500. }
  501. void CDib::ComputeMetrics()
  502. {
  503. if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER))
  504. {
  505. TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmapn");
  506. throw new CException;
  507. }
  508. m_dwSizeImage = m_lpBMIH->biSizeImage;
  509. if(m_dwSizeImage == 0)
  510. {
  511. DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32;
  512. if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32)
  513. {
  514. dwBytes++;
  515. }
  516. dwBytes *= 4;
  517. m_dwSizeImage = dwBytes * m_lpBMIH->biHeight; // no compression
  518. }
  519. m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);
  520. }
  521. void CDib::Empty()
  522. {
  523. // this is supposed to clean up whatever is in the DIB
  524. DetachMapFile();
  525. if(m_nBmihAlloc == crtAlloc)
  526. {
  527. delete [] m_lpBMIH;
  528. }
  529. else if(m_nBmihAlloc == heapAlloc)
  530. {
  531. ::GlobalUnlock(m_hGlobal);
  532. ::GlobalFree(m_hGlobal);
  533. }
  534. if(m_nImageAlloc == crtAlloc)
  535. {
  536. delete [] m_lpImage;
  537. }
  538. if(m_hPalette != NULL)
  539. {
  540. ::DeleteObject(m_hPalette);
  541. }
  542. if(m_hBitmap != NULL)
  543. {
  544. ::DeleteObject(m_hBitmap);
  545. }
  546. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  547. m_hGlobal = NULL;
  548. m_lpBMIH = NULL;
  549. m_lpImage = NULL;
  550. m_lpvColorTable = NULL;
  551. m_nColorTableEntries = 0;
  552. m_dwSizeImage = 0;
  553. m_lpvFile = NULL;
  554. m_hMap = NULL;
  555. m_hFile = NULL;
  556. m_hBitmap = NULL;
  557. m_hPalette = NULL;
  558. }
  559. void CDib::DetachMapFile()
  560. {
  561. if(m_hFile == NULL)
  562. {
  563. return;
  564. }
  565. ::UnmapViewOfFile(m_lpvFile);
  566. ::CloseHandle(m_hMap);
  567. ::CloseHandle(m_hFile);
  568. m_hFile = NULL;
  569. }