crn_freeimage_image_utils.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // File: crn_freeimage_image_utils.h
  2. // See Copyright Notice and license at the end of inc/crnlib.h
  3. // Note: This header file requires FreeImage/FreeImagePlus.
  4. #include "crn_image_utils.h"
  5. #include "freeImagePlus.h"
  6. namespace crnlib
  7. {
  8. namespace freeimage_image_utils
  9. {
  10. inline bool load_from_file(image_u8& dest, const wchar_t* pFilename, int fi_flag)
  11. {
  12. fipImage src_image;
  13. if (!src_image.loadU(pFilename, fi_flag))
  14. return false;
  15. const uint orig_bits_per_pixel = src_image.getBitsPerPixel();
  16. const FREE_IMAGE_COLOR_TYPE orig_color_type = src_image.getColorType();
  17. if (!src_image.convertTo32Bits())
  18. return false;
  19. if (src_image.getBitsPerPixel() != 32)
  20. return false;
  21. uint width = src_image.getWidth();
  22. uint height = src_image.getHeight();
  23. dest.resize(src_image.getWidth(), src_image.getHeight(), src_image.getWidth());
  24. color_quad_u8* pDst = dest.get_ptr();
  25. bool grayscale = true;
  26. bool has_alpha = false;
  27. for (uint y = 0; y < height; y++)
  28. {
  29. const BYTE* pSrc = src_image.getScanLine((WORD)(height - 1 - y));
  30. color_quad_u8* pD = pDst;
  31. for (uint x = width; x; x--)
  32. {
  33. color_quad_u8 c;
  34. c.r = pSrc[FI_RGBA_RED];
  35. c.g = pSrc[FI_RGBA_GREEN];
  36. c.b = pSrc[FI_RGBA_BLUE];
  37. c.a = pSrc[FI_RGBA_ALPHA];
  38. if (!c.is_grayscale())
  39. grayscale = false;
  40. has_alpha |= (c.a < 255);
  41. pSrc += 4;
  42. *pD++ = c;
  43. }
  44. pDst += width;
  45. }
  46. dest.reset_comp_flags();
  47. if (grayscale)
  48. dest.set_grayscale(true);
  49. dest.set_component_valid(3, has_alpha || (orig_color_type == FIC_RGBALPHA) || (orig_bits_per_pixel == 32));
  50. return true;
  51. }
  52. const int cSaveLuma = -1;
  53. inline bool save_to_grayscale_file(const wchar_t* pFilename, const image_u8& src, int component, int fi_flag)
  54. {
  55. fipImage dst_image(FIT_BITMAP, (WORD)src.get_width(), (WORD)src.get_height(), 8);
  56. RGBQUAD* p = dst_image.getPalette();
  57. for (uint i = 0; i < dst_image.getPaletteSize(); i++)
  58. {
  59. p[i].rgbRed = (BYTE)i;
  60. p[i].rgbGreen = (BYTE)i;
  61. p[i].rgbBlue = (BYTE)i;
  62. p[i].rgbReserved = 255;
  63. }
  64. for (uint y = 0; y < src.get_height(); y++)
  65. {
  66. const color_quad_u8* pSrc = src.get_scanline(y);
  67. for (uint x = 0; x < src.get_width(); x++)
  68. {
  69. BYTE v;
  70. if (component == cSaveLuma)
  71. v = (BYTE)(*pSrc).get_luma();
  72. else
  73. v = (*pSrc)[component];
  74. dst_image.setPixelIndex(x, src.get_height() - 1 - y, &v);
  75. pSrc++;
  76. }
  77. }
  78. if (!dst_image.saveU(pFilename, fi_flag))
  79. return false;
  80. return true;
  81. }
  82. inline bool save_to_file(const wchar_t* pFilename, const image_u8& src, int fi_flag, bool ignore_alpha = false)
  83. {
  84. const bool save_alpha = src.is_component_valid(3);
  85. uint bpp = (save_alpha && !ignore_alpha) ? 32 : 24;
  86. if (bpp == 32)
  87. {
  88. dynamic_wstring ext(pFilename);
  89. get_extension(ext);
  90. if ((ext == L"jpg") || (ext == L"jpeg") || (ext == L"gif") || (ext == L"jp2"))
  91. bpp = 24;
  92. }
  93. if ((bpp == 24) && (src.is_grayscale()))
  94. return save_to_grayscale_file(pFilename, src, cSaveLuma, fi_flag);
  95. fipImage dst_image(FIT_BITMAP, (WORD)src.get_width(), (WORD)src.get_height(), (WORD)bpp);
  96. for (uint y = 0; y < src.get_height(); y++)
  97. {
  98. for (uint x = 0; x < src.get_width(); x++)
  99. {
  100. color_quad_u8 c(src(x, y));
  101. RGBQUAD quad;
  102. quad.rgbRed = c.r;
  103. quad.rgbGreen = c.g;
  104. quad.rgbBlue = c.b;
  105. if (bpp == 32)
  106. quad.rgbReserved = c.a;
  107. else
  108. quad.rgbReserved = 255;
  109. dst_image.setPixelColor(x, src.get_height() - 1 - y, &quad);
  110. }
  111. }
  112. if (!dst_image.saveU(pFilename, fi_flag))
  113. return false;
  114. return true;
  115. }
  116. } // namespace freeimage_image_utils
  117. } // namespace crnlib