Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImage/tmoDrago03.cpp  view on Meta::CPAN

			pixel[x].red = (float)((L / interpol) / divider);
		}
		// next line
		bits += pitch;
	}

#endif	// DRAGO03_FAST

	return TRUE;
}

/**
Custom gamma correction based on the ITU-R BT.709 standard
@param dib RGBF image to be corrected
@param gammaval Gamma value (2.2 is a good default value)
@return Returns TRUE if successful, returns FALSE otherwise
*/
static BOOL 
REC709GammaCorrection(FIBITMAP *dib, const float gammaval) {
	if(FreeImage_GetImageType(dib) != FIT_RGBF)
		return FALSE;

	float slope = 4.5F;
	float start = 0.018F;
	
	const float fgamma = (float)((0.45 / gammaval) * 2);
	if(gammaval >= 2.1F) {
		start = (float)(0.018 / ((gammaval - 2) * 7.5));
		slope = (float)(4.5 * ((gammaval - 2) * 7.5));
	} else if (gammaval <= 1.9F) {
		start = (float)(0.018 * ((2 - gammaval) * 7.5));
		slope = (float)(4.5 / ((2 - gammaval) * 7.5));
	}

	const unsigned width  = FreeImage_GetWidth(dib);
	const unsigned height = FreeImage_GetHeight(dib);
	const unsigned pitch  = FreeImage_GetPitch(dib);

	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
	for(unsigned y = 0; y < height; y++) {
		float *pixel = (float*)bits;
		for(unsigned x = 0; x < width; x++) {
			for(int i = 0; i < 3; i++) {
				*pixel = (*pixel <= start) ? *pixel * slope : (1.099F * pow(*pixel, fgamma) - 0.099F);
				pixel++;
			}
		}
		bits += pitch;
	}

	return TRUE;
}

// ----------------------------------------------------------
//  Main algorithm
// ----------------------------------------------------------

/**
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;
}



( run in 0.591 second using v1.01-cache-2.11-cpan-5623c5533a1 )