Skip to content

Instantly share code, notes, and snippets.

@emilk
Created January 21, 2021 09:45
Show Gist options
  • Save emilk/68a753df82771eaef5168beac1a5f835 to your computer and use it in GitHub Desktop.
Save emilk/68a753df82771eaef5168beac1a5f835 to your computer and use it in GitHub Desktop.
OkLab in Rust
//! https://bottosson.github.io/posts/oklab/
/// oklab from linear rgb (0-1 ranges)
pub fn lab_from_rgb([r, g, b]: [f32; 3]) -> (f32, f32, f32) {
let x = 0.4121656120 * r + 0.5362752080 * g + 0.0514575653 * b;
let y = 0.2118591070 * r + 0.6807189584 * g + 0.1074065790 * b;
let z = 0.0883097947 * r + 0.2818474174 * g + 0.6302613616 * b;
let x = x.cbrt();
let y = y.cbrt();
let z = z.cbrt();
(
0.2104542553 * x + 0.7936177850 * y - 0.0040720468 * z,
1.9779984951 * x - 2.4285922050 * y + 0.4505937099 * z,
0.0259040371 * x + 0.7827717662 * y - 0.8086757660 * z,
)
}
/// linear rgb from oklab (0-1 ranges)
pub fn rgb_from_lab((l, a, b): (f32, f32, f32)) -> [f32; 3] {
let x = l + 0.3963377774 * a + 0.2158037573 * b;
let y = l - 0.1055613458 * a - 0.0638541728 * b;
let z = l - 0.0894841775 * a - 1.2914855480 * b;
let x = x.powi(3);
let y = y.powi(3);
let z = z.powi(3);
[
4.0767245293 * x - 3.3072168827 * y + 0.2307590544 * z,
-1.2681437731 * x + 2.6093323231 * y - 0.3411344290 * z,
-0.0041119885 * x - 0.7034763098 * y + 1.7068625689 * z,
]
}
/// 0-1 normalized lch from oklab.
pub fn lch_from_lab((l, a, b): (f32, f32, f32)) -> (f32, f32, f32) {
use std::f32::consts::TAU;
let c = a.hypot(b);
let h = (b.atan2(a) + TAU) % TAU / TAU;
(l, c, h)
}
/// Oklab from 0-1 normalized lch.
pub fn lab_from_lch((l, c, h): (f32, f32, f32)) -> (f32, f32, f32) {
use std::f32::consts::TAU;
let (sin_h, cos_h) = (h * TAU).sin_cos();
let a = c * cos_h;
let b = c * sin_h;
(l, a, b)
}
/// 0-1 normalized lch from linear rgb
pub fn lch_from_rgb(rgb: [f32; 3]) -> (f32, f32, f32) {
lch_from_lab(lab_from_rgb(rgb))
}
/// linear rgb from 0-1 normalized lch
pub fn rgb_from_lch(lch: (f32, f32, f32)) -> [f32; 3] {
rgb_from_lab(lab_from_lch(lch))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment