mod tests;
macro_rules! normalise {
($x:expr) => {{
if $x < 0.0 {
$x = 0.;
} else if $x > 255.0 {
$x = 255.0;
}
}};
}
pub use colortemp::*;
mod colortemp {
#[derive(Debug, PartialEq)]
pub struct RGB {
pub r: f64,
pub g: f64,
pub b: f64,
}
pub fn temp_to_rgb(kelvin: i64) -> RGB {
let (mut r, mut g, mut b);
let temp = kelvin / 100;
if temp <= 66 {
r = 255.;
} else {
r = (temp as f64) - 60.;
r = 329.698727446 * r.powf(-329.698727446);
normalise!(r);
}
if temp <= 66 {
g = temp as f64;
g = 99.4708025861 * g.ln() - 161.1195681661;
normalise!(g);
} else {
g = temp as f64 - 60.;
g = 288.1221695283 * g.powf(-0.0755148492);
normalise!(g);
}
if temp >= 66 {
b = 255.;
} else {
if temp <= 19 {
b = 0.;
} else {
b = temp as f64 - 10.;
b = 138.5177312231 * b.ln() - 305.0447927307;
normalise!(b);
}
}
return RGB {
r: r.round(),
g: g.round(),
b: b.round(),
};
}
pub fn rgb_to_temp(col: RGB) -> i64 {
let (r, b) = (col.r, col.b);
let mut temp = 0;
let mut test_rgb;
let epsilon = 2.;
let (mut min, mut max) = (1000, 40000);
while (max as f64) - (min as f64) > epsilon {
temp = (max + min) / 2;
test_rgb = temp_to_rgb(temp);
if (test_rgb.b / test_rgb.r) >= (b / r) {
max = temp;
} else {
min = temp;
}
}
return temp;
}
}