| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- // File: crn_freeimage_image_utils.h
- // See Copyright Notice and license at the end of inc/crnlib.h
- // Note: This header file requires FreeImage/FreeImagePlus.
- #include "crn_image_utils.h"
- #include "freeImagePlus.h"
- namespace crnlib
- {
- namespace freeimage_image_utils
- {
- inline bool load_from_file(image_u8& dest, const wchar_t* pFilename, int fi_flag)
- {
- fipImage src_image;
- if (!src_image.loadU(pFilename, fi_flag))
- return false;
-
- const uint orig_bits_per_pixel = src_image.getBitsPerPixel();
- const FREE_IMAGE_COLOR_TYPE orig_color_type = src_image.getColorType();
-
- if (!src_image.convertTo32Bits())
- return false;
- if (src_image.getBitsPerPixel() != 32)
- return false;
- uint width = src_image.getWidth();
- uint height = src_image.getHeight();
- dest.resize(src_image.getWidth(), src_image.getHeight(), src_image.getWidth());
- color_quad_u8* pDst = dest.get_ptr();
- bool grayscale = true;
- bool has_alpha = false;
- for (uint y = 0; y < height; y++)
- {
- const BYTE* pSrc = src_image.getScanLine((WORD)(height - 1 - y));
- color_quad_u8* pD = pDst;
- for (uint x = width; x; x--)
- {
- color_quad_u8 c;
- c.r = pSrc[FI_RGBA_RED];
- c.g = pSrc[FI_RGBA_GREEN];
- c.b = pSrc[FI_RGBA_BLUE];
- c.a = pSrc[FI_RGBA_ALPHA];
-
- if (!c.is_grayscale())
- grayscale = false;
- has_alpha |= (c.a < 255);
- pSrc += 4;
- *pD++ = c;
- }
- pDst += width;
- }
- dest.reset_comp_flags();
-
- if (grayscale)
- dest.set_grayscale(true);
-
- dest.set_component_valid(3, has_alpha || (orig_color_type == FIC_RGBALPHA) || (orig_bits_per_pixel == 32));
- return true;
- }
-
- const int cSaveLuma = -1;
-
- inline bool save_to_grayscale_file(const wchar_t* pFilename, const image_u8& src, int component, int fi_flag)
- {
- fipImage dst_image(FIT_BITMAP, (WORD)src.get_width(), (WORD)src.get_height(), 8);
- RGBQUAD* p = dst_image.getPalette();
- for (uint i = 0; i < dst_image.getPaletteSize(); i++)
- {
- p[i].rgbRed = (BYTE)i;
- p[i].rgbGreen = (BYTE)i;
- p[i].rgbBlue = (BYTE)i;
- p[i].rgbReserved = 255;
- }
- for (uint y = 0; y < src.get_height(); y++)
- {
- const color_quad_u8* pSrc = src.get_scanline(y);
- for (uint x = 0; x < src.get_width(); x++)
- {
- BYTE v;
- if (component == cSaveLuma)
- v = (BYTE)(*pSrc).get_luma();
- else
- v = (*pSrc)[component];
- dst_image.setPixelIndex(x, src.get_height() - 1 - y, &v);
- pSrc++;
- }
- }
- if (!dst_image.saveU(pFilename, fi_flag))
- return false;
- return true;
- }
- inline bool save_to_file(const wchar_t* pFilename, const image_u8& src, int fi_flag, bool ignore_alpha = false)
- {
- const bool save_alpha = src.is_component_valid(3);
- uint bpp = (save_alpha && !ignore_alpha) ? 32 : 24;
-
- if (bpp == 32)
- {
- dynamic_wstring ext(pFilename);
- get_extension(ext);
- if ((ext == L"jpg") || (ext == L"jpeg") || (ext == L"gif") || (ext == L"jp2"))
- bpp = 24;
- }
-
- if ((bpp == 24) && (src.is_grayscale()))
- return save_to_grayscale_file(pFilename, src, cSaveLuma, fi_flag);
-
- fipImage dst_image(FIT_BITMAP, (WORD)src.get_width(), (WORD)src.get_height(), (WORD)bpp);
- for (uint y = 0; y < src.get_height(); y++)
- {
- for (uint x = 0; x < src.get_width(); x++)
- {
- color_quad_u8 c(src(x, y));
- RGBQUAD quad;
- quad.rgbRed = c.r;
- quad.rgbGreen = c.g;
- quad.rgbBlue = c.b;
- if (bpp == 32)
- quad.rgbReserved = c.a;
- else
- quad.rgbReserved = 255;
- dst_image.setPixelColor(x, src.get_height() - 1 - y, &quad);
- }
- }
- if (!dst_image.saveU(pFilename, fi_flag))
- return false;
- return true;
- }
-
- } // namespace freeimage_image_utils
-
- } // namespace crnlib
|