/src/FreeImage/Source/FreeImage/ConversionFloat.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 192 lines · 130 code · 27 blank · 35 comment · 26 complexity · 1487a7a054814e8fe8edf26eb59c9b55 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 Float
  25. // ----------------------------------------------------------
  26. FIBITMAP * DLL_CALLCONV
  27. FreeImage_ConvertToFloat(FIBITMAP *dib) {
  28. FIBITMAP *src = NULL;
  29. FIBITMAP *dst = NULL;
  30. if(!FreeImage_HasPixels(dib)) return NULL;
  31. 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 8-bit
  37. if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
  38. src = dib;
  39. } else {
  40. src = FreeImage_ConvertToGreyscale(dib);
  41. if(!src) return NULL;
  42. }
  43. break;
  44. }
  45. case FIT_UINT16:
  46. case FIT_RGB16:
  47. case FIT_RGBA16:
  48. case FIT_RGBF:
  49. case FIT_RGBAF:
  50. src = dib;
  51. break;
  52. case FIT_FLOAT:
  53. // float type : clone the src
  54. return FreeImage_Clone(dib);
  55. default:
  56. return NULL;
  57. }
  58. // allocate dst image
  59. const unsigned width = FreeImage_GetWidth(src);
  60. const unsigned height = FreeImage_GetHeight(src);
  61. dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
  62. if(!dst) {
  63. if(src != dib) {
  64. FreeImage_Unload(src);
  65. }
  66. return NULL;
  67. }
  68. // copy metadata from src to dst
  69. FreeImage_CloneMetadata(dst, src);
  70. // convert from src type to float
  71. const unsigned src_pitch = FreeImage_GetPitch(src);
  72. const unsigned dst_pitch = FreeImage_GetPitch(dst);
  73. const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
  74. BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
  75. switch(src_type) {
  76. case FIT_BITMAP:
  77. {
  78. for(unsigned y = 0; y < height; y++) {
  79. const BYTE *src_pixel = (BYTE*)src_bits;
  80. float *dst_pixel = (float*)dst_bits;
  81. for(unsigned x = 0; x < width; x++) {
  82. // convert and scale to the range [0..1]
  83. dst_pixel[x] = (float)(src_pixel[x]) / 255;
  84. }
  85. src_bits += src_pitch;
  86. dst_bits += dst_pitch;
  87. }
  88. }
  89. break;
  90. case FIT_UINT16:
  91. {
  92. for(unsigned y = 0; y < height; y++) {
  93. const WORD *src_pixel = (WORD*)src_bits;
  94. float *dst_pixel = (float*)dst_bits;
  95. for(unsigned x = 0; x < width; x++) {
  96. // convert and scale to the range [0..1]
  97. dst_pixel[x] = (float)(src_pixel[x]) / 65535;
  98. }
  99. src_bits += src_pitch;
  100. dst_bits += dst_pitch;
  101. }
  102. }
  103. break;
  104. case FIT_RGB16:
  105. {
  106. for(unsigned y = 0; y < height; y++) {
  107. const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
  108. float *dst_pixel = (float*)dst_bits;
  109. for(unsigned x = 0; x < width; x++) {
  110. // convert and scale to the range [0..1]
  111. dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
  112. }
  113. src_bits += src_pitch;
  114. dst_bits += dst_pitch;
  115. }
  116. }
  117. break;
  118. case FIT_RGBA16:
  119. {
  120. for(unsigned y = 0; y < height; y++) {
  121. const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
  122. float *dst_pixel = (float*)dst_bits;
  123. for(unsigned x = 0; x < width; x++) {
  124. // convert and scale to the range [0..1]
  125. dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
  126. }
  127. src_bits += src_pitch;
  128. dst_bits += dst_pitch;
  129. }
  130. }
  131. break;
  132. case FIT_RGBF:
  133. {
  134. for(unsigned y = 0; y < height; y++) {
  135. const FIRGBF *src_pixel = (FIRGBF*)src_bits;
  136. float *dst_pixel = (float*)dst_bits;
  137. for(unsigned x = 0; x < width; x++) {
  138. // convert (assume pixel values are in the range [0..1])
  139. dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
  140. }
  141. src_bits += src_pitch;
  142. dst_bits += dst_pitch;
  143. }
  144. }
  145. break;
  146. case FIT_RGBAF:
  147. {
  148. for(unsigned y = 0; y < height; y++) {
  149. const FIRGBAF *src_pixel = (FIRGBAF*)src_bits;
  150. float *dst_pixel = (float*)dst_bits;
  151. for(unsigned x = 0; x < width; x++) {
  152. // convert (assume pixel values are in the range [0..1])
  153. dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
  154. }
  155. src_bits += src_pitch;
  156. dst_bits += dst_pitch;
  157. }
  158. }
  159. break;
  160. }
  161. if(src != dib) {
  162. FreeImage_Unload(src);
  163. }
  164. return dst;
  165. }