PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/BotE Game/branch/Alpha7/Source/include/ImageStone/include/imagefile/ImageHandle_FreeImage.h

#
C++ Header | 249 lines | 181 code | 27 blank | 41 comment | 46 complexity | 0211d2c9baa3274727fcef1eb22701aa MD5 | raw file
Possible License(s): GPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  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 : crazybitwps@hotmail.com
  8. * History :
  9. */
  10. #ifndef __FOO_IMAGE_HANDLE_FREEIMAGE__2004_04_09__H__
  11. #define __FOO_IMAGE_HANDLE_FREEIMAGE__2004_04_09__H__
  12. //class FCImageHandle ;
  13. class FCImageHandle_FreeImage ;
  14. //=============================================================================
  15. /**
  16. * Read/Write image via FreeImage library.
  17. * It's a free image library, you can download from <a href='http://sourceforge.net/projects/freeimage' target='_blank'>http://sourceforge.net/projects/freeimage</a><BR><BR>
  18. * Load from file can load all frames of gif/tiff, load from memory only load first frame.
  19. */
  20. class FCImageHandle_FreeImage : public FCImageHandleBase
  21. {
  22. public:
  23. static bool FreeImage_to_FCImage (FIBITMAP* pFIimg, FCObjImage& img)
  24. {
  25. if (!pFIimg)
  26. return false ;
  27. // prepare image info
  28. BYTE __bufImgInfo[sizeof(BITMAPINFOHEADER) + 16] = {0} ;
  29. BITMAPINFOHEADER * pInfo = (BITMAPINFOHEADER*)__bufImgInfo ;
  30. memcpy (pInfo, FreeImage_GetInfoHeader(pFIimg), sizeof(BITMAPINFOHEADER)) ;
  31. if (pInfo->biCompression == BI_BITFIELDS)
  32. {
  33. DWORD * pMask = (DWORD*)(pInfo + 1) ;
  34. pMask[0] = FreeImage_GetRedMask (pFIimg) ;
  35. pMask[1] = FreeImage_GetGreenMask (pFIimg) ;
  36. pMask[2] = FreeImage_GetBlueMask (pFIimg) ;
  37. }
  38. // create image
  39. if (!img.Create(pInfo))
  40. return false ;
  41. // set palette
  42. if (img.ColorBits() <= 8)
  43. img.SetColorTable (0, FreeImage_GetColorsUsed(pFIimg), FreeImage_GetPalette(pFIimg)) ;
  44. // set pixel
  45. assert (img.GetPitch() == FreeImage_GetPitch(pFIimg)) ;
  46. memcpy (img.GetMemStart(), FreeImage_GetBits(pFIimg), img.GetPitch()*img.Height()) ;
  47. // transparency
  48. if ((img.ColorBits() <= 8) && FreeImage_IsTransparent(pFIimg))
  49. {
  50. FCObjImage idxImg (img) ;
  51. int n = (int)FreeImage_GetTransparencyCount(pFIimg) ;
  52. BYTE * p = FreeImage_GetTransparencyTable(pFIimg) ;
  53. img.ConvertTo32Bit() ;
  54. for (int y=0 ; y < img.Height() ; y++)
  55. for (int x=0 ; x < img.Width() ; x++)
  56. {
  57. int nIndex = *idxImg.GetBits(x,y) ;
  58. if (nIndex < n)
  59. PCL_A(img.GetBits(x,y)) = p[nIndex] ;
  60. }
  61. }
  62. return true ;
  63. }
  64. static FIBITMAP* AllocateFreeImage (const FCObjImage& img)
  65. {
  66. if (!img.IsValidImage())
  67. return 0 ;
  68. // create FreeImage object
  69. DWORD dwBitFields[3] = {0, 0, 0} ;
  70. if (img.ColorBits() == 16)
  71. {
  72. PCL_array<BITMAPINFOHEADER> info (img.NewImgInfoWithPalette()) ;
  73. memcpy (dwBitFields, info.get() + 1, 12) ;
  74. }
  75. FIBITMAP * pFIimg = FreeImage_AllocateT (FIT_BITMAP, img.Width(), img.Height(), img.ColorBits(), dwBitFields[0], dwBitFields[1], dwBitFields[2]) ;
  76. if (!pFIimg)
  77. return 0 ;
  78. // set pixel
  79. assert (img.GetPitch() == FreeImage_GetPitch(pFIimg)) ;
  80. memcpy (FreeImage_GetBits(pFIimg), img.GetMemStart(), img.GetPitch()*img.Height()) ;
  81. // set palette
  82. if (img.ColorBits() <= 8)
  83. {
  84. RGBQUAD pPal[256] = {0} ;
  85. img.GetColorTable (0, 1<<img.ColorBits(), pPal) ;
  86. memcpy (FreeImage_GetPalette(pFIimg), pPal, FreeImage_GetColorsUsed(pFIimg)*sizeof(RGBQUAD)) ;
  87. }
  88. return pFIimg ;
  89. }
  90. private:
  91. static void StoreFrame (FIBITMAP* pFIimage,
  92. PCL_Interface_Composite<FCObjImage>& rImageList,
  93. std::auto_ptr<FCImageProperty>& rImageProp)
  94. {
  95. // create frame
  96. FCObjImage * pImg = new FCObjImage ;
  97. FreeImage_to_FCImage (pFIimage, *pImg) ;
  98. if (pImg->IsValidImage())
  99. {
  100. rImageList.PCL_PushObject (pImg) ;
  101. }
  102. else
  103. {
  104. delete pImg ;
  105. }
  106. }
  107. /// Read file routine
  108. virtual bool LoadImageFile (const char* szFileName,
  109. PCL_Interface_Composite<FCObjImage>& rImageList,
  110. std::auto_ptr<FCImageProperty>& rImageProp)
  111. {
  112. // get image format
  113. FREE_IMAGE_FORMAT imgType = FreeImage_GetFileType (szFileName) ;
  114. if (imgType == FIF_UNKNOWN)
  115. return false ;
  116. // read image file via FreeImage library
  117. if ((imgType == FIF_GIF) || (imgType == FIF_TIFF))
  118. {
  119. FIMULTIBITMAP * FIMul = FreeImage_OpenMultiBitmap (imgType, szFileName, FALSE, TRUE) ;
  120. if (FIMul)
  121. {
  122. rImageProp = std::auto_ptr<FCImageProperty>(new FCImageProperty) ;
  123. // get all frames
  124. for (int i=0 ; i < FreeImage_GetPageCount(FIMul) ; i++)
  125. {
  126. FIBITMAP * pFI = FreeImage_LockPage (FIMul, i) ;
  127. if (pFI)
  128. {
  129. StoreFrame (pFI, rImageList, rImageProp) ;
  130. // get frame delay time
  131. FITAG * tag ;
  132. if (FreeImage_GetMetadata (FIMD_ANIMATION, pFI, "FrameTime", &tag))
  133. {
  134. rImageProp->PutFrameDelay (*(int*)FreeImage_GetTagValue(tag)) ;
  135. }
  136. FreeImage_UnlockPage (FIMul, pFI, FALSE) ;
  137. }
  138. }
  139. FreeImage_CloseMultiBitmap (FIMul) ;
  140. }
  141. }
  142. else
  143. {
  144. FIBITMAP * pFI = FreeImage_Load (imgType, szFileName) ;
  145. if (pFI)
  146. {
  147. StoreFrame (pFI, rImageList, rImageProp) ;
  148. FreeImage_Unload (pFI) ;
  149. }
  150. }
  151. return rImageList.PCL_GetObjectCount() ? true : false ;
  152. }
  153. /// Read memory routine
  154. virtual bool LoadImageMemory (const BYTE* pStart, int nMemSize,
  155. PCL_Interface_Composite<FCObjImage>& rImageList,
  156. std::auto_ptr<FCImageProperty>& rImageProp)
  157. {
  158. FIMEMORY * pMem = FreeImage_OpenMemory (const_cast<BYTE*>(pStart), nMemSize) ;
  159. if (!pMem)
  160. return false ;
  161. // get image format
  162. FREE_IMAGE_FORMAT imgType = FreeImage_GetFileTypeFromMemory (pMem) ;
  163. FIBITMAP * pFI = FreeImage_LoadFromMemory (imgType, pMem) ;
  164. if (pFI)
  165. {
  166. StoreFrame (pFI, rImageList, rImageProp) ;
  167. FreeImage_Unload (pFI) ;
  168. }
  169. FreeImage_CloseMemory (pMem) ;
  170. return rImageList.PCL_GetObjectCount() ? true : false ;
  171. }
  172. /// save to file routine
  173. virtual bool SaveImageFile (const char* szFileName,
  174. const std::deque<const FCObjImage*>& rImageList,
  175. const FCImageProperty& rImageProp)
  176. {
  177. if (rImageList.empty() || !rImageList[0]->IsValidImage())
  178. return false ;
  179. const FCObjImage &img = *rImageList[0] ;
  180. // is the FreeImage library support
  181. FREE_IMAGE_FORMAT imgFormat = FreeImage_GetFIFFromFilename (szFileName) ;
  182. if (imgFormat == FIF_UNKNOWN)
  183. return false ;
  184. if (!FreeImage_FIFSupportsWriting (imgFormat) || !FreeImage_FIFSupportsExportBPP (imgFormat, img.ColorBits()))
  185. return false ;
  186. // create FreeImage object
  187. FIBITMAP * pFI = AllocateFreeImage (img) ;
  188. if (!pFI)
  189. return false ;
  190. // save flag
  191. int nFlag = 0 ;
  192. if ((imgFormat == FIF_GIF) && (img.ColorBits() <= 8))
  193. {
  194. // gif transparency
  195. int nCount = 1 << img.ColorBits(),
  196. nIndex = GifSaveTransparentIndex(rImageProp) ;
  197. if (nIndex != -1)
  198. {
  199. PCL_array<BYTE> aTab(nCount) ;
  200. memset (aTab.get(), 0xFF, nCount) ;
  201. aTab[FClamp(nIndex,0,nCount-1)] = 0 ;
  202. FreeImage_SetTransparent (pFI, true) ;
  203. FreeImage_SetTransparencyTable (pFI, aTab.get(), nCount) ;
  204. }
  205. }
  206. else if (imgFormat == FIF_JPEG)
  207. {
  208. nFlag = JpegSaveQuality(rImageProp) ;
  209. }
  210. // save image file
  211. bool bRet = FreeImage_Save (imgFormat, pFI, szFileName, nFlag) ? true : false ;
  212. FreeImage_Unload (pFI) ;
  213. return bRet ;
  214. }
  215. virtual ~FCImageHandle_FreeImage() {FreeImage_DeInitialise();}
  216. public:
  217. FCImageHandle_FreeImage() {FreeImage_Initialise();}
  218. };
  219. //=============================================================================
  220. // inline Implement
  221. //=============================================================================
  222. #endif