Skip to content

Instantly share code, notes, and snippets.

@douglashill
Created May 7, 2016 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save douglashill/0bcc696065cf169172c8208ef76ad4d0 to your computer and use it in GitHub Desktop.
Save douglashill/0bcc696065cf169172c8208ef76ad4d0 to your computer and use it in GitHub Desktop.
Transform between RGB and XYZ colours with come calculations I found on the web
#include <CoreGraphics/CoreGraphics.h>
static inline CGFloat gammaCorrect(CGFloat component) {
if (component > 0.04045f) {
return pow((component + 0.055f) / 1.055f, 2.4f);
}
return component / 12.92f;
}
static inline CGFloat reverseGammaCorrect(CGFloat component) {
if (component > 0.0031308) {
return 1.055f * pow(component, 1 / 2.4f) - 0.055f;
}
return component * 12.92f;
}
static void RGBToXYZ(CGFloat red, CGFloat green, CGFloat blue, CGFloat *X, CGFloat *Y, CGFloat *Z) {
// http://www.easyrgb.com/index.php?X=MATH&H=02#text2
CGFloat correctedRed = gammaCorrect(red);
CGFloat correctedGreen = gammaCorrect(green);
CGFloat correctedBlue = gammaCorrect(blue);
// Observer = 2°, Illuminant = D65
if (X) *X = correctedRed * 0.4124f + correctedGreen * 0.3576f + correctedBlue * 0.1805f;
if (Y) *Y = correctedRed * 0.2126f + correctedGreen * 0.7152f + correctedBlue * 0.0722f;
if (Z) *Z = correctedRed * 0.0193f + correctedGreen * 0.1192f + correctedBlue * 0.9505f;
}
static void XYZToRGB(CGFloat X, CGFloat Y, CGFloat Z, CGFloat *red, CGFloat *green, CGFloat *blue) {
// http://www.easyrgb.com/index.php?X=MATH&H=01#text1
// Observer = 2°, Illuminant = D65
CGFloat correctedRed = X * 3.2406f + Y * -1.5372f + Z * -0.4986f;
CGFloat correctedGreen = X * -0.9689f + Y * 1.8758f + Z * 0.0415f;
CGFloat correctedBlue = X * 0.0557f + Y * -0.2040f + Z * 1.0570f;
if (red) *red = reverseGammaCorrect(correctedRed);
if (green) *green = reverseGammaCorrect(correctedGreen);
if (blue) *blue = reverseGammaCorrect(correctedBlue);
}
int main(int argc, char *argv[]) {
CGFloat X, Y, Z;
RGBToXYZ(1, 0.5, 0.1, &X, &Y, &Z);
CGFloat red, green, blue;
XYZToRGB(X, Y, Z, &red, &green, &blue);
printf("RGB(%g, %g, %g)\n", red, green, blue);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment