/* color.c */
#include <stdio.h>
#include <math.h>
#include "vector.h"
#include "color.h"
#include "mymath.h"

RGB 	NullRGB   = {0., 0., 0.},
        Black     = {0., 0., 0.},
        Red       = {1., 0., 0.},
        Yellow    = {1., 1., 0.},
        Green     = {0., 1., 0.},
        Turquoise = {0., 1., 1.},
        Blue      = {0., 0., 1.},
        Magenta   = {1., 0., 1.},
        White     = {1., 1., 1.};

/* gamma correction factor */
static float _gamma_ = 1.0;

void RGBSetGamma(float gam)
{
	_gamma_ = gam;
}

/* averge radiance used for rescaling. no rescaling if set to zero */
static float avmax = 0.;

void SetRadianceRescaleFactor(float averageradiance)
{
	avmax = averageradiance;
}

COLOR *RescaleRadiance(COLOR in, COLOR *out)
{
	float max, factor;

	if (avmax == 0.) {*out = in; return out;}

	max = in.r;
	if (in.g > max) max = in.g;
	if (in.b > max) max = in.b;
	if (max < EPSILON) {*out = in; return out;}

    	factor = (1. - exp(-M_LN2 * max/avmax)) / max;
	COLORSCALE(factor, in, *out);
	return out;
}

/* converts colors in the physically based model to the RGB model,
 * currently very simple ... */
RGB *ColorToRGB(COLOR color, RGB *rgb)
{
	rgb->r = color.r;
	rgb->g = color.g;
	rgb->b = color.b;
	return rgb;
}

/* does gamma correction for the display being used */
RGB *RGBGammaCorrect(RGB *rgb)
{
	RGBCLIP(*rgb);
	RGBGAMMACORRECT(*rgb, _gamma_);
	return rgb;
}

/* does everything to convert computed radiances to RGB colors
 * ready for display on the screen */
RGB *RadianceToRGB(COLOR color, RGB *rgb)
{
	RescaleRadiance(color, &color);
	ColorToRGB(color, rgb);
	RGBGammaCorrect(rgb);
	return rgb;
}

