/src/FreeImage/Source/FreeImage/Conversion16_555.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 209 lines · 131 code · 43 blank · 35 comment · 33 complexity · a454422f0a233554598adc29d6ab9384 MD5 · raw file

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