ImageHandle_Bmp.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright (C) =USTC= Fu Li
  3. *
  4. * Author : Fu Li
  5. * Create : 2004-4-9
  6. * Home : http://www.crazy-bit.com/
  7. * Mail : crazybit@263.net
  8. * History :
  9. */
  10. #ifndef __FOO_IMAGE_HANDLE_BMP__2004_04_09__H__
  11. #define __FOO_IMAGE_HANDLE_BMP__2004_04_09__H__
  12. #include "../ObjImage.h"
  13. //class FCImageHandle ;
  14. class FCImageHandle_Bmp ;
  15. //=============================================================================
  16. /**
  17. * Read/Write BMP image.
  18. */
  19. class FCImageHandle_Bmp : public FCImageHandleBase
  20. {
  21. // inner struct
  22. #pragma pack(2)
  23. struct PCL_BMPHEADER
  24. {
  25. WORD bfType;
  26. DWORD bfSize;
  27. WORD bfReserved1;
  28. WORD bfReserved2;
  29. DWORD bfOffBits;
  30. };
  31. #pragma pack()
  32. /// Load BMP image.
  33. virtual bool LoadImageMemory (const BYTE* pStart, int nMemSize,
  34. PCL_Interface_Composite<FCObjImage>& rImageList,
  35. std::auto_ptr<FCImageProperty>& rImageProp)
  36. {
  37. if (!pStart || (nMemSize <= sizeof(PCL_BMPHEADER)))
  38. return false ;
  39. if (((PCL_BMPHEADER*)pStart)->bfType != 0x4D42)
  40. return false ;
  41. // size check
  42. const int nOffset = (int)((PCL_BMPHEADER*)pStart)->bfOffBits ;
  43. if (nMemSize <= nOffset)
  44. return false ;
  45. // create image
  46. BITMAPINFOHEADER * pBmih = (BITMAPINFOHEADER*)(pStart + sizeof(PCL_BMPHEADER)) ;
  47. FCObjImage * pImg = new FCObjImage ;
  48. if (!pImg->Create(pBmih))
  49. {
  50. delete pImg; return false;
  51. }
  52. // set palette
  53. if (pImg->ColorBits() <= 8)
  54. {
  55. BYTE * pPal = (BYTE*)pBmih + pBmih->biSize ;
  56. pImg->SetColorTable (0, 1<<pImg->ColorBits(), (RGBQUAD*)pPal) ;
  57. }
  58. // set pixel
  59. int nCopyByte = pImg->GetPitch()*pImg->Height() ;
  60. assert (nMemSize - nOffset >= nCopyByte) ;
  61. nCopyByte = FMin (nCopyByte, nMemSize - nOffset) ;
  62. memcpy (pImg->GetMemStart(), pStart + nOffset, nCopyByte) ;
  63. // add to list
  64. rImageList.PCL_PushObject (pImg) ;
  65. return true ;
  66. }
  67. /// Save BMP image.
  68. virtual bool SaveImageFile (const char* szFileName,
  69. const std::deque<const FCObjImage*>& rImageList,
  70. const FCImageProperty& rImageProp)
  71. {
  72. if (rImageList.empty() || !rImageList[0]->IsValidImage())
  73. return false ;
  74. const FCObjImage &img = *rImageList[0] ;
  75. // create image file, if the file already exists, its contents are discarded.
  76. FILE * pf = fopen (szFileName, "wb") ;
  77. if (!pf)
  78. return false ;
  79. // calculate total size of bmp file.
  80. const int nPixs = img.GetPitch() * img.Height() ;
  81. int nTotalSize = sizeof(PCL_BMPHEADER) + sizeof(BITMAPINFOHEADER) + nPixs ;
  82. PCL_array<BITMAPINFOHEADER> info (img.NewImgInfoWithPalette()) ;
  83. if (img.ColorBits() <= 8)
  84. nTotalSize += (4 * (1<<img.ColorBits())) ;
  85. else if (info.get()->biCompression == BI_BITFIELDS)
  86. nTotalSize += 12 ;
  87. // write bmp file header
  88. PCL_BMPHEADER bmHeader ;
  89. bmHeader.bfType = 0x4D42 ; // "BM"
  90. bmHeader.bfSize = nTotalSize ;
  91. bmHeader.bfReserved1 = bmHeader.bfReserved2 = 0 ;
  92. bmHeader.bfOffBits = nTotalSize - nPixs ;
  93. fwrite (&bmHeader, 1, sizeof(bmHeader), pf) ;
  94. // write BMP file info / bitfields / palette
  95. fwrite (info.get(), 1, nTotalSize - sizeof(PCL_BMPHEADER) - nPixs, pf) ;
  96. // write pixels value
  97. fwrite (img.GetMemStart(), 1, nPixs, pf) ;
  98. fclose (pf) ;
  99. return true ;
  100. }
  101. };
  102. #endif