Ejemplo n.º 1
0
/**
Apply the global/local tone mapping operator to a RGBF image and convert to 24-bit RGB<br>
User parameters control intensity, contrast, and level of adaptation
@param src Input RGBF image
@param intensity Overall intensity in range [-8:8] : default to 0
@param contrast Contrast in range [0.3:1) : default to 0
@param adaptation Adaptation in range [0:1] : default to 1
@param color_correction Color correction in range [0:1] : default to 0
@return Returns a 24-bit RGB image if successful, returns NULL otherwise
*/
FIBITMAP* DLL_CALLCONV 
FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity, double contrast, double adaptation, double color_correction) {
	if(!FreeImage_HasPixels(src)) return NULL;

	// working RGBF variable
	FIBITMAP *dib = NULL, *Y = NULL;

	dib = FreeImage_ConvertToRGBF(src);
	if(!dib) return NULL;

	// get the Luminance channel
	Y = ConvertRGBFToY(dib);
	if(!Y) {
		FreeImage_Unload(dib);
		return NULL;
	}

	// perform the tone mapping
	ToneMappingReinhard05(dib, Y, (float)intensity, (float)contrast, (float)adaptation, (float)color_correction);
	// not needed anymore
	FreeImage_Unload(Y);
	// clamp image highest values to display white, then convert to 24-bit RGB
	FIBITMAP *dst = ClampConvertRGBFTo24(dib);

	// clean-up and return
	FreeImage_Unload(dib);

	// copy metadata from src to dst
	FreeImage_CloneMetadata(dst, src);

	return dst;
}
/**
Apply the Adaptive Logarithmic Mapping operator to a HDR image and convert to 24-bit RGB
@param src Input RGB16 or RGB[A]F image
@param gamma Gamma correction (gamma > 0). 1 means no correction, 2.2 in the original paper.
@param exposure Exposure parameter (0 means no correction, 0 in the original paper)
@return Returns a 24-bit RGB image if successful, returns NULL otherwise
*/
FIBITMAP* DLL_CALLCONV
FreeImage_TmoDrago03(FIBITMAP *src, double gamma, double exposure) {
    float maxLum, minLum, avgLum;

    if(!FreeImage_HasPixels(src)) return NULL;

    // working RGBF variable
    FIBITMAP *dib = NULL;

    dib = FreeImage_ConvertToRGBF(src);
    if(!dib) return NULL;

    // default algorithm parameters
    const float biasParam = 0.85F;
    const float expoParam = (float)pow(2.0, exposure); //default exposure is 1, 2^0

    // convert to Yxy
    ConvertInPlaceRGBFToYxy(dib);
    // get the luminance
    LuminanceFromYxy(dib, &maxLum, &minLum, &avgLum);
    // perform the tone mapping
    ToneMappingDrago03(dib, maxLum, avgLum, biasParam, expoParam);
    // convert back to RGBF
    ConvertInPlaceYxyToRGBF(dib);
    if(gamma != 1) {
        // perform gamma correction
        REC709GammaCorrection(dib, (float)gamma);
    }
    // clamp image highest values to display white, then convert to 24-bit RGB
    FIBITMAP *dst = ClampConvertRGBFTo24(dib);

    // clean-up and return
    FreeImage_Unload(dib);

    // copy metadata from src to dst
    FreeImage_CloneMetadata(dst, src);

    return dst;
}
Ejemplo n.º 3
0
/**
Apply the Gradient Domain High Dynamic Range Compression to a RGBF image and convert to 24-bit RGB
@param dib Input RGBF / RGB16 image
@param color_saturation Color saturation (s parameter in the paper) in [0.4..0.6]
@param attenuation Atenuation factor (beta parameter in the paper) in [0.8..0.9]
@return Returns a 24-bit RGB image if successful, returns NULL otherwise
*/
FIBITMAP* DLL_CALLCONV 
FreeImage_TmoFattal02(FIBITMAP *dib, double color_saturation, double attenuation) {	
	const float alpha = 0.1F;									// parameter alpha = 0.1
	const float beta = (float)MAX(0.8, MIN(0.9, attenuation));	// parameter beta = [0.8..0.9]
	const float s = (float)MAX(0.4, MIN(0.6, color_saturation));// exponent s controls color saturation = [0.4..0.6]

	FIBITMAP *src = NULL;
	FIBITMAP *Yin = NULL;
	FIBITMAP *Yout = NULL;
	FIBITMAP *dst = NULL;

	if(!FreeImage_HasPixels(dib)) return NULL;

	try {

		// convert to RGBF
		src = FreeImage_ConvertToRGBF(dib);
		if(!src) throw(1);

		// get the luminance channel
		Yin = ConvertRGBFToY(src);
		if(!Yin) throw(1);

		// perform the tone mapping
		Yout = tmoFattal02(Yin, alpha, beta);
		if(!Yout) throw(1);

		// clip low and high values and normalize to [0..1]
		//NormalizeY(Yout, 0.001F, 0.995F);
		NormalizeY(Yout, 0, 1);

		// compress the dynamic range

		const unsigned width = FreeImage_GetWidth(src);
		const unsigned height = FreeImage_GetHeight(src);

		const unsigned rgb_pitch = FreeImage_GetPitch(src);
		const unsigned y_pitch = FreeImage_GetPitch(Yin);

		BYTE *bits      = (BYTE*)FreeImage_GetBits(src);
		BYTE *bits_yin  = (BYTE*)FreeImage_GetBits(Yin);
		BYTE *bits_yout = (BYTE*)FreeImage_GetBits(Yout);

		for(unsigned y = 0; y < height; y++) {
			float *Lin = (float*)bits_yin;
			float *Lout = (float*)bits_yout;
			float *color = (float*)bits;
			for(unsigned x = 0; x < width; x++) {
				for(unsigned c = 0; c < 3; c++) {
					*color = (Lin[x] > 0) ? pow(*color/Lin[x], s) * Lout[x] : 0;
					color++;
				}
			}
			bits += rgb_pitch;
			bits_yin += y_pitch;
			bits_yout += y_pitch;
		}

		// not needed anymore
		FreeImage_Unload(Yin);  Yin  = NULL;
		FreeImage_Unload(Yout); Yout = NULL;

		// clamp image highest values to display white, then convert to 24-bit RGB
		dst = ClampConvertRGBFTo24(src);

		// clean-up and return
		FreeImage_Unload(src); src = NULL;

		// copy metadata from src to dst
		FreeImage_CloneMetadata(dst, dib);
		
		return dst;

	} catch(int) {
		if(src) FreeImage_Unload(src);
		if(Yin) FreeImage_Unload(Yin);
		if(Yout) FreeImage_Unload(Yout);
		return NULL;
	}
}