/** Convert image of any type to a standard 8-bit greyscale image. For standard images, a clone of the input image is returned. When the scale_linear parameter is TRUE, conversion is done by scaling linearly each pixel to an integer value between [0..255]. When it is FALSE, conversion is done by rounding each float pixel to an integer between [0..255]. For complex images, the magnitude is extracted as a double image, then converted according to the scale parameter. @param image Image to convert @param scale_linear Linear scaling / rounding switch */ FIBITMAP* DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear) { FIBITMAP *dst = NULL; if(!src) return NULL; // convert from src_type to FIT_BITMAP const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src); switch(src_type) { case FIT_BITMAP: // standard image: 1-, 4-, 8-, 16-, 24-, 32-bit dst = FreeImage_Clone(src); break; case FIT_UINT16: // array of unsigned short: unsigned 16-bit dst = convertUShortToByte.convert(src, scale_linear); break; case FIT_INT16: // array of short: signed 16-bit dst = convertShortToByte.convert(src, scale_linear); break; case FIT_UINT32: // array of unsigned long: unsigned 32-bit dst = convertULongToByte.convert(src, scale_linear); break; case FIT_INT32: // array of long: signed 32-bit dst = convertLongToByte.convert(src, scale_linear); break; case FIT_FLOAT: // array of float: 32-bit dst = convertFloatToByte.convert(src, scale_linear); break; case FIT_DOUBLE: // array of double: 64-bit dst = convertDoubleToByte.convert(src, scale_linear); break; case FIT_COMPLEX: // array of FICOMPLEX: 2 x 64-bit { // Convert to type FIT_DOUBLE FIBITMAP *dib_double = FreeImage_GetComplexChannel(src, FICC_MAG); if(dib_double) { // Convert to a standard bitmap (linear scaling) dst = convertDoubleToByte.convert(dib_double, scale_linear); // Free image of type FIT_DOUBLE FreeImage_Unload(dib_double); } } break; case FIT_RGB16: // 48-bit RGB image: 3 x 16-bit break; case FIT_RGBA16: // 64-bit RGBA image: 4 x 16-bit break; case FIT_RGBF: // 96-bit RGB float image: 3 x 32-bit IEEE floating point break; case FIT_RGBAF: // 128-bit RGBA float image: 4 x 32-bit IEEE floating point break; } if(NULL == dst) { FreeImage_OutputMessageProc(FIF_UNKNOWN, "FREE_IMAGE_TYPE: Unable to convert from type %d to type %d.\n No such conversion exists.", src_type, FIT_BITMAP); } return dst; }
void fipWinImage::drawEx(HDC hDC, RECT& rcDest, BOOL useFileBkg, RGBQUAD *appBkColor, FIBITMAP *bg) const { // Convert to a standard bitmap if needed if(_bHasChanged) { if(_bDeleteMe) { FreeImage_Unload(_display_dib); _display_dib = NULL; _bDeleteMe = FALSE; } FREE_IMAGE_TYPE image_type = getImageType(); if(image_type == FIT_BITMAP) { BOOL bHasBackground = FreeImage_HasBackgroundColor(_dib); BOOL bIsTransparent = FreeImage_IsTransparent(_dib); if(!bIsTransparent && (!bHasBackground || !useFileBkg)) { // Copy pointer _display_dib = _dib; } else { // Create the transparent / alpha blended image _display_dib = FreeImage_Composite(_dib, useFileBkg, appBkColor, bg); if(_display_dib) { // Remember to delete _display_dib _bDeleteMe = TRUE; } else { // Something failed: copy pointers _display_dib = _dib; } } } else { // Convert to a standard dib for display if(image_type == FIT_COMPLEX) { // Convert to type FIT_DOUBLE FIBITMAP *dib_double = FreeImage_GetComplexChannel(_dib, FICC_MAG); // Convert to a standard bitmap (linear scaling) _display_dib = FreeImage_ConvertToStandardType(dib_double, TRUE); // Free image of type FIT_DOUBLE FreeImage_Unload(dib_double); } else if((image_type == FIT_RGBF) || (image_type == FIT_RGB16)) { // Apply a tone mapping algorithm and convert to 24-bit _display_dib = FreeImage_ToneMapping(_dib, _tmo, _tmo_param_1, _tmo_param_2); } else if(image_type == FIT_RGBA16) { // Convert to 32-bit FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib); if(dib32) { // Create the transparent / alpha blended image _display_dib = FreeImage_Composite(dib32, useFileBkg, appBkColor, bg); FreeImage_Unload(dib32); } } else { // Other cases: convert to a standard bitmap (linear scaling) _display_dib = FreeImage_ConvertToStandardType(_dib, TRUE); } // Remember to delete _display_dib _bDeleteMe = TRUE; } _bHasChanged = FALSE; } // Draw the dib SetStretchBltMode(hDC, COLORONCOLOR); StretchDIBits(hDC, rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top, 0, 0, FreeImage_GetWidth(_display_dib), FreeImage_GetHeight(_display_dib), FreeImage_GetBits(_display_dib), FreeImage_GetInfo(_display_dib), DIB_RGB_COLORS, SRCCOPY); }