/src/FreeImage/Source/FreeImage/ConversionRGBF.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 241 lines · 166 code · 34 blank · 41 comment · 26 complexity · d4e6e234933b05cd09d6f107ea3225ef MD5 · raw file

  1. // ==========================================================
  2. // Bitmap conversion routines
  3. //
  4. // Design and implementation by
  5. // - Hervé Drolon (drolon@infonie.fr)
  6. //
  7. // This file is part of FreeImage 3
  8. //
  9. // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
  10. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
  11. // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
  12. // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
  13. // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
  14. // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
  15. // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
  16. // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  17. // THIS DISCLAIMER.
  18. //
  19. // Use at your own risk!
  20. // ==========================================================
  21. #include "FreeImage.h"
  22. #include "Utilities.h"
  23. // ----------------------------------------------------------
  24. // smart convert X to RGBF
  25. // ----------------------------------------------------------
  26. FIBITMAP * DLL_CALLCONV
  27. FreeImage_ConvertToRGBF(FIBITMAP *dib) {
  28. FIBITMAP *src = NULL;
  29. FIBITMAP *dst = NULL;
  30. if(!FreeImage_HasPixels(dib)) return NULL;
  31. const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
  32. // check for allowed conversions
  33. switch(src_type) {
  34. case FIT_BITMAP:
  35. {
  36. // allow conversion from 24- and 32-bit
  37. const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
  38. if((color_type != FIC_RGB) && (color_type != FIC_RGBALPHA)) {
  39. src = FreeImage_ConvertTo24Bits(dib);
  40. if(!src) return NULL;
  41. } else {
  42. src = dib;
  43. }
  44. break;
  45. }
  46. case FIT_UINT16:
  47. // allow conversion from 16-bit
  48. src = dib;
  49. break;
  50. case FIT_RGB16:
  51. // allow conversion from 48-bit RGB
  52. src = dib;
  53. break;
  54. case FIT_RGBA16:
  55. // allow conversion from 64-bit RGBA (ignore the alpha channel)
  56. src = dib;
  57. break;
  58. case FIT_FLOAT:
  59. // allow conversion from 32-bit float
  60. src = dib;
  61. break;
  62. case FIT_RGBAF:
  63. // allow conversion from 128-bit RGBAF
  64. src = dib;
  65. break;
  66. case FIT_RGBF:
  67. // RGBF type : clone the src
  68. return FreeImage_Clone(dib);
  69. break;
  70. default:
  71. return NULL;
  72. }
  73. // allocate dst image
  74. const unsigned width = FreeImage_GetWidth(src);
  75. const unsigned height = FreeImage_GetHeight(src);
  76. dst = FreeImage_AllocateT(FIT_RGBF, width, height);
  77. if(!dst) {
  78. if(src != dib) {
  79. FreeImage_Unload(src);
  80. }
  81. return NULL;
  82. }
  83. // copy metadata from src to dst
  84. FreeImage_CloneMetadata(dst, src);
  85. // convert from src type to RGBF
  86. const unsigned src_pitch = FreeImage_GetPitch(src);
  87. const unsigned dst_pitch = FreeImage_GetPitch(dst);
  88. switch(src_type) {
  89. case FIT_BITMAP:
  90. {
  91. // calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit)
  92. const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
  93. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  94. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  95. for(unsigned y = 0; y < height; y++) {
  96. const BYTE *src_pixel = (BYTE*)src_bits;
  97. FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
  98. for(unsigned x = 0; x < width; x++) {
  99. // convert and scale to the range [0..1]
  100. dst_pixel->red = (float)(src_pixel[FI_RGBA_RED]) / 255.0F;
  101. dst_pixel->green = (float)(src_pixel[FI_RGBA_GREEN]) / 255.0F;
  102. dst_pixel->blue = (float)(src_pixel[FI_RGBA_BLUE]) / 255.0F;
  103. src_pixel += bytespp;
  104. dst_pixel ++;
  105. }
  106. src_bits += src_pitch;
  107. dst_bits += dst_pitch;
  108. }
  109. }
  110. break;
  111. case FIT_UINT16:
  112. {
  113. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  114. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  115. for(unsigned y = 0; y < height; y++) {
  116. const WORD *src_pixel = (WORD*)src_bits;
  117. FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
  118. for(unsigned x = 0; x < width; x++) {
  119. // convert and scale to the range [0..1]
  120. const float dst_value = (float)src_pixel[x] / 65535.0F;
  121. dst_pixel[x].red = dst_value;
  122. dst_pixel[x].green = dst_value;
  123. dst_pixel[x].blue = dst_value;
  124. }
  125. src_bits += src_pitch;
  126. dst_bits += dst_pitch;
  127. }
  128. }
  129. break;
  130. case FIT_RGB16:
  131. {
  132. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  133. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  134. for(unsigned y = 0; y < height; y++) {
  135. const FIRGB16 *src_pixel = (FIRGB16*) src_bits;
  136. FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
  137. for(unsigned x = 0; x < width; x++) {
  138. // convert and scale to the range [0..1]
  139. dst_pixel[x].red = (float)(src_pixel[x].red) / 65535.0F;
  140. dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
  141. dst_pixel[x].blue = (float)(src_pixel[x].blue) / 65535.0F;
  142. }
  143. src_bits += src_pitch;
  144. dst_bits += dst_pitch;
  145. }
  146. }
  147. break;
  148. case FIT_RGBA16:
  149. {
  150. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  151. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  152. for(unsigned y = 0; y < height; y++) {
  153. const FIRGBA16 *src_pixel = (FIRGBA16*) src_bits;
  154. FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
  155. for(unsigned x = 0; x < width; x++) {
  156. // convert and scale to the range [0..1]
  157. dst_pixel[x].red = (float)(src_pixel[x].red) / 65535.0F;
  158. dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
  159. dst_pixel[x].blue = (float)(src_pixel[x].blue) / 65535.0F;
  160. }
  161. src_bits += src_pitch;
  162. dst_bits += dst_pitch;
  163. }
  164. }
  165. break;
  166. case FIT_FLOAT:
  167. {
  168. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  169. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  170. for(unsigned y = 0; y < height; y++) {
  171. const float *src_pixel = (float*) src_bits;
  172. FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
  173. for(unsigned x = 0; x < width; x++) {
  174. // convert by copying greyscale channel to each R, G, B channels
  175. dst_pixel[x].red = src_pixel[x];
  176. dst_pixel[x].green = src_pixel[x];
  177. dst_pixel[x].blue = src_pixel[x];
  178. }
  179. src_bits += src_pitch;
  180. dst_bits += dst_pitch;
  181. }
  182. }
  183. break;
  184. case FIT_RGBAF:
  185. {
  186. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  187. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  188. for(unsigned y = 0; y < height; y++) {
  189. const FIRGBAF *src_pixel = (FIRGBAF*) src_bits;
  190. FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
  191. for(unsigned x = 0; x < width; x++) {
  192. // convert and skip alpha channel
  193. dst_pixel[x].red = src_pixel[x].red;
  194. dst_pixel[x].green = src_pixel[x].green;
  195. dst_pixel[x].blue = src_pixel[x].blue;
  196. }
  197. src_bits += src_pitch;
  198. dst_bits += dst_pitch;
  199. }
  200. }
  201. break;
  202. }
  203. if(src != dib) {
  204. FreeImage_Unload(src);
  205. }
  206. return dst;
  207. }