/* COLORMAPS 1.0  (c) Jacek Matulewski 2001 */
/* Translation function between color coordinates */
/* Jacek Matulewski (jacek@phys.uni.torun.pl) */

#ifndef __COLORMAPS_CPP
#define __COLORMAPS_CPP

#include "colormaps.h"
#include <math.h>

#define  min(x,y)  (x)<(y)?(x):(y)
#define  max(x,y)  (x)>(y)?(x):(y)

double gamma_correction(double L,double L_range,double gamma=colormaps_gamma)
{
    L=L/L_range; //L->L_relative
	double E_prime=pow(L,gamma);
   	return L_range*E_prime; //from relative to the same range as L
}

double gamma_correction_709(double L,double L_range)
{
    //In 709 specification gamma=0.45 is used
    //L is color value or lightness, brightness etc
    L=L/L_range; //L->L_relative
	double E_prime;
	if (L<=0.018) E_prime=4.5*L; else E_prime=1.099*pow(L,0.45)-0.099; //Nonlinear part matched to gamma=0.45
   	return L_range*E_prime; //from relative to the same range as L
}

nlrgb_triplet rgb_gamma_correction(rgb_triplet rgb,double gamma=colormaps_gamma)
{
    nlrgb_triplet nlrgb;
    nlrgb.r=(cm_byte)gamma_correction(rgb.r,rgb_white.r,gamma);
    nlrgb.g=(cm_byte)gamma_correction(rgb.g,rgb_white.g,gamma);
    nlrgb.b=(cm_byte)gamma_correction(rgb.b,rgb_white.b,gamma);
    return nlrgb;
};

nlrgb_triplet rgb_gamma_correction_709(rgb_triplet rgb)
{
    nlrgb_triplet nlrgb;
    nlrgb.r=(cm_byte)gamma_correction_709(rgb.r,rgb_white.r);
    nlrgb.g=(cm_byte)gamma_correction_709(rgb.g,rgb_white.g);
    nlrgb.b=(cm_byte)gamma_correction_709(rgb.b,rgb_white.b);
    return nlrgb;
};

nlrgb_triplet rgb2nlrgb(rgb_triplet rgb)
{
    return rgb_gamma_correction_709(rgb);
}

double inverse_gamma_correction_709(double E_prime, double E_prime_range)
{
    //Here gamma is set to 0.45 and linear part is included (see gamma_correction_709())
    E_prime=E_prime/E_prime_range; //to relative value
	double L;
	if (E_prime<=0.081) L=E_prime/4.5; else L=pow((E_prime+0.099)/1.099,1.0/0.45);
   	return E_prime_range*L;
}

double inverse_gamma_correction(double E_prime, double E_prime_range, double gamma=colormaps_gamma)
{
    E_prime=E_prime/E_prime_range; //to relative value
	double L=pow(E_prime,1.0/gamma);
   	return E_prime_range*L;
}

rgb_triplet nlrgb_inverse_gamma_correction(nlrgb_triplet nlrgb,double gamma=colormaps_gamma)
{
    rgb_triplet rgb;
    rgb.r=(cm_byte)inverse_gamma_correction(nlrgb.r,rgb_white.r,gamma);
    rgb.g=(cm_byte)inverse_gamma_correction(nlrgb.g,rgb_white.g,gamma);
    rgb.b=(cm_byte)inverse_gamma_correction(nlrgb.b,rgb_white.b,gamma);
    return rgb;
}

rgb_triplet nlrgb_inverse_gamma_correction_709(nlrgb_triplet nlrgb)
{
    rgb_triplet rgb;
    rgb.r=(cm_byte)inverse_gamma_correction_709(nlrgb.r,rgb_white.r);
    rgb.g=(cm_byte)inverse_gamma_correction_709(nlrgb.g,rgb_white.g);
    rgb.b=(cm_byte)inverse_gamma_correction_709(nlrgb.b,rgb_white.b);
    return rgb;
}

rgb_triplet nlrgb2rgb(nlrgb_triplet nlrgb)
{
    return nlrgb_inverse_gamma_correction_709(nlrgb);
}

int rgb2int(rgb_triplet rgb) //range as for 24-bits integer
{
    return rgb.r+256*(rgb.g+256*rgb.b);
}

cm_byte rgb2brightness(rgb_triplet rgb) //range [0:255], common symbol Br
{
    return cm_byte((rgb.r+rgb.g+rgb.b)/3.0); //all weights are 0.33(3)
}

double rgb2luminance(rgb_triplet rgb) //range [0:255], common symbol: Y
{
    return 0.2126*rgb.r+0.7152*rgb.g+0.0722*rgb.b; //weigths are taken from CCIR Rec. 709
}

double nlrgb2luma(nlrgb_triplet nlrgb) //range [0:255], common symbol Y'
{
    return 0.299*nlrgb.r+0.587*nlrgb.g+0.114*nlrgb.b; //weigths are taken from CCIR Rec. 601
}

double rgb2lightness(rgb_triplet rgb) //range [0:100], common symbol: L
{
    double Y_white=rgb2luminance(rgb_white); //double, then byte/double -> double
    double Y=rgb2luminance(rgb);
    double L;
    if (Y/Y_white>0.008856) L=(116*pow(Y/Y_white,1.0/3)-16);
    					else L=903.3*(Y/Y_white);
    return L;
}


/* LINEAR COLOR MAPS TRANSFORMATIONS */
cmy_triplet rgb2cmy(rgb_triplet rgb)
{
    cmy_triplet cmyk;
    cmyk.c=255-rgb.r;
    cmyk.m=255-rgb.g;
    cmyk.y=255-rgb.b;
    cmyk.k=(cm_byte)((rgb.r+rgb.g+rgb.b)/3.0);
	return cmyk;
}

rgb_triplet cmy2rgb(cmy_triplet cmy)
{
    rgb_triplet rgb;
    rgb.r=255-cmy.c;
    rgb.g=255-cmy.m;
    rgb.b=255-cmy.y;
	return rgb;
}


/* NONLINEAR COLOR MAPS TRANSFORMATION */
hsb_triplet rgb2hsb(rgb_triplet rgb)
{
    hsb_triplet hsb;

	double _min,_max,delta,tmp;
	_min=min(rgb.r,min(rgb.g,rgb.b));
	_max=max(rgb.r,max(rgb.g,rgb.b));
	delta=_max-_min;

	hsb.b=(int)_max;
	if(delta==0) //Szary
	{
		hsb.h=0;
        hsb.s=0;
	}
	else
	{
		tmp=delta/_max;
		hsb.s=(int)(tmp*255);

		if(rgb.r==(int)_max)
		{
			tmp=(double)(rgb.g-rgb.b)/delta;
		}
		else
			if(rgb.g==(int)_max)
			{
				tmp=2.0+((double)(rgb.b-rgb.r)/delta);
			}
			else
			{
				tmp=4.0+((double)(rgb.r-rgb.g)/delta);
			}
		tmp=tmp*60;
		if(tmp<0)
		{
			tmp+=360;
		}
		if(tmp==360)
		{
			tmp=0;
		}
		hsb.h=(int)tmp;
	}
	return hsb;
}


rgb_triplet hsb2rgb(hsb_triplet hsb)
{
    rgb_triplet rgb;
	if(hsb.h==0 && hsb.s==0) //Szary
	{
    	rgb.r=hsb.b;
        rgb.g=hsb.b;
        rgb.b=hsb.b;
	}

    double _min,_max,delta,hue;

	_max=hsb.b;
	delta=(_max*hsb.s)/255.0;
	_min=_max-delta;

	hue=hsb.h;
	if(hsb.h>300 || hsb.h<=60)
	{
		rgb.r=(int)_max;
		if(hsb.h>300)
		{
			rgb.g=(int)_min;
			hue=(hue-360.0)/60.0;
			rgb.b=(int)(_min-hue*delta);
		}
		else
		{
			rgb.b=(int)_min;
			hue=hue/60.0;
			rgb.g=(int)(_min+hue*delta);
		}
	}
	else
		if(hsb.h>60 && hsb.h<180)
		{
			rgb.g=(int)_max;
			if(hsb.h<120)
			{
				rgb.b=(int)_min;
				hue=(hue/60.0-2.0)*delta;
				rgb.r=(int)(_min-hue);
			}
			else
			{
				rgb.r=(int)_min;
				hue=(hue/60-2.0)*delta;
				rgb.b=(int)(_min+hue);
			}
        }
		else
		{
			rgb.b=(int)_max;
			if(hsb.h<240)
			{
				rgb.r=(int)_min;
				hue=(hue/60.0-4.0)*delta;
				rgb.g = (int)(_min-hue);
			}
			else
			{
				rgb.g=(int)_min;
				hue=(hue/60-4.0)*delta;
				rgb.r=(int)(_min + hue);
			}
		}
	return rgb;
}


hsv_triplet hsb2hsv(hsb_triplet hsb)
{
    hsv_triplet hsv;
    hsv.h=hsb.h;
    hsv.s=cm_byte(hsb.s/2.55);
    hsv.v=cm_byte(hsb.b/2.55);
    return hsv;
}

hsb_triplet hsv2hsb(hsv_triplet hsv)
{
    hsb_triplet hsb;
    hsb.h=hsv.h;
    hsb.s=cm_byte(hsv.s*2.55);
    hsb.b=cm_byte(hsv.v*2.55);
    return hsb;
}

hsv_triplet rgb2hsv(rgb_triplet rgb)
{
    return hsb2hsv(rgb2hsb(rgb));
}

rgb_triplet hsv2rgb(hsv_triplet hsv)
{
    return hsb2rgb(hsv2hsb(hsv));
}

cieXYZ_triplet rgb2cieXYZ(rgb_triplet rgb)
{
    cieXYZ_triplet cieXYZ;
    double r=rgb.r/255.0, g=rgb.g/255.0, b=rgb.b/255.0; //[0:255]->[0:1]
    cieXYZ.X=0.412453*r+0.357580*g+0.180423*b;
	cieXYZ.Y=0.212671*r+0.715160*g+0.072169*b;
    cieXYZ.Z=0.019334*r+0.119193*g+0.950227*b;
    if (cieXYZ.X>1) cieXYZ.X=1;
    if (cieXYZ.Y>1) cieXYZ.Y=1;
    if (cieXYZ.Z>1) cieXYZ.Z=1;
    return cieXYZ;
}

rgb_triplet cieXYZ2rgb(cieXYZ_triplet cieXYZ)
{
	double r,g,b;
    r= 3.240479*cieXYZ.X-1.537150*cieXYZ.Y-0.498535*cieXYZ.Z;
    g=-0.969256*cieXYZ.X+1.875992*cieXYZ.Y+0.041556*cieXYZ.Z;
    b= 0.055648*cieXYZ.X-0.204043*cieXYZ.Y+1.057311*cieXYZ.Z;
    if (r<0) r=0; if (r>1) r=1;
    if (g<0) g=0; if (g>1) g=1;
    if (b<0) b=0; if (b>1) b=1;
    rgb_triplet rgb;
    rgb.r=cm_byte((int)255*r); rgb.g=cm_byte((int)255*g); rgb.b=cm_byte((int)255*b); //[0:1]->[0:255]
    return rgb;
}

ciexyz_triplet cieXYZ2ciexyz(cieXYZ_triplet cieXYZ)
{
    ciexyz_triplet ciexyz;
    if (cieXYZ.X==0 && cieXYZ.Y==0 && cieXYZ.Z==0)
    {
        ciexyz.x=0;
        ciexyz.y=0;
        ciexyz.z=0;
		return ciexyz;
    }
    ciexyz.x=cieXYZ.X/(cieXYZ.X+cieXYZ.Y+cieXYZ.Z);
    ciexyz.y=cieXYZ.Y/(cieXYZ.X+cieXYZ.Y+cieXYZ.Z);
    ciexyz.z=cieXYZ.Z/(cieXYZ.X+cieXYZ.Y+cieXYZ.Z);
    return ciexyz;
}

ciexyY_triplet cieXYZ2ciexyY(cieXYZ_triplet cieXYZ)
{
    ciexyY_triplet ciexyY;
    if (cieXYZ.X==0 && cieXYZ.Y==0 && cieXYZ.Z==0)
    {
        ciexyY.x=0;
        ciexyY.y=0;
        ciexyY.Y=0;
		return ciexyY;
    }
    ciexyY.x=cieXYZ.X/(cieXYZ.X+cieXYZ.Y+cieXYZ.Z);
    ciexyY.y=cieXYZ.Y/(cieXYZ.X+cieXYZ.Y+cieXYZ.Z);
    ciexyY.Y=cieXYZ.Y;
    return ciexyY;
}

cieXYZ_triplet ciexyY2cieXYZ(ciexyY_triplet ciexyY)
{
    cieXYZ_triplet cieXYZ;
    if (ciexyY.y==0)
   	{
        //To trzeba poprawic
        cieXYZ.X=0;
		cieXYZ.Y=0;
        cieXYZ.Z=0;
        return cieXYZ;
	}
    cieXYZ.X=ciexyY.x*(ciexyY.Y/ciexyY.y);
	cieXYZ.Y=ciexyY.Y;
    cieXYZ.Z=(1-ciexyY.x-ciexyY.y)*(ciexyY.Y/ciexyY.y);
    return cieXYZ;
}


ciexyY_triplet rgb2ciexyY(rgb_triplet rgb)
{
    return cieXYZ2ciexyY(rgb2cieXYZ(rgb));
}

rgb_triplet ciexyY2rgb(ciexyY_triplet ciexyY)
{
    return cieXYZ2rgb(ciexyY2cieXYZ(ciexyY));
}

YPbPr_triplet nlrgb2YPbPr(nlrgb_triplet nlrgb)
{
    //Y is scaled luma (see rgb2luma(..)), but luma is formely definied for nonlinear rgb
    double r=nlrgb.r/255.0, g=nlrgb.g/255.0, b=nlrgb.b/255.0; //[0:255]->[0:1]
    YPbPr_triplet ypbpr;
	ypbpr.Y=  0.299*r+0.587*g+0.114*b; //Y'
   	ypbpr.Pb=-0.299*r-0.587*g+0.886*b; //Now it is B'-Y'
	ypbpr.Pr= 0.701*r-0.587*g-0.114*b; //Now it is R'-Y'
	ypbpr.Pb=(0.5/0.886)*ypbpr.Pb; //->Pb
    ypbpr.Pr=(0.5/0.701)*ypbpr.Pr; //->Pr
    return ypbpr;
}

nlrgb_triplet YPbPr2nlrgb(YPbPr_triplet ypbpr)
{
	double r=ypbpr.Y+1.402*ypbpr.Pr;
	double g=ypbpr.Y-0.344136*ypbpr.Pb-0.714136*ypbpr.Pr;
    double b=ypbpr.Y+1.772*ypbpr.Pb;
    if (r<0) r=0; if (r>1) r=1;
    if (g<0) g=0; if (g>1) g=1;
    if (b<0) b=0; if (b>1) b=1;
    nlrgb_triplet nlrgb;
    nlrgb.r=cm_byte(255*r);
    nlrgb.g=cm_byte(255*g);
    nlrgb.b=cm_byte(255*b);
    return nlrgb;
}

double XYZ2U(cieXYZ_triplet cieXYZ)
{
    if (cieXYZ.X==0 && cieXYZ.Y==0 && cieXYZ.Z==0) return 0;
    return 4*cieXYZ.X/(cieXYZ.X+15*cieXYZ.Y+3*cieXYZ.Z);
}

double XYZ2V(cieXYZ_triplet cieXYZ)
{
    if (cieXYZ.X==0 && cieXYZ.Y==0 && cieXYZ.Z==0) return 0;
    return 9*cieXYZ.Y/(cieXYZ.X+15*cieXYZ.Y+3*cieXYZ.Z);
}

cieLUV_triplet rgb2cieLUV(rgb_triplet rgb)
{
    cieLUV_triplet cieLUV;
    cieLUV.L=rgb2lightness(rgb);
    cieXYZ_triplet cieXYZ=rgb2cieXYZ(rgb);
    cieXYZ_triplet cieXYZ_white=rgb2cieXYZ(rgb_white);
    cieLUV.U=13*cieLUV.L*(XYZ2U(cieXYZ)-XYZ2U(cieXYZ_white));
    cieLUV.V=13*cieLUV.L*(XYZ2V(cieXYZ)-XYZ2V(cieXYZ_white));
    return cieLUV;
}



/* This function is modified version of RGB VALUES FOR HOT OBJECTS by Dan Bruton (astro@sfasu.edu) */

//from 380nm to 780nm every 5nm
const int CIEXYZCMF_bandsnumber=81;
double CIEXYZColorMatchingFunction[][3]=
{
	{0.0014, 0.0000, 0.0065},
	{0.0022, 0.0001, 0.0105},
	{0.0042, 0.0001, 0.0201},
	{0.0076, 0.0002, 0.0362},
	{0.0143, 0.0004, 0.0679},
	{0.0232, 0.0006, 0.1102},
	{0.0435, 0.0012, 0.2074},
	{0.0776, 0.0022, 0.3713},
	{0.1344, 0.0040, 0.6456},
	{0.2148, 0.0073, 1.0391},
	{0.2839, 0.0116, 1.3856},
	{0.3285, 0.0168, 1.6230},
	{0.3483, 0.0230, 1.7471},
	{0.3481, 0.0298, 1.7826},
	{0.3362, 0.0380, 1.7721},
	{0.3187, 0.0480, 1.7441},
	{0.2908, 0.0600, 1.6692},
	{0.2511, 0.0739, 1.5281},
	{0.1954, 0.0910, 1.2876},
	{0.1421, 0.1126, 1.0419},
	{0.0956, 0.1390, 0.8130},
	{0.0580, 0.1693, 0.6162},
	{0.0320, 0.2080, 0.4652},
	{0.0147, 0.2586, 0.3533},
	{0.0049, 0.3230, 0.2720},
	{0.0024, 0.4073, 0.2123},
	{0.0093, 0.5030, 0.1582},
	{0.0291, 0.6082, 0.1117},
	{0.0633, 0.7100, 0.0782},
	{0.1096, 0.7932, 0.0573},
	{0.1655, 0.8620, 0.0422},
	{0.2257, 0.9149, 0.0298},
	{0.2904, 0.9540, 0.0203},
	{0.3597, 0.9803, 0.0134},
	{0.4334, 0.9950, 0.0087},
	{0.5121, 1.0000, 0.0057},
	{0.5945, 0.9950, 0.0039},
	{0.6784, 0.9786, 0.0027},
	{0.7621, 0.9520, 0.0021},
	{0.8425, 0.9154, 0.0018},
	{0.9163, 0.8700, 0.0017},
	{0.9786, 0.8163, 0.0014},
	{1.0263, 0.7570, 0.0011},
	{1.0567, 0.6949, 0.0010},
	{1.0622, 0.6310, 0.0008},
	{1.0456, 0.5668, 0.0006},
	{1.0026, 0.5030, 0.0003},
	{0.9384, 0.4412, 0.0002},
	{0.8544, 0.3810, 0.0002},
	{0.7514, 0.3210, 0.0001},
	{0.6424, 0.2650, 0.0000},
	{0.5419, 0.2170, 0.0000},
	{0.4479, 0.1750, 0.0000},
	{0.3608, 0.1382, 0.0000},
	{0.2835, 0.1070, 0.0000},
	{0.2187, 0.0816, 0.0000},
	{0.1649, 0.0610, 0.0000},
	{0.1212, 0.0446, 0.0000},
	{0.0874, 0.0320, 0.0000},
	{0.0636, 0.0232, 0.0000},
	{0.0468, 0.0170, 0.0000},
	{0.0329, 0.0119, 0.0000},
	{0.0227, 0.0082, 0.0000},
	{0.0158, 0.0057, 0.0000},
	{0.0114, 0.0041, 0.0000},
	{0.0081, 0.0029, 0.0000},
	{0.0058, 0.0021, 0.0000},
	{0.0041, 0.0015, 0.0000},
	{0.0029, 0.0010, 0.0000},
	{0.0020, 0.0007, 0.0000},
	{0.0014, 0.0005, 0.0000},
	{0.0010, 0.0004, 0.0000},
	{0.0007, 0.0002, 0.0000},
	{0.0005, 0.0002, 0.0000},
	{0.0003, 0.0001, 0.0000},
	{0.0002, 0.0001, 0.0000},
	{0.0002, 0.0001, 0.0000},
	{0.0001, 0.0000, 0.0000},
	{0.0001, 0.0000, 0.0000},
	{0.0001, 0.0000, 0.0000},
	{0.0000, 0.0000, 0.0000}
};


double blackbody_I(double wavelength,double temperature) //radiation intensity for black body
{
    const double con=1240.0/8.617e-5;
    //I(w)=h*w^3 / Pi^2*c^2*(e^(hw/kT)-1 but translated to wavelength
    return 3.74183e-16*(1.0/pow(wavelength,5))/(exp(con/(wavelength*temperature))-1.);
}

rgb_triplet BlackBodyTemperature2rgb(double temperature, double gamma=colormaps_gamma)
{
    //Integration ;over wavelength for black body spectrum
    double X=0, Y=0, Z=0;
    for(int band=0;band<CIEXYZCMF_bandsnumber;band++)
	{
        double wavelength=380.0+(double)band*5.0;/* wavelength in nm */
        double weight=1; if (band==0 || band==CIEXYZCMF_bandsnumber) weight=0.5; //weigth for traoezoid method of integrating
        double dis=blackbody_I(wavelength,temperature);
        X=X+weight*dis*CIEXYZColorMatchingFunction[band][0];
        Y=Y+weight*dis*CIEXYZColorMatchingFunction[band][1];
        Z=Z+weight*dis*CIEXYZColorMatchingFunction[band][2];
	}

	/*
    X=pow(X,gamma);
    Y=pow(Y,gamma);
    Z=pow(Z,gamma);
	*/
	X=gamma_correction(X,1,gamma);
    Y=gamma_correction(Y,1,gamma);
    Z=gamma_correction(Z,1,gamma);

    double maxXYZ=max(X,max(Y,Z));
    X=X/maxXYZ; Y=Y/maxXYZ; Z=Z/maxXYZ;
    cieXYZ_triplet cieXYZ={X,Y,Z};
    return cieXYZ2rgb(cieXYZ);
}


/* This is translated to C version of function RGB VALUES FOR VISIBLE WAVELENGTHS by Dan Bruton (astro@tamu.edu) */

rgb_triplet SunWavelength2rgb(double wavelength, double gamma=colormaps_gamma)
{
    if (wavelength<380 || wavelength>780) return rgb_black;

	double r=0,g=0,b=0;

    //Paleta liniowa
	if (wavelength>=380 && wavelength<440)
	{
	    r=-1*(wavelength-440)/(440-380);
	    g=0;
	    b=1;
	}
	if (wavelength>=440 && wavelength<490)
	{
	    r=0;
	    g=(wavelength-440)/(490-440);
	    b=1;
	}
	if (wavelength>=490 && wavelength<510)
	{
	    r=0;
	    g=1;
	    b=-1*(wavelength-510)/(510-490);
	}
	if (wavelength>=510 && wavelength<580)
	{
		r=(wavelength-510)/(580-510);
	    g=1;
	    b=0;
	}
	if (wavelength>=580 && wavelength<645)
	{
	    r=1;
	    g=-1*(wavelength-645)/(645-580);
	    b=0;
	}
	if (wavelength>=645 && wavelength<=780)
	{
	    r=1;
	    g=0;
	    b=0;
	}

	//Poprawki na granicach widzialnosci
    double s=1;
    if (wavelength>700) s=0.3+0.7*(780-wavelength)/(780-700);
	if (wavelength<420) s=0.3+0.7*(wavelength-380)/(420-380);

    r=gamma_correction(s*r,s,gamma); //range of s*r is s*1
    g=gamma_correction(s*g,s,gamma);
    b=gamma_correction(s*b,s,gamma);

    rgb_triplet rgb={cm_byte(255*r),cm_byte(255*g),cm_byte(255*b)};
    return rgb;
}


rgb_triplet SetColorSzary(double min, double max, double psi)
{
	rgb_triplet Kolor;
    Kolor.r=Kolor.g=Kolor.b=0;
    double delta=max-min, dp=psi-min;
    if (!delta) return Kolor;
  	Kolor.r=cm_byte((255*dp/delta));
  	Kolor.g=cm_byte((255*dp/delta));
  	Kolor.b=cm_byte((255*dp/delta));
  	return Kolor;
}

rgb_triplet SetColorJednolity(rgb_triplet kolor)
{
    return kolor;
}

rgb_triplet SetColorWLength(double min, double max, double psi)
{
    return SunWavelength2rgb(380+(psi-min)*400/(max-min));
}

rgb_triplet SetColorTemp(double min, double max, double psi)
{
    return BlackBodyTemperature2rgb(1000+(psi-min)*10000/(max-min));
}

rgb_triplet SetColorN5(double min, double max, double psi)
{
	unsigned char przedzial;	//numer podprzedziału
    rgb_triplet Kolor;			//przechowuje składowe koloru
    double delta=max-min,		//różnica pomiędzy maksymalna a minimalna
								//wartościa danych
           dr=delta/5.0,dp;		//szerokość podprzedziału

    Kolor.r=Kolor.g=Kolor.b=0; //wyzerowanie składowych
    //wyznaczenie podprzedziału, do którego zalicza sie wartość psi
  	if ((psi>=min) && (psi<(min+dr))) przedzial=1;
  	else if ((psi>=min+dr) && (psi<(min+2*dr))) przedzial=2;
  	else if ((psi>=min+2*dr) && (psi<(min+3*dr))) przedzial=3;
  	else if ((psi>=min+3*dr) && (psi<(min+4*dr))) przedzial=4;
  	else przedzial=5;

    if (!delta) return Kolor; //jeżeli min=max zwracamy kolor czarny
    switch (przedzial) 
	{
        //przedział pierwszy
        //R=G=0 B=0->255
        case 1 : Kolor.r=0; Kolor.g=0;
            	 dp=psi-min;
            	 Kolor.b=cm_byte((255*dp/dr));
                 break;
        //przedział drugi
        //R=0 B=255 G=0->255
        case 2 : Kolor.r=0; Kolor.b=255;
            	 dp=psi-(min+dr);
            	 Kolor.g=cm_byte((255*dp/dr));
                 break;
        //przedział trzeci
        //R=0 G=255 B=255->0
        case 3 : Kolor.r=0; Kolor.g=255;
            	 dp=psi-(min+2*dr);
            	 Kolor.b=cm_byte(255-(255*dp/dr));
                 break;
        //przedział czwarty
        //G=255 B=0 R=0->255
        case 4 : Kolor.g=255; Kolor.b=0;
            	 dp=psi-(min+3*dr);
            	 Kolor.r=cm_byte((255*dp/dr));
                 break;
        //przedział piaty
        //R=255 B=0 G=255->0
		case 5 : Kolor.r=255; Kolor.b=0;
            	 dp=psi-(min+4*dr);
            	 Kolor.g=cm_byte(255-(255*dp/dr));
                 break;
    }
    return Kolor;
}

rgb_triplet SetColorN7(double min, double max, double psi)
{
    rgb_triplet Kolor;
	unsigned char przedzial;
    double delta=max-min, dr=delta/7.0,dp;

    Kolor.r=Kolor.b=Kolor.g=0;
    if (!delta) return Kolor;
  	if ((psi>=min) && (psi<(min+dr))) przedzial=7;
  	else if ((psi>=min+dr) && (psi<(min+2*dr))) przedzial=6;
  	else if ((psi>=min+2*dr) && (psi<(min+3*dr))) przedzial=5;
  	else if ((psi>=min+3*dr) && (psi<(min+4*dr))) przedzial=4;
    else if ((psi>=min+4*dr) && (psi<(min+5*dr))) przedzial=3;
    else if ((psi>=min+5*dr) && (psi<(min+6*dr))) przedzial=2;
  	else przedzial=1;

    switch (przedzial) 
	{
        case 1 : Kolor.r=255;
            	 dp=psi-(min+6*dr);
            	 Kolor.g=Kolor.b=cm_byte((255*dp/dr));
                 break;
		case 2 : Kolor.r=255; Kolor.b=0;
            	 dp=psi-(min+5*dr);
            	 Kolor.g=cm_byte(255-(255*dp/dr));
                 break;
        case 3 : Kolor.g=255; Kolor.b=0;
            	 dp=psi-(min+4*dr);
            	 Kolor.r=cm_byte((255*dp/dr));
                 break;
        case 4 : Kolor.r=0; Kolor.g=255;
            	 dp=psi-(min+3*dr);
            	 Kolor.b=cm_byte(255-(255*dp/dr));
                 break;
        case 5 : Kolor.r=0; Kolor.b=255;
            	 dp=psi-(min+2*dr);
            	 Kolor.g=cm_byte((255*dp/dr));
                 break;
        case 6 : Kolor.g=0; Kolor.b=255;
            	 dp=psi-(min+dr);
            	 Kolor.r=cm_byte(255-(255*dp/dr));
                 break;
        case 7 : Kolor.g=0;
            	 dp=psi-min;
            	 Kolor.r=Kolor.b=cm_byte((255*dp/dr));
                 break;
    }
    return Kolor;
}


#endif //__COLORMAPS_CPP
