/src/FreeImage/Source/FreeImage/Conversion24.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 214 lines · 149 code · 34 blank · 31 comment · 33 complexity · a53123239b8b2ef9528584f4f3aafe28 MD5 · raw file

  1. // ==========================================================
  2. // Bitmap conversion routines
  3. //
  4. // Design and implementation by
  5. // - Floris van den Berg (flvdberg@wxs.nl)
  6. // - Dale Larson (dlarson@norsesoft.com)
  7. // - Hervé Drolon (drolon@infonie.fr)
  8. // - Jani Kajala (janik@remedy.fi)
  9. //
  10. // This file is part of FreeImage 3
  11. //
  12. // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
  13. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
  14. // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
  15. // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
  16. // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
  17. // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
  18. // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
  19. // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  20. // THIS DISCLAIMER.
  21. //
  22. // Use at your own risk!
  23. // ==========================================================
  24. #include "FreeImage.h"
  25. #include "Utilities.h"
  26. // ----------------------------------------------------------
  27. // internal conversions X to 24 bits
  28. // ----------------------------------------------------------
  29. void DLL_CALLCONV
  30. FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
  31. for (int cols = 0; cols < width_in_pixels; cols++) {
  32. BYTE index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
  33. target[FI_RGBA_BLUE] = palette[index].rgbBlue;
  34. target[FI_RGBA_GREEN] = palette[index].rgbGreen;
  35. target[FI_RGBA_RED] = palette[index].rgbRed;
  36. target += 3;
  37. }
  38. }
  39. void DLL_CALLCONV
  40. FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
  41. BOOL low_nibble = FALSE;
  42. int x = 0;
  43. for (int cols = 0; cols < width_in_pixels; ++cols ) {
  44. if (low_nibble) {
  45. target[FI_RGBA_BLUE] = palette[LOWNIBBLE(source[x])].rgbBlue;
  46. target[FI_RGBA_GREEN] = palette[LOWNIBBLE(source[x])].rgbGreen;
  47. target[FI_RGBA_RED] = palette[LOWNIBBLE(source[x])].rgbRed;
  48. x++;
  49. } else {
  50. target[FI_RGBA_BLUE] = palette[HINIBBLE(source[x]) >> 4].rgbBlue;
  51. target[FI_RGBA_GREEN] = palette[HINIBBLE(source[x]) >> 4].rgbGreen;
  52. target[FI_RGBA_RED] = palette[HINIBBLE(source[x]) >> 4].rgbRed;
  53. }
  54. low_nibble = !low_nibble;
  55. target += 3;
  56. }
  57. }
  58. void DLL_CALLCONV
  59. FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
  60. for (int cols = 0; cols < width_in_pixels; cols++) {
  61. target[FI_RGBA_BLUE] = palette[source[cols]].rgbBlue;
  62. target[FI_RGBA_GREEN] = palette[source[cols]].rgbGreen;
  63. target[FI_RGBA_RED] = palette[source[cols]].rgbRed;
  64. target += 3;
  65. }
  66. }
  67. void DLL_CALLCONV
  68. FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels) {
  69. WORD *bits = (WORD *)source;
  70. for (int cols = 0; cols < width_in_pixels; cols++) {
  71. target[FI_RGBA_RED] = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
  72. target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
  73. target[FI_RGBA_BLUE] = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
  74. target += 3;
  75. }
  76. }
  77. void DLL_CALLCONV
  78. FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels) {
  79. WORD *bits = (WORD *)source;
  80. for (int cols = 0; cols < width_in_pixels; cols++) {
  81. target[FI_RGBA_RED] = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
  82. target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
  83. target[FI_RGBA_BLUE] = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
  84. target += 3;
  85. }
  86. }
  87. void DLL_CALLCONV
  88. FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels) {
  89. for (int cols = 0; cols < width_in_pixels; cols++) {
  90. target[FI_RGBA_BLUE] = source[FI_RGBA_BLUE];
  91. target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
  92. target[FI_RGBA_RED] = source[FI_RGBA_RED];
  93. target += 3;
  94. source += 4;
  95. }
  96. }
  97. // ----------------------------------------------------------
  98. // smart convert X to 24 bits
  99. // ----------------------------------------------------------
  100. FIBITMAP * DLL_CALLCONV
  101. FreeImage_ConvertTo24Bits(FIBITMAP *dib) {
  102. if(!FreeImage_HasPixels(dib)) return NULL;
  103. const unsigned bpp = FreeImage_GetBPP(dib);
  104. const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
  105. if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16)) {
  106. return NULL;
  107. }
  108. if (bpp != 24) {
  109. const int width = FreeImage_GetWidth(dib);
  110. const int height = FreeImage_GetHeight(dib);
  111. FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
  112. if(new_dib == NULL) {
  113. return NULL;
  114. }
  115. // copy metadata from src to dst
  116. FreeImage_CloneMetadata(new_dib, dib);
  117. switch(bpp) {
  118. case 1 :
  119. {
  120. for (int rows = 0; rows < height; rows++) {
  121. FreeImage_ConvertLine1To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
  122. }
  123. return new_dib;
  124. }
  125. case 4 :
  126. {
  127. for (int rows = 0; rows < height; rows++) {
  128. FreeImage_ConvertLine4To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
  129. }
  130. return new_dib;
  131. }
  132. case 8 :
  133. {
  134. for (int rows = 0; rows < height; rows++) {
  135. FreeImage_ConvertLine8To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
  136. }
  137. return new_dib;
  138. }
  139. case 16 :
  140. {
  141. for (int rows = 0; rows < height; rows++) {
  142. if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
  143. FreeImage_ConvertLine16To24_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
  144. } else {
  145. // includes case where all the masks are 0
  146. FreeImage_ConvertLine16To24_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
  147. }
  148. }
  149. return new_dib;
  150. }
  151. case 32 :
  152. {
  153. for (int rows = 0; rows < height; rows++) {
  154. FreeImage_ConvertLine32To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
  155. }
  156. return new_dib;
  157. }
  158. case 48:
  159. {
  160. const unsigned src_pitch = FreeImage_GetPitch(dib);
  161. const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
  162. const BYTE *src_bits = FreeImage_GetBits(dib);
  163. BYTE *dst_bits = FreeImage_GetBits(new_dib);
  164. for (int rows = 0; rows < height; rows++) {
  165. const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
  166. RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
  167. for(int cols = 0; cols < width; cols++) {
  168. dst_pixel[cols].rgbtRed = (BYTE)(src_pixel[cols].red >> 8);
  169. dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
  170. dst_pixel[cols].rgbtBlue = (BYTE)(src_pixel[cols].blue >> 8);
  171. }
  172. src_bits += src_pitch;
  173. dst_bits += dst_pitch;
  174. }
  175. return new_dib;
  176. }
  177. }
  178. }
  179. return FreeImage_Clone(dib);
  180. }