go-colorful
go-colorful copied to clipboard
[wip] oklab
xyz -> oklab for draft to fix #54
oklab->xyz failing due to fp inaccuracy (I think?) with calculated matrix inverse. Might have to go through linear rgb for now. Port should be easy. Ref: https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab.
I tested walking it through linear rgb and also with integrating the matrices from comments at: https://github.com/LeaVerou/color.js/issues/109#issuecomment-938312745, but the precision failures on oklab->xyz still remain. This isn't my normal area of expertise, so I'm still unclear of where to take it from here, but hopefully this is helpful.
//OklabToXyz converts from Oklab space to CIE XYZ-space
func OklabToXyz(l, a, b float64) (x, y, z float64) {
// l_ := 0.9999999985*l + 0.3963377922*a + 0.2158037581*b
// m_ := 1.0000000089*l - 0.1055613423*a - 0.0638541748*b
// s_ := 1.0000000547*l - 0.0894841821*a - 1.2914855379*b
// ll := l_ * l_ * l_
// m := m_ * m_ * m_
// s := s_ * s_ * s_
// x = 1.2270138511*ll - 0.5577999807*m + 0.2812561490*s
// y = -0.0405801784*ll + 1.1122568696*m - 0.0716766787*s
// z = -0.0763812845*ll - 0.4214819784*m + 1.5861632204*s
// return
r, g, B := OklabToLinearRgb(l, a, b)
return LinearRgbToXyz(r, g, B)
}
//OklabToLinearRgb converts from Oklab space to Linear RGB space.
func OklabToLinearRgb(l, a, b float64) (r, g, B float64) {
ll := 0.9999999984505196*l + 0.39633779217376774*a + 0.2158037580607588*b
m := 1.0000000088817607*l - 0.10556134232365633*a - 0.0638541747717059*b
s := 1.0000000546724108*l - 0.08948418209496574*a - 1.2914855378640917*b
ll = ll * ll * ll
m = m * m * m
s = s * s * s
r = 4.076741661347994*ll - 3.3077115904081933*m + 0.23096992872942793*s
g = -1.2684380040921763*ll + 2.6097574006633715*m - 0.3413193963102196*s
B = -0.004196086541837079*ll - 0.7034186144594495*m + 1.7076147009309446*s
return r, g, B
}
colors_test.go:466: 1. OklabToXyz => (1.001), want 1 (x)
colors_test.go:469: 2. OklabToXyz => (1.001), want 1 (y)
colors_test.go:472: 2. OklabToXyz => (0.001), want 0 (z)
colors_test.go:466: 3. OklabToXyz => (0.001), want 0 (x)
colors_test.go:472: 3. OklabToXyz => (1.002), want 1 (z)
years later :) I just merged this PR that adds these: https://github.com/lucasb-eyer/go-colorful/pull/66