Skip to content

Instantly share code, notes, and snippets.

@JuniperPhoton
Created December 10, 2024 08:37
Show Gist options
  • Save JuniperPhoton/92a31c334a1d9cc820947ac79512c8d9 to your computer and use it in GitHub Desktop.
Save JuniperPhoton/92a31c334a1d9cc820947ac79512c8d9 to your computer and use it in GitHub Desktop.
Calculate the matrix for the linear RGB to CIE XYZ transformation.
/// Calculate the matrix for the linear RGB to CIE XYZ transformation.
///
/// Example code to calcualte the matrix for sRGB:
///
/// ```swift
/// let d65WhitePoint = [0.9505, 1.0, 1.0891]
///
/// matrix = calculateLinearRGBToCIEXYZMatrix(xr: 0.64, yr: 0.33,
/// xg: 0.30, yg: 0.60,
/// xb: 0.1558, yb: 0.06,
/// Xw: d65WhitePoint[0], Yw: d65WhitePoint[1], Zw: d65WhitePoint[2])
/// ```
///
/// - parameter Xw: X for the white point.
/// - parameter Yw: Y for the white point.
/// - parameter Zw: Z for the white point.
///
/// See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html for more information.
func calculateLinearRGBToCIEXYZMatrix(
xr: CGFloat, yr: CGFloat,
xg: CGFloat, yg: CGFloat,
xb: CGFloat, yb: CGFloat,
Xw: CGFloat, Yw: CGFloat, Zw: CGFloat
) -> [CGFloat] {
let Xr = xr / yr
let Yr = 1.0
let Zr = (1 - xr - yr) / yr
let Xg = xg / yg
let Yg = 1.0
let Zg = (1 - xg - yg) / yg
let Xb = xb / yb
let Yb = 1.0
let Zb = (1 - xb - yb) / yb
let mm = matrix_double3x3(rows: [
SIMD3<Double>(Xr, Xg, Xb),
SIMD3<Double>(Yr, Yg, Yb),
SIMD3<Double>(Zr, Zg, Zb)
])
let Srgb = matrix_multiply(mm.inverse, simd_double3(Xw, Yw, Zw))
let Sr = Srgb.x
let Sg = Srgb.y
let Sb = Srgb.z
return [
Sr * Xr, Sg * Xg, Sb * Xb,
Sr * Yr, Sg * Yg, Sb * Yb,
Sr * Zr, Sg * Zg, Sb * Zb
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment