Toshihiro Shimizu 890ddd
#include "igs_color_rgb_hls.h"
Toshihiro Shimizu 890ddd
void igs::color::rgb_to_hls(
Toshihiro Shimizu 890ddd
	const double red, // 0.0...1.0
Toshihiro Shimizu 890ddd
	const double gre, // 0.0...1.0
Toshihiro Shimizu 890ddd
	const double blu, // 0.0...1.0
Toshihiro Shimizu 890ddd
	double &hue,	  /* 0.0...360.0	hue(色相) */
Toshihiro Shimizu 890ddd
	double &lig,	  /* 0.0...1.0	lightness(明度) */
Toshihiro Shimizu 890ddd
	double &sat		  /* 0.0...1.0	saturation(彩度) */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const double maxi =
Toshihiro Shimizu 890ddd
		(red < gre) ? ((gre < blu) ? blu : gre) : ((red < blu) ? blu : red);
Toshihiro Shimizu 890ddd
	const double mini =
Toshihiro Shimizu 890ddd
		(gre < red) ? ((blu < gre) ? blu : gre) : ((blu < red) ? blu : red);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	lig = (maxi + mini) / 2.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (maxi == mini) { /* RGB各値に差がない(=白黒で色がない) */
Toshihiro Shimizu 890ddd
		sat = 0.0;		/* saturation(彩度)はゼロ */
Toshihiro Shimizu 890ddd
		hue = 0.0;		/* hue(色相)は意味を持たない */
Toshihiro Shimizu 890ddd
	} else {			/* 色のあるとき */
Toshihiro Shimizu 890ddd
		if (lig <= 0.5) {
Toshihiro Shimizu 890ddd
			sat = (maxi - mini) / (maxi + mini);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			sat = (maxi - mini) / (2.0 - (maxi + mini));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/* 色相(Hue) */
Toshihiro Shimizu 890ddd
		const double rmid = (maxi - red) / (maxi - mini);
Toshihiro Shimizu 890ddd
		const double gmid = (maxi - gre) / (maxi - mini);
Toshihiro Shimizu 890ddd
		const double bmid = (maxi - blu) / (maxi - mini);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/* -1 .. 1 マゼンタ(M)から黄色(Y)までの間の色 */
Toshihiro Shimizu 890ddd
		if (red == maxi) {
Toshihiro Shimizu 890ddd
			hue = bmid - gmid;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*  1 .. 3 黄色(Y)からシアン(C)までの間の色 */
Toshihiro Shimizu 890ddd
		else if (gre == maxi) {
Toshihiro Shimizu 890ddd
			hue = 2.0 + rmid - bmid;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*  3 .. 5 シアン(C)からマゼンタ(M)までの間の色 */
Toshihiro Shimizu 890ddd
		else if (blu == maxi) {
Toshihiro Shimizu 890ddd
			hue = 4.0 + gmid - rmid;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
			M-R-Y-G-C-B-M
Toshihiro Shimizu 890ddd
		       -1 0 1 2 3 4 5
Toshihiro Shimizu 890ddd
		*/
Toshihiro Shimizu 890ddd
		hue *= 60.0; /* -60 ... 300 */
Toshihiro Shimizu 890ddd
		if (hue < 0.0) {
Toshihiro Shimizu 890ddd
			hue += 360.0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
double hls2rgb_calc(const double m1, const double m2, const double hue)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double hh = hue;
Toshihiro Shimizu 890ddd
	while (360.0 < hh) {
Toshihiro Shimizu 890ddd
		hh -= 360;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	while (hh < 0.0) {
Toshihiro Shimizu 890ddd
		hh += 360;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (hh < 60.0) {
Toshihiro Shimizu 890ddd
		return m1 + (m2 - m1) * hh / 60.0;
Toshihiro Shimizu 890ddd
	} else if (hh < 180.0) {
Toshihiro Shimizu 890ddd
		return m2;
Toshihiro Shimizu 890ddd
	} else if (hh < 240.0) {
Toshihiro Shimizu 890ddd
		return m1 + (m2 - m1) * (240.0 - hh) / 60.0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return m1; /* 240 ... 360 */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void igs::color::hls_to_rgb(
Toshihiro Shimizu 890ddd
	const double hue, /* 0.0...360.0	hue(色相) */
Toshihiro Shimizu 890ddd
	const double lig, /* 0.0...1.0	lightness(明度) */
Toshihiro Shimizu 890ddd
	const double sat, /* 0.0...1.0	saturation(彩度) */
Toshihiro Shimizu 890ddd
	double &red,	  /* 0.0...1.0 */
Toshihiro Shimizu 890ddd
	double &gre,	  /* 0.0...1.0 */
Toshihiro Shimizu 890ddd
	double &blu		  /* 0.0...1.0 */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (0.0 == sat) { /* 白黒で色がない */
Toshihiro Shimizu 890ddd
		red = gre = blu = lig;
Toshihiro Shimizu 890ddd
	} else { /* 色のあるとき */
Toshihiro Shimizu 890ddd
		const double m2 =
Toshihiro Shimizu 890ddd
			(lig <= 0.5) ? (lig * (1.0 + sat)) : (lig + sat - lig * sat);
Toshihiro Shimizu 890ddd
		const double m1 = 2.0 * lig - m2;
Toshihiro Shimizu 890ddd
		red = hls2rgb_calc(m1, m2, hue + 120.0);
Toshihiro Shimizu 890ddd
		gre = hls2rgb_calc(m1, m2, hue);
Toshihiro Shimizu 890ddd
		blu = hls2rgb_calc(m1, m2, hue - 120.0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}