# source:trunk/src/lol/image/color.h@2189Tweet

Last change on this file since 2189 was 2189, checked in by sam, 9 years ago

color: conversions from CIE XYZ to CIE L*a*b*.

File size: 3.2 KB
Line
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
8//   http://www.wtfpl.net/ for more details.
9//
10
11//
12// The Color class
13// ---------------
14// Provides various color conversion routines.
15//
16
17#if !defined __LOL_IMAGE_COLOR_H__
18#define __LOL_IMAGE_COLOR_H__
19
20#include <lol/math/vector.h>
21
22namespace lol
23{
24
25class Color
26{
27public:
28    /*
29     * Convert linear RGB to sRGB
30     */
31    static vec3 LinearRGBTosRGB(vec3 c)
32    {
33        vec3 ret = 12.92f * c;
34        if (c.r > 0.0031308f)
35            ret.r = 1.055f * pow(c.r, 1.0f / 2.4f) - 0.055f;
36        if (c.g > 0.0031308f)
37            ret.g = 1.055f * pow(c.g, 1.0f / 2.4f) - 0.055f;
38        if (c.b > 0.0031308f)
39            ret.b = 1.055f * pow(c.b, 1.0f / 2.4f) - 0.055f;
40        return ret;
41    }
42
43    static vec4 LinearRGBTosRGB(vec4 c)
44    {
45        return vec4(LinearRGBTosRGB(c.rgb), c.a);
46    }
47
48    /*
49     * Convert sRGB to linear RGB
50     */
51    static vec3 sRGBToLinearRGB(vec3 c)
52    {
53        vec3 ret = 1.0f / 12.92f * c;
54        if (c.r > 0.04045f)
55            ret.r = pow(c.r + 0.055f, 2.4f) / pow(1.055f, 2.4f);
56        if (c.g > 0.04045f)
57            ret.g = pow(c.g + 0.055f, 2.4f) / pow(1.055f, 2.4f);
58        if (c.b > 0.04045f)
59            ret.b = pow(c.b + 0.055f, 2.4f) / pow(1.055f, 2.4f);
60        return ret;
61    }
62
63    static vec4 sRGBToLinearRGB(vec4 c)
64    {
65        return vec4(sRGBToLinearRGB(c.rgb), c.a);
66    }
67
68    /*
69     * Convert linear RGB to CIE XYZ
70     */
71    static vec3 LinearRGBToCIEXYZ(vec3 c)
72    {
73        mat3 m(vec3(3.2406f, -0.9689f, 0.0557f),
74               vec3(-1.5372f, 1.8758f, -0.2040f),
75               vec3(-0.4986f, 0.0415f, 1.0570f));
76        return m * c;
77    }
78
79    static vec4 LinearRGBToCIEXYZ(vec4 c)
80    {
81        return vec4(LinearRGBToCIEXYZ(c.rgb), c.a);
82    }
83
84    /*
85     * Convert CIE XYZ to linear RGB
86     */
87    static vec3 CIEXYZToLinearRGB(vec3 c)
88    {
89        mat3 m(vec3(0.4124f, 0.2126f, 0.0193f),
90               vec3(0.3576f, 0.7152f, 0.1192f),
91               vec3(0.1805f, 0.0722f, 0.9505f));
92        return m * c;
93    }
94
95    static vec4 CIEXYZToLinearRGB(vec4 c)
96    {
97        return vec4(CIEXYZToLinearRGB(c.rgb), c.a);
98    }
99
100    /*
101     * Convert CIE XYZ to CIE L*a*b*
102     */
103    static vec3 CIEXYZToCIELab(vec3 col)
104    {
105        using std::pow;
106
107        float const a = 8.85645167903563081e-3; /* (6/29)^3 */
108        float const b = 7.78703703703703703;    /* 1/3 (29/6)^2 */
109        float const c = 1.37931034482758620e-1; /* 4/29 */
110
111        vec3 f = b * col + vec3(c);
112        if (col.x > a)
113            f.x = pow(col.x, 1.0 / 3.0);
114        if (col.y > a)
115            f.y = pow(col.y, 1.0 / 3.0);
116        if (col.z > a)
117            f.z = pow(col.z, 1.0 / 3.0);
118
119        return vec3(116.0 * f.y - 16.0,
120                    500.0 * (f.x - f.y),
121                    200.0 * (f.y - f.z));
122    }
123
124    static vec4 CIEXYZToCIELab(vec4 c)
125    {
126        return vec4(CIEXYZToLinearRGB(c.rgb), c.a);
127    }
128};
129
130} /* namespace lol */
131
132#endif // __LOL_IMAGE_COLOR_H__
133
Note: See TracBrowser for help on using the repository browser.