/src/FreeImage/Source/FreeImage/PixelAccess.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 209 lines · 157 code · 27 blank · 25 comment · 41 complexity · 94d0869683255a20de1c6dd025c57259 MD5 · raw file

  1. // ==========================================================
  2. // Pixel access functions
  3. //
  4. // Design and implementation by
  5. // - Floris van den Berg (flvdberg@wxs.nl)
  6. // - Hervé Drolon (drolon@infonie.fr)
  7. // - Ryan Rubley (ryan@lostreality.org)
  8. // - Riley McNiff (rmcniff@marexgroup.com)
  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. BYTE * DLL_CALLCONV
  28. FreeImage_GetBits(FIBITMAP *dib) {
  29. if(!FreeImage_HasPixels(dib)) {
  30. return NULL;
  31. }
  32. // returns the pixels aligned on a FIBITMAP_ALIGNMENT bytes alignment boundary
  33. size_t lp = (size_t)FreeImage_GetInfoHeader(dib);
  34. lp += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * FreeImage_GetColorsUsed(dib);
  35. lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
  36. return (BYTE *)lp;
  37. }
  38. BYTE * DLL_CALLCONV
  39. FreeImage_GetScanLine(FIBITMAP *dib, int scanline) {
  40. if(!FreeImage_HasPixels(dib)) {
  41. return NULL;
  42. }
  43. return CalculateScanLine(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), scanline);
  44. }
  45. BOOL DLL_CALLCONV
  46. FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
  47. BYTE shift;
  48. if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
  49. return FALSE;
  50. if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
  51. BYTE *bits = FreeImage_GetScanLine(dib, y);
  52. switch(FreeImage_GetBPP(dib)) {
  53. case 1:
  54. *value = (bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
  55. break;
  56. case 4:
  57. shift = (BYTE)((1 - x % 2) << 2);
  58. *value = (bits[x >> 1] & (0x0F << shift)) >> shift;
  59. break;
  60. case 8:
  61. *value = bits[x];
  62. break;
  63. default:
  64. return FALSE;
  65. }
  66. return TRUE;
  67. }
  68. return FALSE;
  69. }
  70. BOOL DLL_CALLCONV
  71. FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
  72. if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
  73. return FALSE;
  74. if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
  75. BYTE *bits = FreeImage_GetScanLine(dib, y);
  76. switch(FreeImage_GetBPP(dib)) {
  77. case 16:
  78. {
  79. bits += 2*x;
  80. WORD *pixel = (WORD *)bits;
  81. if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
  82. value->rgbBlue = (BYTE)((((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
  83. value->rgbGreen = (BYTE)((((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
  84. value->rgbRed = (BYTE)((((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
  85. value->rgbReserved = 0;
  86. } else {
  87. value->rgbBlue = (BYTE)((((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
  88. value->rgbGreen = (BYTE)((((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
  89. value->rgbRed = (BYTE)((((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
  90. value->rgbReserved = 0;
  91. }
  92. break;
  93. }
  94. case 24:
  95. bits += 3*x;
  96. value->rgbBlue = bits[FI_RGBA_BLUE]; // B
  97. value->rgbGreen = bits[FI_RGBA_GREEN]; // G
  98. value->rgbRed = bits[FI_RGBA_RED]; // R
  99. value->rgbReserved = 0;
  100. break;
  101. case 32:
  102. bits += 4*x;
  103. value->rgbBlue = bits[FI_RGBA_BLUE]; // B
  104. value->rgbGreen = bits[FI_RGBA_GREEN]; // G
  105. value->rgbRed = bits[FI_RGBA_RED]; // R
  106. value->rgbReserved = bits[FI_RGBA_ALPHA]; // A
  107. break;
  108. default:
  109. return FALSE;
  110. }
  111. return TRUE;
  112. }
  113. return FALSE;
  114. }
  115. BOOL DLL_CALLCONV
  116. FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
  117. BYTE shift;
  118. if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
  119. return FALSE;
  120. if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
  121. BYTE *bits = FreeImage_GetScanLine(dib, y);
  122. switch(FreeImage_GetBPP(dib)) {
  123. case 1:
  124. *value ? bits[x >> 3] |= (0x80 >> (x & 0x7)) : bits[x >> 3] &= (0xFF7F >> (x & 0x7));
  125. break;
  126. case 4:
  127. shift = (BYTE)((1 - x % 2) << 2);
  128. bits[x >> 1] &= ~(0x0F << shift);
  129. bits[x >> 1] |= ((*value & 0x0F) << shift);
  130. break;
  131. case 8:
  132. bits[x] = *value;
  133. break;
  134. default:
  135. return FALSE;
  136. }
  137. return TRUE;
  138. }
  139. return FALSE;
  140. }
  141. BOOL DLL_CALLCONV
  142. FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
  143. if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
  144. return FALSE;
  145. if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
  146. BYTE *bits = FreeImage_GetScanLine(dib, y);
  147. switch(FreeImage_GetBPP(dib)) {
  148. case 16:
  149. {
  150. bits += 2*x;
  151. WORD *pixel = (WORD *)bits;
  152. if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
  153. *pixel = ((value->rgbBlue >> 3) << FI16_565_BLUE_SHIFT) |
  154. ((value->rgbGreen >> 2) << FI16_565_GREEN_SHIFT) |
  155. ((value->rgbRed >> 3) << FI16_565_RED_SHIFT);
  156. } else {
  157. *pixel = ((value->rgbBlue >> 3) << FI16_555_BLUE_SHIFT) |
  158. ((value->rgbGreen >> 3) << FI16_555_GREEN_SHIFT) |
  159. ((value->rgbRed >> 3) << FI16_555_RED_SHIFT);
  160. }
  161. break;
  162. }
  163. case 24:
  164. bits += 3*x;
  165. bits[FI_RGBA_BLUE] = value->rgbBlue; // B
  166. bits[FI_RGBA_GREEN] = value->rgbGreen; // G
  167. bits[FI_RGBA_RED] = value->rgbRed; // R
  168. break;
  169. case 32:
  170. bits += 4*x;
  171. bits[FI_RGBA_BLUE] = value->rgbBlue; // B
  172. bits[FI_RGBA_GREEN] = value->rgbGreen; // G
  173. bits[FI_RGBA_RED] = value->rgbRed; // R
  174. bits[FI_RGBA_ALPHA] = value->rgbReserved; // A
  175. break;
  176. default:
  177. return FALSE;
  178. }
  179. return TRUE;
  180. }
  181. return FALSE;
  182. }