CDIB.CPP
Upload User: szkelitina
Upload Date: 2022-05-21
Package Size: 6797k
Code Size: 10k
Category:

Special Effects

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #include "cdib.h"
  3. #include "windowsx.h"
  4. #include "math.h"
  5. #define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4) 
  6. CDib::CDib()
  7. {
  8. // size=0;
  9. // LoadFile();
  10. }
  11. CDib::~CDib()
  12. {
  13.     GlobalFreePtr(m_pBitmapInfo);
  14. }
  15. void CDib::LoadFile(const char* dibFileName)
  16. {
  17. strcpy(m_fileName,dibFileName);
  18.     CFile dibFile(m_fileName, CFile::modeRead);
  19.     
  20.     dibFile.Read((void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
  21.     if (bitmapFileHeader.bfType == 0x4d42)
  22.     {
  23.         DWORD fileLength = dibFile.GetLength();    
  24.         DWORD size = fileLength -
  25. sizeof(BITMAPFILEHEADER);
  26.         BYTE* pDib =
  27.             (BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, size);
  28.         dibFile.Read((void*)pDib, size);
  29.         dibFile.Close();
  30.         m_pBitmapInfo = (BITMAPINFO*) pDib;
  31.         m_pBitmapInfoHeader = (BITMAPINFOHEADER*) pDib;
  32.         m_pRGB = (RGBQUAD*)(pDib +
  33. m_pBitmapInfoHeader->biSize);
  34.         int m_numberOfColors = GetNumberOfColors();
  35.         if (m_pBitmapInfoHeader->biClrUsed == 0)
  36.             m_pBitmapInfoHeader->biClrUsed =
  37.     m_numberOfColors;
  38. colorTableSize = m_numberOfColors *
  39.             sizeof(RGBQUAD);
  40. //////////////////////////////////////////////////////////
  41. // if(m_pBitmapInfoHeader->biBitCount==24)
  42. // m_pData = pDib + m_pBitmapInfoHeader->biSize;
  43.       ///  else
  44.         m_pData = pDib + m_pBitmapInfoHeader->biSize
  45.             + colorTableSize;
  46. //////////////////////////////////////////////////////////
  47. if (m_pRGB == (RGBQUAD*)m_pData) // No color table
  48. m_pRGB = NULL;
  49.         m_pBitmapInfoHeader->biSizeImage = GetSize();
  50. m_valid = TRUE;
  51.     }    
  52.     else
  53.     {
  54.         m_valid = FALSE;
  55.         AfxMessageBox("This isn't a bitmap file!");
  56.     }
  57. }
  58. BOOL CDib::IsValid()
  59. {
  60.     return m_valid;
  61. }
  62.         
  63. char* CDib::GetFileName()
  64. {
  65.     return m_fileName;
  66. }
  67.         
  68. UINT CDib::GetWidth()
  69. {
  70.     return (UINT) m_pBitmapInfoHeader->biWidth;
  71. }
  72.         
  73. UINT CDib::GetHeight()
  74. {
  75.     return (UINT) m_pBitmapInfoHeader->biHeight;
  76. }
  77.         
  78. DWORD CDib::GetSize()
  79. {
  80.     if (m_pBitmapInfoHeader->biSizeImage != 0)
  81.         return m_pBitmapInfoHeader->biSizeImage;
  82. else
  83.     {
  84.         DWORD height = (DWORD) GetHeight();
  85.         DWORD width = (DWORD) GetWidth();
  86.         return height * width;
  87.     }
  88. }
  89. UINT CDib::GetNumberOfColors()
  90. {
  91. int numberOfColors;
  92.     if ((m_pBitmapInfoHeader->biClrUsed == 0) &&
  93.           (m_pBitmapInfoHeader->biBitCount < 9))
  94. {
  95. switch (m_pBitmapInfoHeader->biBitCount)
  96. {
  97.     case 1: numberOfColors = 2; break;
  98.     case 4: numberOfColors = 16; break;
  99.     case 8: numberOfColors = 256;
  100. }
  101. }
  102.     else
  103. numberOfColors = (int) m_pBitmapInfoHeader->biClrUsed;
  104.     return numberOfColors;
  105. }
  106. DWORD CDib::GetDibWidthBytes()
  107. {  
  108. byBitCount=m_pBitmapInfoHeader->biBitCount;
  109. LONG nWidth=m_pBitmapInfoHeader->biWidth;
  110. dwWidthBytes = (DWORD)m_pBitmapInfoHeader->biWidth; //8-bits
  111. if(byBitCount == 1) dwWidthBytes = (nWidth + 7) / 8;
  112. else if(byBitCount == 4) dwWidthBytes = (nWidth + 1) / 2;
  113. else if(byBitCount == 24) dwWidthBytes = 3 * nWidth ;
  114. while((dwWidthBytes & 3) != 0)dwWidthBytes++;
  115. return dwWidthBytes;
  116. }  
  117.   
  118. BYTE* CDib::GetData()
  119. {
  120.     return m_pData;
  121. }
  122. RGBQUAD* CDib::GetRGB()
  123. {
  124.     return m_pRGB;
  125. }
  126. BITMAPINFO* CDib::GetInfo()
  127. {
  128.     return m_pBitmapInfo;
  129. }
  130. WORD CDib::PaletteSize(LPBYTE lpDIB) 
  131.     return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE)); 
  132. WORD CDib::DIBNumColors(LPBYTE lpDIB) 
  133.     WORD wBitCount;  // DIB bit count 
  134.     wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount; 
  135.     switch (wBitCount) 
  136.     { 
  137.         case 1: 
  138.             return 2; 
  139.         case 4: 
  140.             return 16; 
  141.         case 8: 
  142.             return 256; 
  143.         default: 
  144.             return 0; 
  145.     } 
  146. void CDib::SaveFile(const CString filename)
  147. {
  148. /* strcpy(m_fileName,filename);
  149.     CFile dibFile(m_fileName, CFile::modeCreate|CFile::modeWrite);
  150.     dibFile.Write((void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
  151.     dibFile.Write((void*)pDib, size);
  152.     dibFile.Close();
  153. */
  154.    BITMAPFILEHEADER    bmfHdr;     // Header for Bitmap file 
  155.     LPBITMAPINFOHEADER  lpBI;       // Pointer to DIB info structure 
  156.     DWORD               dwDIBSize; 
  157.  
  158.     bmfHdr.bfType = 0x4d42;  // "BM" 
  159.     lpBI = (LPBITMAPINFOHEADER)m_pBitmapInfoHeader; 
  160.     dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);   
  161.     if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) 
  162.         dwDIBSize += lpBI->biSizeImage; 
  163.     else 
  164.     { 
  165.         DWORD dwBmBitsSize;  // Size of Bitmap Bits only 
  166.         dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * 
  167.                 lpBI->biHeight; 
  168.         dwDIBSize += dwBmBitsSize; 
  169.         lpBI->biSizeImage = dwBmBitsSize; 
  170.     } 
  171.     bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); 
  172.     bmfHdr.bfReserved1 = 0; 
  173.     bmfHdr.bfReserved2 = 0; 
  174.     bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + 
  175.             PaletteSize((LPBYTE)lpBI); 
  176.  
  177. CFile dibFile(filename, CFile::modeWrite|CFile::modeCreate);
  178. dibFile.Write(&bmfHdr, sizeof(BITMAPFILEHEADER));
  179. dibFile.WriteHuge(lpBI, dwDIBSize);
  180. dibFile.Close();
  181. /*
  182. bitmapFileHeader.bfSize=GetSize()+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO);
  183. bitmapFileHeader.bfType = 0x4d42;
  184. bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO);
  185. bitmapFileHeader.bfReserved1 = 0;
  186. bitmapFileHeader.bfReserved2 = 0;
  187. CFile dibFile(filename, CFile::modeWrite|CFile::modeCreate);
  188. dibFile.Write(&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
  189. dibFile.Write(m_pBitmapInfo,sizeof(BITMAPINFO));
  190. dibFile.WriteHuge(m_pData,GetSize());
  191. dibFile.Close();
  192. }
  193. //////////////////////////////////////////////////////////////////
  194.     BITMAPFILEHEADER bmfh;
  195. bmfh.bfType = 0x4d42;  // 'BM'
  196. int sizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorEntries;
  197. bmfh.bfSize = 0;
  198. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  199. bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  200. sizeof(RGBQUAD) * m_nColorEntries;
  201. try {
  202. pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  203. pFile->Write((LPVOID) m_lpBMPHdr,  sizeHdr);
  204. pFile->Write((LPVOID) m_lpDIBits, m_dwImageSize);
  205. }
  206. catch(CException* pe) {
  207. pe->Delete();
  208. AfxMessageBox("write error");
  209. return FALSE;
  210. }
  211. return TRUE;
  212. }
  213. /////////////////////////////////////////////////
  214. WaitCursorBegin();
  215.     BITMAPFILEHEADER    bmfHdr;     // Header for Bitmap file 
  216.     LPBITMAPINFOHEADER  lpBI;       // Pointer to DIB info structure 
  217.     DWORD               dwDIBSize; 
  218. // Get a pointer to the DIB memory, the first of which contains 
  219.     // a BITMAPINFO structure 
  220.     lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib); 
  221.     if (!lpBI) 
  222. {
  223. GlobalUnlock(m_hDib);
  224. WaitCursorEnd();
  225.         return FALSE; 
  226. }
  227.  
  228.     // Check to see if we're dealing with an OS/2 DIB.  If so, don't 
  229.     // save it because our functions aren't written to deal with these 
  230.     // DIBs. 
  231.     if (lpBI->biSize != sizeof(BITMAPINFOHEADER)) 
  232.     { 
  233.         GlobalUnlock(m_hDib); 
  234. WaitCursorEnd();
  235.         return FALSE; 
  236.     } 
  237.  
  238.     // Fill in the fields of the file header 
  239.  
  240.     // Fill in file type (first 2 bytes must be "BM" for a bitmap) 
  241.  
  242.     bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM" 
  243.  
  244.     // Calculating the size of the DIB is a bit tricky (if we want to 
  245.     // do it right).  The easiest way to do this is to call GlobalSize() 
  246.     // on our global handle, but since the size of our global memory may have 
  247.     // been padded a few bytes, we may end up writing out a few too 
  248.     // many bytes to the file (which may cause problems with some apps, 
  249.     // like HC 3.0). 
  250.     // 
  251.     // So, instead let's calculate the size manually. 
  252.     // 
  253.     // To do this, find size of header plus size of color table.  Since the 
  254.     // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains 
  255.     // the size of the structure, let's use this. 
  256.  
  257.     // Partial Calculation 
  258.  
  259.     dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);   
  260.  
  261.     // Now calculate the size of the image 
  262.  
  263.     // It's an RLE bitmap, we can't calculate size, so trust the biSizeImage 
  264.     // field 
  265.  
  266.     if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) 
  267.         dwDIBSize += lpBI->biSizeImage; 
  268.     else 
  269.     { 
  270.         DWORD dwBmBitsSize;  // Size of Bitmap Bits only 
  271.  
  272.         // It's not RLE, so size is Width (DWORD aligned) * Height 
  273.  
  274.         dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * 
  275.                 lpBI->biHeight; 
  276.  
  277.         dwDIBSize += dwBmBitsSize; 
  278.  
  279.         // Now, since we have calculated the correct size, why don't we 
  280.         // fill in the biSizeImage field (this will fix any .BMP files which  
  281.         // have this field incorrect). 
  282.  
  283.         lpBI->biSizeImage = dwBmBitsSize; 
  284.     } 
  285.  
  286.  
  287.     // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) 
  288.                     
  289.     bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); 
  290.     bmfHdr.bfReserved1 = 0; 
  291.     bmfHdr.bfReserved2 = 0; 
  292.  
  293.     // Now, calculate the offset the actual bitmap bits will be in 
  294.     // the file -- It's the Bitmap file header plus the DIB header, 
  295.     // plus the size of the color table. 
  296.      
  297.     bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + 
  298.             PaletteSize((LPBYTE)lpBI); 
  299.  
  300.   TRY
  301. {
  302.     // Write the file header 
  303. pFile->Write(&bmfHdr, sizeof(BITMAPFILEHEADER));
  304. // write DIB buffer
  305. pFile->WriteHuge(lpBI, dwDIBSize);
  306. }
  307. CATCH (CException, e)
  308. {
  309.         GlobalUnlock(m_hDib); 
  310. WaitCursorEnd();
  311. return FALSE;
  312. }
  313. END_CATCH
  314. GlobalUnlock(m_hDib); 
  315. WaitCursorEnd();
  316. return TRUE;
  317. */
  318. }