Download | Plain Text | No Line Numbers


  1. /**
  2.  * @module cwindowsbitmap
  3.  * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
  4.  * @brief Implementation of CBitmap handling Windows Bitmaps.
  5.  * @date 17.04.2009
  6.  */
  7.  
  8. #include <boost/lexical_cast.hpp>
  9. #include <boost/numeric/conversion/cast.hpp>
  10. #include <assert.h>
  11. #ifdef DEBUG
  12. # include <iostream>
  13. #endif
  14. #include "cwindowsbitmap.h"
  15. #include "cpixelformat_bgr24.h"
  16. #include "cpixelformat_bgr555.h"
  17.  
  18. using namespace std;
  19.  
  20. CWindowsBitmap::CWindowsBitmap()
  21. {
  22. m_types.insert("BMP");
  23.  
  24. /* add our handlers */
  25. m_handlers.insert(new CPixelFormat_BGR24(this));
  26. m_handlers.insert(new CPixelFormat_BGR555(this));
  27. }
  28.  
  29. /*----------------------------------------------------------------------------*/
  30.  
  31. void CWindowsBitmap::read(std::ifstream& in)
  32. {
  33. /* read and check file header */
  34. in.read(reinterpret_cast<char *>(&m_fileheader), sizeof(m_fileheader));
  35.  
  36. if (m_fileheader.bfType[0] != 'B' || m_fileheader.bfType[1] != 'M')
  37. throw FileError("Imagefile has invalid Bitmap header.");
  38. /* bfSize is unreliable (http://de.wikipedia.org/wiki/Windows_Bitmap) */
  39. if (m_fileheader.bfSize < 0)
  40. throw FileError("Bitmap filesize is less than zero?");
  41.  
  42. /* read and check info header */
  43. in.read(reinterpret_cast<char *>(&m_infoheader), sizeof(m_infoheader));
  44.  
  45. if (m_infoheader.biSize != 40)
  46. throw FileError("Bitmap info header size is invalid.");
  47. if (m_infoheader.biPlanes != 1)
  48. throw FileError("Bitmap color planes is not set to 1.");
  49. if (m_infoheader.biCompression != 0)
  50. throw FileError("Bitmap compression is set but not supported.");
  51. if (m_infoheader.biSizeImage < 0)
  52. throw FileError("Bitmap image size is less than zero?");
  53. if (m_infoheader.biClrUsed != 0 || m_infoheader.biClrImportant != 0)
  54. throw FileError("Bitmap colortable is used but not supported.");
  55.  
  56. /* read pixel data using separate class */
  57. if (m_infoheader.biSizeImage > 0)
  58. {
  59. if (m_pixeldata != NULL)
  60. delete[] m_pixeldata;
  61. m_pixeldata = new uint8_t[m_infoheader.biSizeImage];
  62. assert(m_fileheader.bfOffBits > 0);
  63. in.seekg(m_fileheader.bfOffBits);
  64. in.read(reinterpret_cast<char *>(m_pixeldata), m_infoheader.biSizeImage);
  65. }
  66.  
  67. /* get pixelformat instance */
  68. m_pixelformat = NULL;
  69. set<CPixelFormat *>::iterator it;
  70. for (it = m_handlers.begin(); it != m_handlers.end(); it++)
  71. {
  72. if (m_infoheader.biBitCount == (*it)->getBitCount())
  73. {
  74. m_pixelformat = *it;
  75. break;
  76. }
  77. }
  78. if (m_pixelformat == NULL)
  79. throw FileError("Bitmap bitcount is not supported.");
  80.  
  81. /* calc rowsize - boundary is 32 */
  82. m_rowsize = 4 * static_cast<uint32_t>(
  83. ((m_pixelformat->getBitCount() * m_infoheader.biWidth) + 31) / 32
  84. );
  85. }
  86.  
  87. /*----------------------------------------------------------------------------*/
  88.  
  89. void CWindowsBitmap::write(std::ofstream& out)
  90. {
  91. /* set header values */
  92. m_fileheader.bfSize = m_infoheader.biSizeImage + sizeof(m_infoheader) + sizeof(m_fileheader);
  93.  
  94. /* write file header */
  95. out.write(reinterpret_cast<char *>(&m_fileheader), sizeof(m_fileheader));
  96.  
  97. /* write info header */
  98. out.write(reinterpret_cast<char *>(&m_infoheader), sizeof(m_infoheader));
  99.  
  100. /* write pixel data */
  101. if (m_pixeldata != NULL)
  102. out.write(reinterpret_cast<char *>(m_pixeldata), m_infoheader.biSizeImage);
  103. }
  104.  
  105. /*----------------------------------------------------------------------------*/
  106.  
  107. #ifdef DEBUG
  108. void CWindowsBitmap::dump(std::ostream& out)
  109. {
  110. out
  111. << "Bitmap File Header:" << endl
  112. << " bfType=" << m_fileheader.bfType[0] << m_fileheader.bfType[1]
  113. << ", bfSize=" << m_fileheader.bfSize
  114. << ", bfReserved=" << m_fileheader.bfReserved
  115. << ", bfOffBits=" << m_fileheader.bfOffBits
  116. << endl;
  117.  
  118. out
  119. << "Bitmap Info Header:" << endl
  120. << " biSize=" << m_infoheader.biSize
  121. << ", biWidth=" << m_infoheader.biWidth
  122. << ", biHeight=" << m_infoheader.biHeight
  123. << ", biPlanes=" << m_infoheader.biPlanes
  124. << endl
  125.  
  126. << " biBitCount=" << m_infoheader.biBitCount
  127. << ", biCompression=" << m_infoheader.biCompression
  128. << ", biSizeImage=" << m_infoheader.biSizeImage
  129. << endl
  130.  
  131. << " biXPelsPerMeter=" << m_infoheader.biXPelsPerMeter
  132. << ", biYPelsPerMeter=" << m_infoheader.biYPelsPerMeter
  133. << ", biClrUsed=" << m_infoheader.biClrUsed
  134. << ", biClrImportant=" << m_infoheader.biClrImportant
  135. << endl;
  136. }
  137. #endif
  138.  
  139. /* vim: set et sw=2 ts=2: */
  140.