Dib.cpp
上传用户:elida16851
上传日期:2022-08-05
资源大小:2048k
文件大小:18k
源码类别:

图形图象

开发平台:

Visual C++

  1. // Dib.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include <math.h>
  7. #include <windowsx.h> // especially for GlobalAllocPtr
  8. #include "Dib.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. IMPLEMENT_SERIAL(CDib, CObject, 0)
  15. ////////////////////////////////////////////////////////////////////////////
  16. CDib::CDib()
  17. {
  18. m_hDib = NULL;
  19. m_hBitmap   = NULL;
  20. m_pPalette  = NULL;
  21. m_pBitmap   = NULL;
  22. }           
  23.                                       
  24. CDib::~CDib()
  25. {
  26. Destroy();
  27. if (m_pBitmap != NULL)
  28. {
  29. delete m_pBitmap;
  30. m_pBitmap = NULL;
  31. }
  32. if (m_pPalette != NULL)
  33. {
  34. delete m_pPalette;
  35. m_pPalette = NULL;
  36. }
  37. }
  38. void CDib::Destroy()
  39. {
  40. if (m_hDib != NULL)
  41. {
  42. DestroyDIB(m_hDib);
  43. m_hDib = NULL;
  44. }
  45. }
  46. BOOL CDib::Create(DWORD dwWidth, DWORD dwHeight)
  47. {
  48. HDIB hDib = CreateDefaultDIB(dwWidth, dwHeight);
  49. if (! hDib)
  50. return FALSE;
  51. Destroy();
  52. m_hDib = hDib;
  53. return UpdateInternal();
  54. }
  55. BOOL CDib::Create(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
  56. {
  57. HDIB hDib = CreateDIB(dwWidth, dwHeight, wBitCount);
  58. if (! hDib)
  59. return FALSE;
  60. Destroy();
  61. m_hDib = hDib;
  62. return UpdateInternal();
  63. }
  64. BOOL CDib::Create(LPBYTE lpDIB)
  65. {
  66. if (lpDIB == NULL)
  67. return FALSE;
  68. DWORD dwSize = DIBlockSize(lpDIB);
  69.     HDIB hDib  = GlobalAlloc(GHND, dwSize); 
  70.     // Check that DIB handle is valid 
  71.     if (! hDib) 
  72.         return FALSE; 
  73.  
  74.     LPBYTE lpbi  = (LPBYTE)GlobalLock(hDib); 
  75. if (! lpbi)
  76.         return FALSE; 
  77. CopyMemory(lpbi, lpDIB, dwSize);
  78. GlobalUnlock(hDib);
  79. Destroy();
  80. m_hDib = hDib;
  81. return UpdateInternal();
  82. }
  83. BOOL CDib::Create(LPBYTE lpDIB,
  84.   WORD  wBitCount) // bits/pixel 
  85. {
  86. if (lpDIB == NULL)
  87. return FALSE;
  88. if (! Create(lpDIB))
  89. return FALSE;
  90. WORD wBits = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
  91. if (wBitCount == wBits)
  92. return TRUE;
  93. HDIB hNewDib = ConvertDIBFormat(m_hDib, wBitCount, NULL); 
  94. if (! hNewDib)
  95. return FALSE;
  96. Destroy();
  97. m_hDib = hNewDib;
  98. return UpdateInternal();
  99. }
  100. BOOL CDib::Create(HBITMAP hBitmap) // DIB Section
  101. {
  102. if (! hBitmap)
  103.         return FALSE; 
  104. HDIB hDib = DIBSectionToDIB(hBitmap); 
  105.     if (! hDib) 
  106.         return FALSE; 
  107. Destroy();
  108. m_hDib = hDib;
  109. return UpdateInternal();
  110. }
  111. BOOL CDib::Create(HBITMAP hBitmap, // DIB Section
  112.   WORD  wBitCount) // bits/pixel 
  113. {
  114. HDIB hNewDib;
  115. if (! hBitmap)
  116.         return FALSE; 
  117. HDIB hDib = DIBSectionToDIB(hBitmap); 
  118.     if (! hDib) 
  119.         return FALSE; 
  120. DIBSECTION ds;
  121. GetObject(hBitmap, sizeof(DIBSECTION), &ds);
  122. if (wBitCount == ds.dsBmih.biBitCount)
  123. hNewDib = hDib;
  124. else
  125. {
  126. hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL); 
  127. // cleanup hDib
  128. GlobalFree(hDib);
  129. }
  130. if (! hNewDib)
  131. return FALSE;
  132. Destroy();
  133. m_hDib = hNewDib;
  134. return UpdateInternal();
  135. }
  136. BOOL CDib::Create(HBITMAP hBitmap, // DDB bitmap
  137.       HPALETTE hPalette) // DDB palette
  138. {
  139. if (! hBitmap)
  140.         return FALSE; 
  141. HDIB hDib = BitmapToDIB(hBitmap, hPalette); 
  142.     if (! hDib) 
  143.         return FALSE; 
  144. Destroy();
  145. m_hDib = hDib;
  146. return UpdateInternal();
  147. }
  148. BOOL CDib::Create(HBITMAP hBitmap, // DDB bitmap
  149.       HPALETTE hPalette, // DDB palette
  150.   WORD  wBitCount) // bits/pixel 
  151. {
  152. if (! hBitmap)
  153.         return FALSE; 
  154. HDIB hDib = BitmapToDIB(hBitmap, hPalette, wBitCount); 
  155.     if (! hDib) 
  156.         return FALSE; 
  157. Destroy();
  158. m_hDib = hDib;
  159. return UpdateInternal();
  160. }
  161. BOOL CDib::Create(CRect rcScreen)
  162. {
  163. HDIB hDib = CopyScreenToDIB(rcScreen); 
  164.     if (! hDib) 
  165.         return FALSE; 
  166. Destroy();
  167. m_hDib = hDib;
  168. return UpdateInternal();
  169. }
  170. BOOL CDib::Create(HWND hWnd, WORD fPrintArea)
  171. {
  172. HDIB hDib = CopyWindowToDIB(hWnd, fPrintArea); 
  173.     if (! hDib) 
  174.         return FALSE; 
  175. Destroy();
  176. m_hDib = hDib;
  177. return UpdateInternal();
  178. }
  179. BOOL CDib::Create(HWND hWnd, CRect rcClientArea)
  180. {
  181. HDIB hDib = CopyClientRectToDIB(hWnd, rcClientArea); 
  182.     if (! hDib) 
  183.         return FALSE; 
  184. Destroy();
  185. m_hDib = hDib;
  186. return UpdateInternal();
  187. }
  188. void CDib::Serialize(CArchive& ar)
  189. {
  190. CObject::Serialize(ar);
  191. ar.Flush();
  192. if (ar.IsStoring())
  193. {
  194. Write(ar.GetFile());
  195. }
  196.     else
  197.     {
  198.     Read(ar.GetFile());
  199.     }
  200. }
  201. BOOL CDib::Load(UINT uIDS, LPCTSTR lpszDibType)
  202. {                                
  203. LPCTSTR lpszDibRes = MAKEINTRESOURCE(uIDS);
  204. return Load(lpszDibRes, lpszDibType);
  205. }
  206. BOOL CDib::Load(LPCTSTR lpszDibRes, LPCTSTR lpszDibType)
  207. {                                
  208. HINSTANCE hInst = AfxGetInstanceHandle();
  209. HRSRC   hRes    = ::FindResource(hInst, lpszDibRes, lpszDibType);
  210. HGLOBAL hData   = ::LoadResource(hInst, hRes);
  211. // if resource ok?
  212. if (hRes == NULL || hData == NULL)
  213. return FALSE;
  214. // get resource buffer
  215. LPBYTE lpBuf = (LPBYTE)::LockResource(hData);
  216. // is DIB ?
  217. if (((LPBITMAPFILEHEADER)lpBuf)->bfType != DIB_HEADER_MARKER/*"BM"*/)
  218. return FALSE;
  219. // use this buffer to create CDib
  220. LPBYTE lpDIB = lpBuf + sizeof(BITMAPFILEHEADER);
  221. return Create(lpDIB);
  222. }
  223. BOOL CDib::Load(LPCTSTR lpszDibFile)
  224. {                                
  225. TRY
  226. {
  227. CFile file(lpszDibFile, CFile::modeRead|CFile::shareDenyNone);
  228. if (! Read(&file))
  229. return FALSE;
  230. }
  231. CATCH (CException, e)
  232. {
  233. return FALSE;
  234. }
  235. END_CATCH
  236. return TRUE;
  237. }               
  238. BOOL CDib::Save(LPCSTR lpszDibFile)
  239. {
  240. TRY
  241. {
  242. CFile file(lpszDibFile, CFile::modeCreate|CFile::modeWrite);
  243. if (! Write(&file))
  244. return FALSE;
  245. }
  246. CATCH (CException, e)
  247. {
  248. return FALSE;
  249. }
  250. END_CATCH
  251. return TRUE;
  252. }
  253. BOOL CDib::Read(CFile *pFile)
  254. {
  255. WaitCursorBegin();
  256. LPBITMAPINFOHEADER lpbi;
  257. DWORD dwSize;
  258. TRY
  259. {
  260. // read DIB file header
  261. BITMAPFILEHEADER bmfHdr;
  262. pFile->Read(&bmfHdr, sizeof(BITMAPFILEHEADER));
  263. // is DIB file?
  264. if (bmfHdr.bfType != DIB_HEADER_MARKER/*"BM"*/)
  265. {
  266. WaitCursorEnd();
  267. return FALSE;
  268. }
  269. DWORD dwLength = pFile->GetLength();
  270. if (bmfHdr.bfSize != dwLength)
  271. bmfHdr.bfSize = dwLength;
  272. // read DIB buffer
  273. dwSize = bmfHdr.bfSize - sizeof(BITMAPFILEHEADER);
  274. lpbi = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, dwSize);
  275. DWORD dwCount = pFile->Read(lpbi, dwSize);
  276. // read ok?
  277. if (dwCount != dwSize)
  278. {
  279. GlobalFreePtr(lpbi);
  280. WaitCursorEnd();
  281. return FALSE;
  282. }
  283. // Check to see that it's a Windows DIB -- an OS/2 DIB would cause 
  284. // strange problems with the rest of the DIB API since the fields 
  285. // in the header are different and the color table entries are 
  286. // smaller. 
  287. // 
  288. // If it's not a Windows DIB (e.g. if biSize is wrong), return NULL. 
  289.     if (lpbi->biSize != sizeof(BITMAPINFOHEADER)) 
  290. {
  291. GlobalFreePtr(lpbi);
  292. WaitCursorEnd();
  293. return FALSE;
  294. }
  295. // fill color num item
  296. int nNumColors = (UINT)lpbi->biClrUsed;
  297. if (nNumColors == 0) 
  298. // no color table for 24-bit, default size otherwise 
  299.         if (lpbi->biBitCount != 24) 
  300.         nNumColors = 1 << lpbi->biBitCount; // standard size table 
  301.  
  302. // fill in some default values if they are zero 
  303.     if (lpbi->biClrUsed == 0) 
  304.     lpbi->biClrUsed = nNumColors; 
  305. if (lpbi->biSizeImage == 0) 
  306. lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight; 
  307.   }
  308. CATCH (CException, e)
  309. {
  310. GlobalFreePtr(lpbi);
  311. WaitCursorEnd();
  312. return FALSE;
  313. }
  314. END_CATCH
  315. // create CDib with DIB buffer
  316. BOOL bSuccess = Create((LPBYTE)lpbi);
  317. GlobalFreePtr(lpbi);
  318. WaitCursorEnd();
  319. return bSuccess;
  320. }
  321. BOOL CDib::Write(CFile *pFile)
  322. {
  323. WaitCursorBegin();
  324.     BITMAPFILEHEADER    bmfHdr;     // Header for Bitmap file 
  325.     LPBITMAPINFOHEADER  lpBI;       // Pointer to DIB info structure 
  326.     DWORD               dwDIBSize; 
  327. // Get a pointer to the DIB memory, the first of which contains 
  328.     // a BITMAPINFO structure 
  329.     lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib); 
  330.     if (!lpBI) 
  331. {
  332. GlobalUnlock(m_hDib);
  333. WaitCursorEnd();
  334.         return FALSE; 
  335. }
  336.  
  337.     // Check to see if we're dealing with an OS/2 DIB.  If so, don't 
  338.     // save it because our functions aren't written to deal with these 
  339.     // DIBs. 
  340.     if (lpBI->biSize != sizeof(BITMAPINFOHEADER)) 
  341.     { 
  342.         GlobalUnlock(m_hDib); 
  343. WaitCursorEnd();
  344.         return FALSE; 
  345.     } 
  346.  
  347.     // Fill in the fields of the file header 
  348.  
  349.     // Fill in file type (first 2 bytes must be "BM" for a bitmap) 
  350.  
  351.     bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM" 
  352.  
  353.     // Calculating the size of the DIB is a bit tricky (if we want to 
  354.     // do it right).  The easiest way to do this is to call GlobalSize() 
  355.     // on our global handle, but since the size of our global memory may have 
  356.     // been padded a few bytes, we may end up writing out a few too 
  357.     // many bytes to the file (which may cause problems with some apps, 
  358.     // like HC 3.0). 
  359.     // 
  360.     // So, instead let's calculate the size manually. 
  361.     // 
  362.     // To do this, find size of header plus size of color table.  Since the 
  363.     // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains 
  364.     // the size of the structure, let's use this. 
  365.  
  366.     // Partial Calculation 
  367.  
  368.     dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);   
  369.  
  370.     // Now calculate the size of the image 
  371.  
  372.     // It's an RLE bitmap, we can't calculate size, so trust the biSizeImage 
  373.     // field 
  374.  
  375.     if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) 
  376.         dwDIBSize += lpBI->biSizeImage; 
  377.     else 
  378.     { 
  379.         DWORD dwBmBitsSize;  // Size of Bitmap Bits only 
  380.  
  381.         // It's not RLE, so size is Width (DWORD aligned) * Height 
  382.  
  383.         dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * 
  384.                 lpBI->biHeight; 
  385.  
  386.         dwDIBSize += dwBmBitsSize; 
  387.  
  388.         // Now, since we have calculated the correct size, why don't we 
  389.         // fill in the biSizeImage field (this will fix any .BMP files which  
  390.         // have this field incorrect). 
  391.  
  392.         lpBI->biSizeImage = dwBmBitsSize; 
  393.     } 
  394.  
  395.  
  396.     // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) 
  397.                     
  398.     bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); 
  399.     bmfHdr.bfReserved1 = 0; 
  400.     bmfHdr.bfReserved2 = 0; 
  401.  
  402.     // Now, calculate the offset the actual bitmap bits will be in 
  403.     // the file -- It's the Bitmap file header plus the DIB header, 
  404.     // plus the size of the color table. 
  405.      
  406.     bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + 
  407.             PaletteSize((LPBYTE)lpBI); 
  408.  
  409.   TRY
  410. {
  411.     // Write the file header 
  412. pFile->Write(&bmfHdr, sizeof(BITMAPFILEHEADER));
  413. // write DIB buffer
  414. pFile->Write(lpBI, dwDIBSize);
  415. }
  416. CATCH (CException, e)
  417. {
  418.         GlobalUnlock(m_hDib); 
  419. WaitCursorEnd();
  420. return FALSE;
  421. }
  422. END_CATCH
  423. GlobalUnlock(m_hDib); 
  424. WaitCursorEnd();
  425. return TRUE;
  426. }
  427. BOOL CDib::Display(CDC* pDC, int xDest, int yDest, int nWidthDest, int nHeightDest, 
  428.      int xSrc, int ySrc, DWORD dwRop)
  429. {
  430. CDC MemDC;
  431. MemDC.CreateCompatibleDC(pDC);
  432. CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
  433. CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
  434.     pDC->RealizePalette();
  435. BOOL bSuccess = pDC->BitBlt( xDest, yDest, 
  436. nWidthDest, nHeightDest,
  437.     &MemDC, 
  438. xSrc, ySrc, 
  439. dwRop);
  440. MemDC.SelectObject(pOldBmp);
  441. pDC->SelectPalette(pOldPal, TRUE);
  442. return bSuccess;
  443. }
  444. BOOL CDib::Display(CDC * pDC, int xDest, int yDest, int nWidthDest, int nHeightDest, 
  445.    int xSrc, int ySrc, int nWidthSrc, int nHeightSrc, DWORD dwRop)
  446. {
  447. CDC MemDC;
  448. MemDC.CreateCompatibleDC(pDC);
  449. CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
  450. CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
  451.     pDC->RealizePalette();
  452. BOOL bSuccess = pDC->StretchBlt( xDest, yDest, 
  453. nWidthDest, nHeightDest,
  454.         &MemDC, 
  455. xSrc, ySrc, 
  456. nWidthSrc, nHeightSrc, 
  457. dwRop);
  458. MemDC.SelectObject(pOldBmp);
  459. pDC->SelectPalette(pOldPal, TRUE);
  460. return bSuccess;
  461. }
  462. BOOL CDib::Display(CDC * pDC, int x, int y, DWORD dwRop)
  463. {
  464. CDC MemDC;
  465. MemDC.CreateCompatibleDC(pDC);
  466. CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
  467. CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
  468.     pDC->RealizePalette();
  469. BOOL bSuccess = pDC->BitBlt(x, y, 
  470. GetWidth(), GetHeight(),
  471. &MemDC, 
  472. 0, 0, 
  473. dwRop);
  474. MemDC.SelectObject(pOldBmp);
  475. pDC->SelectPalette(pOldPal, TRUE);
  476. return bSuccess;
  477. }
  478. BOOL CDib::Display(CDC* pDC, CRect rcDest, CRect rcSrc, DWORD dwRop)
  479. {
  480. CDC MemDC;
  481. MemDC.CreateCompatibleDC(pDC);
  482. CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
  483. CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
  484.     pDC->RealizePalette();
  485. BOOL bSuccess = pDC->StretchBlt( rcDest.left, rcDest.top, 
  486. rcDest.Width(), rcDest.Height(),
  487.         &MemDC, 
  488. rcSrc.left, rcSrc.top, 
  489. rcSrc.Width(), rcSrc.Height(),
  490. dwRop);
  491. MemDC.SelectObject(pOldBmp);
  492. pDC->SelectPalette(pOldPal, TRUE);
  493. return bSuccess;
  494. }
  495. BOOL CDib::BuildBitmap()
  496. {
  497. if (m_pBitmap != NULL)
  498. {
  499. delete m_pBitmap;
  500. m_pBitmap = NULL;
  501. m_hBitmap = NULL;
  502. }
  503. m_hBitmap = DIBToDIBSection(m_hDib);
  504. if (m_hBitmap == NULL)
  505. return FALSE;
  506. m_pBitmap = new CBitmap;
  507. m_pBitmap->Attach(m_hBitmap);
  508. return TRUE;
  509. }
  510. BOOL CDib::BuildPalette()
  511. {
  512. if (m_pPalette != NULL)
  513. {
  514. delete m_pPalette;
  515. m_pPalette = NULL;
  516. }
  517. HPALETTE hPalette = CreateDIBPalette(m_hDib);
  518. if (hPalette == NULL)
  519. return FALSE;
  520. m_pPalette = new CPalette;
  521. m_pPalette->Attach(hPalette);
  522. return TRUE;
  523. }
  524. BOOL CDib::UpdateInternal()
  525. {
  526. BuildPalette();
  527. return BuildBitmap();
  528. }
  529. CPalette* CDib::GetPalette()
  530. {
  531. return m_pPalette;
  532. }
  533. CBitmap* CDib::GetBitmap()
  534. {
  535. return m_pBitmap;
  536. }
  537. BOOL CDib::IsEmpty()
  538. {
  539. if (m_hDib == NULL)
  540. return TRUE;
  541. if (! GlobalLock(m_hDib))
  542. return TRUE;
  543. GlobalUnlock(m_hDib);
  544. return FALSE;
  545. }
  546. DWORD CDib::GetCompression()
  547. {
  548.     LPBITMAPINFOHEADER lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib); 
  549.     if (!lpBI) 
  550. {
  551. GlobalUnlock(m_hDib);
  552.         return 0; 
  553. }
  554.  
  555. DWORD dwCompression = lpBI->biCompression;
  556. GlobalUnlock(m_hDib);
  557. return dwCompression;
  558. }
  559. WORD CDib::GetBitCount()
  560. {
  561.     LPBITMAPINFOHEADER lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib); 
  562.     if (!lpBI) 
  563. {
  564. GlobalUnlock(m_hDib);
  565.         return 0; 
  566. }
  567.  
  568. WORD wBitCount = lpBI->biBitCount;
  569. GlobalUnlock(m_hDib);
  570. return wBitCount;
  571. }
  572. LONG CDib::GetWidth()
  573. {
  574. // get DIB buffer pointer
  575.     LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib); 
  576. if (! lpDIB)
  577. {
  578. GlobalUnlock(m_hDib);
  579. return 0;
  580. }
  581. LONG lWidth = (LONG)DIBWidth(lpDIB);
  582. GlobalUnlock(m_hDib);
  583. return lWidth; 
  584. }
  585. LONG CDib::GetHeight()
  586. {
  587. // get DIB buffer pointer
  588.     LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib); 
  589. if (! lpDIB)
  590. {
  591. GlobalUnlock(m_hDib);
  592. return 0;
  593. }
  594. LONG lHeight = (LONG)DIBHeight(lpDIB);
  595. GlobalUnlock(m_hDib);
  596. return lHeight; 
  597. }
  598. LONG CDib::GetWidthBytes()
  599. {
  600. return WIDTHBYTES((GetWidth())*((DWORD)GetBitCount()));
  601. }
  602. COLORREF CDib::GetPixel(LONG x, LONG y)
  603. {
  604. COLORREF cColor;
  605. switch (GetBitCount())
  606. {
  607. case 1 : if (1<<(7-x%8) & 
  608. *(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)))
  609. cColor = RGB(255,255,255);
  610. else
  611. cColor = RGB(0,0,0);
  612. break;
  613. case 4 :
  614. {
  615. PALETTEENTRY PaletteColors[16];
  616. m_pPalette->GetPaletteEntries(0, 16, PaletteColors);
  617. int nIndex = (*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)) & 
  618.    (x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
  619. cColor = RGB(PaletteColors[nIndex].peRed,
  620.  PaletteColors[nIndex].peGreen,
  621.  PaletteColors[nIndex].peBlue);
  622. }
  623. break;
  624. case 8 :
  625. {
  626. PALETTEENTRY PaletteColors[256];
  627. m_pPalette->GetPaletteEntries(0, 256, PaletteColors);
  628. int nIndex = *(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y));
  629. cColor = RGB(PaletteColors[nIndex].peRed,
  630.  PaletteColors[nIndex].peGreen,
  631.  PaletteColors[nIndex].peBlue);
  632. }
  633. break;
  634. default: cColor = RGB(*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)),
  635.  *(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)+1),
  636.  *(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)+2));
  637. break;
  638. }
  639. return cColor;
  640. }
  641. LONG CDib::GetPixelOffset(LONG x, LONG y)
  642. {
  643. return (GetHeight()-y-1)*GetWidthBytes()+(x*GetBitCount())/8;
  644. }
  645. LPBYTE CDib::GetBitsPtr()
  646. {
  647.     LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib); 
  648.     if (! lpDIB) 
  649. {
  650. GlobalUnlock(m_hDib);
  651. return NULL;
  652. }
  653. LPBYTE lpData = FindDIBBits(lpDIB);
  654. GlobalUnlock(m_hDib);
  655. return lpData;
  656. }
  657. HANDLE CDib::GetHandle()
  658. {
  659. return m_hDib;
  660. }
  661. WORD CDib::GetColorNumber()
  662. {
  663.     LPBYTE lpBI = (LPBYTE)GlobalLock(m_hDib); 
  664.     if (! lpBI) 
  665. {
  666. GlobalUnlock(m_hDib);
  667. return 0;
  668. }
  669.  
  670. WORD wColors = DIBNumColors(lpBI);
  671. GlobalUnlock(m_hDib);
  672. return wColors;
  673. }
  674. WORD CDib::GetPaletteSize()
  675. {
  676.     LPBYTE lpBI = (LPBYTE)GlobalLock(m_hDib); 
  677.     if (! lpBI) 
  678. {
  679. GlobalUnlock(m_hDib);
  680. return 0;
  681. }
  682.  
  683. WORD wPalSize = PaletteSize(lpBI);
  684. GlobalUnlock(m_hDib);
  685. return wPalSize;
  686. }
  687. CDC* CDib::BeginPaint(CDC *pDC)
  688. {
  689. m_pMemDC = new CDC;
  690. m_pMemDC->CreateCompatibleDC(pDC);
  691. m_pPaletteTmp = m_pMemDC->SelectPalette(m_pPalette, TRUE);
  692. m_pMemDC->RealizePalette();
  693. m_pBitmapTmp = (CBitmap *)m_pMemDC->SelectObject(m_pBitmap);
  694. return m_pMemDC;
  695. }
  696. void CDib::EndPaint()
  697. {
  698. m_pMemDC->SelectObject(m_pBitmapTmp);
  699. m_pMemDC->SelectPalette(m_pPaletteTmp, TRUE);
  700. delete m_pMemDC;
  701. Create(m_hBitmap);
  702. }
  703. BOOL CDib::DisplayPalette(CDC* pDC, CRect rc)
  704. {
  705. return ::DisplayPalette(pDC->GetSafeHdc(), &rc, (HPALETTE)m_pPalette->GetSafeHandle());
  706. }
  707. CDib * CDib::Clone()
  708. {
  709. if (m_hDib == NULL)
  710. return NULL;
  711. HDIB hDIB = CopyHandle(m_hDib);
  712. if (hDIB == NULL)
  713. return NULL;
  714. CDib *pDib = new CDib;
  715. pDib->m_hDib = hDIB;
  716. pDib->BuildPalette();
  717. pDib->BuildBitmap();
  718. return pDib;
  719. }