Dib.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Dib.cpp: implementation of the CDib class.
  2. // Download by http://www.NewXing.com
  3. //////////////////////////////////////////////////////////////////////
  4. #include "StdAfx.h"
  5. #include "Dib.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CDib::CDib()
  15. {
  16. m_hDrawDib=NULL;
  17. m_pDib=NULL;
  18. }
  19. CDib::~CDib()
  20. {
  21. Close();
  22. }
  23. void CDib::Draw(CDC *pDC,int nWidth, int nHeight)
  24. {
  25. if(m_pDib!=NULL)
  26. {
  27. ASSERT(IsValid());
  28. DrawDibRealize(m_hDrawDib,pDC->GetSafeHdc(),TRUE);
  29. DrawDibDraw(m_hDrawDib,pDC->GetSafeHdc(),
  30. 0, //desktop left
  31. 0, //desktop top
  32. nWidth,
  33. nHeight,
  34. (BITMAPINFOHEADER *)m_pDib,
  35. (LPVOID) GetBits(),
  36. 0, //source left
  37. 0, //source top
  38. ((BITMAPINFOHEADER *)m_pDib)->biWidth,
  39. ((BITMAPINFOHEADER *)m_pDib)->biHeight,
  40. DDF_BACKGROUNDPAL);
  41. }
  42. }
  43. CSize CDib::GetSize()
  44. {
  45. return CSize(((BITMAPINFOHEADER *)m_pDib)->biWidth,
  46. ((BITMAPINFOHEADER *)m_pDib)->biHeight);
  47. }
  48. LONG CDib::GetWidth()
  49. {
  50. return ((BITMAPINFOHEADER *)m_pDib)->biWidth;
  51. }
  52. LONG CDib::GetHeight()
  53. {
  54. return ((BITMAPINFOHEADER *)m_pDib)->biHeight;
  55. }
  56. void CDib::Close()
  57. {
  58. if(m_hDrawDib!=NULL)
  59. {
  60. DrawDibClose(m_hDrawDib);
  61. m_hDrawDib=NULL;
  62. }
  63. if(m_pDib!=NULL)
  64. {
  65. delete m_pDib;
  66. m_pDib=NULL;
  67. }
  68. }
  69. BOOL CDib::Open(const char * pzFileName)
  70. {
  71. // BITMAPFILEHEADER bmpFileHeader;
  72. CFile file;
  73. int nBmpFileHeaderSize;
  74. Close();
  75. //drawdibopen initialize the diradib library and
  76. //returns a handle for all drawdib operations
  77. if(!(m_hDrawDib=DrawDibOpen()))
  78. goto exit;
  79. //open and read the DIB file header
  80. nBmpFileHeaderSize=sizeof(BITMAPFILEHEADER);
  81. if(!file.Open(pzFileName,CFile::modeRead | CFile::typeBinary))
  82. goto exit;
  83. if(file.Read((void *)&bmpFileHeader,nBmpFileHeaderSize)!=(UINT)nBmpFileHeaderSize)
  84. goto failure;
  85. //validate the DIB file header by checking the first
  86. //two characters for the signature "BM"
  87. if(bmpFileHeader.bfType!=*((WORD *)"BM"))
  88. goto failure;
  89. //allocate a big chuck of global memory to store the DIB
  90. m_pDib=(BYTE *)new char [bmpFileHeader.bfSize-nBmpFileHeaderSize];
  91. //allocate memory fail
  92. if(!m_pDib)
  93. goto failure;
  94. //read the dib into the buffer at a time using ReadHuge
  95. //file.ReadHuge(m_pDib,bmpFileHeader.bfSize-nBmpFileHeaderSize);
  96. file.Read(m_pDib,bmpFileHeader.bfSize-nBmpFileHeaderSize);
  97. if(((BITMAPINFOHEADER *)m_pDib)->biSizeImage==0)
  98. {
  99. //the application that create this bitmap didn't fill
  100. //in the biSizeImage field. Let's fill it
  101. //in even though the DrawDib * functions don't need it.
  102. BITMAPINFOHEADER *pDib=(BITMAPINFOHEADER *)m_pDib;
  103. //scan lines must be DWord aligned, hence the strange bit stuff
  104. pDib->biSizeImage=((((pDib->biWidth*pDib->biBitCount)+31)&~31)>>3)*pDib->biHeight;
  105. }
  106. m_pDibBits=GetBits();
  107. file.Close();
  108. return TRUE;
  109. failure:
  110. file.Close();
  111. exit:
  112. Close();
  113. return FALSE;
  114. }
  115. BOOL CDib::Save(const char * pzFileName)
  116. {
  117. // BITMAPFILEHEADER bmpFileHeader;
  118. CFile file;
  119. int nBmpFileHeaderSize;
  120. //open and read the DIB file header
  121. nBmpFileHeaderSize=sizeof(BITMAPFILEHEADER);
  122. if(!file.Open(pzFileName,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary))
  123. goto exit;
  124. file.Write(&bmpFileHeader,nBmpFileHeaderSize);
  125. //allocate memory fail
  126. if(!m_pDib)
  127. goto failure;
  128. //read the dib into the buffer at a time using ReadHuge
  129. //file.WriteHuge(m_pDib,bmpFileHeader.bfSize-nBmpFileHeaderSize);
  130. file.Write(m_pDib,bmpFileHeader.bfSize-nBmpFileHeaderSize);
  131. file.Close();
  132. return TRUE;
  133. failure:
  134. file.Close();
  135. exit:
  136. return FALSE;
  137. }
  138. BYTE * CDib::GetBits()
  139. {
  140. //the size of the color map is determined by the number
  141. //of RGBQUAD structures presend.
  142. //it also depends on the bit_depth of the Dib
  143. DWORD dwNumColors,dwColorTableSize;
  144. BITMAPINFOHEADER *lpDib=(BITMAPINFOHEADER *)m_pDib;
  145. WORD wBitCount=lpDib->biBitCount;
  146. if(lpDib->biSize>=36)
  147. dwNumColors=lpDib->biClrUsed;
  148. else
  149. dwNumColors=0;
  150. if(dwNumColors==0)
  151. {
  152. if(wBitCount!=24)
  153. dwNumColors=1L<<wBitCount;
  154. else
  155. dwNumColors=0;
  156. }
  157. dwColorTableSize=dwNumColors*sizeof(RGBQUAD);
  158. return m_pDib+lpDib->biSize+dwColorTableSize;
  159. }
  160. int CDib::GetBiBitCount()
  161. {
  162. if(m_pDib!=NULL)
  163. return ((BITMAPINFOHEADER *)m_pDib)->biBitCount;
  164. return 0;
  165. }