From 10d5d30b85b9bcc515b4fa58223fd7ff8e8a20cd Mon Sep 17 00:00:00 2001
From: Sam Hocevar <sam@hocevar.net>
Date: Mon, 31 Dec 2012 04:26:43 +0000
Subject: [PATCH] image: a few colour conversion routines.

---
 src/Makefile.am             |   1 +
 src/core.h                  |   2 +
 src/lol/image/color.h       | 106 ++++++++++++++++++++++++++++++++++++
 src/lolcore.vcxproj         |   1 +
 src/lolcore.vcxproj.filters |   8 ++-
 5 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 src/lol/image/color.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 90368c68..998946e8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,6 +21,7 @@ liblol_a_SOURCES = \
     lol/base/map.h \
     lol/math/vector.h lol/math/half.h lol/math/real.h lol/math/remez.h \
     lol/math/math.h \
+    lol/image/color.h \
     \
     generated/location.hh generated/position.hh generated/stack.hh \
     \
diff --git a/src/core.h b/src/core.h
index 324add1e..6a3cad26 100644
--- a/src/core.h
+++ b/src/core.h
@@ -87,6 +87,8 @@ static inline int isnan(float f)
 #include <lol/math/real.h>
 #include <lol/math/vector.h>
 
+#include <lol/image/color.h>
+
 #include "numeric.h"
 #include "timer.h"
 #include "thread/thread.h"
diff --git a/src/lol/image/color.h b/src/lol/image/color.h
new file mode 100644
index 00000000..6407432a
--- /dev/null
+++ b/src/lol/image/color.h
@@ -0,0 +1,106 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
+//   This program is free software; you can redistribute it and/or
+//   modify it under the terms of the Do What The Fuck You Want To
+//   Public License, Version 2, as published by Sam Hocevar. See
+//   http://www.wtfpl.net/ for more details.
+//
+
+//
+// The Color class
+// ---------------
+// Provides various color conversion routines.
+//
+
+#if !defined __LOL_IMAGE_COLOR_H__
+#define __LOL_IMAGE_COLOR_H__
+
+#include <lol/math/vector.h>
+
+namespace lol
+{
+
+class Color
+{
+public:
+    /*
+     * Convert linear RGB to sRGB
+     */
+    static vec3 LinearRGBTosRGB(vec3 c)
+    {
+        using std::pow;
+        vec3 ret = 12.92 * c;
+        if (c.r > 0.0031308)
+            ret.r = 1.055 * pow(c.r, 1.0 / 2.4) - 0.055;
+        if (c.g > 0.0031308)
+            ret.g = 1.055 * pow(c.g, 1.0 / 2.4) - 0.055;
+        if (c.b > 0.0031308)
+            ret.b = 1.055 * pow(c.b, 1.0 / 2.4) - 0.055;
+        return ret;
+    }
+
+    static vec4 LinearRGBTosRGB(vec4 c)
+    {
+        return vec4(LinearRGBTosRGB(c.rgb), c.a);
+    }
+
+    /*
+     * Convert sRGB to linear RGB
+     */
+    static vec3 sRGBToLinearRGB(vec3 c)
+    {
+        using std::pow;
+        vec3 ret = 1.0 / 12.92 * c;
+        if (c.r > 0.04045)
+            ret.r = pow(c.r + 0.055, 2.4) / pow(1.055, 2.4);
+        if (c.g > 0.04045)
+            ret.g = pow(c.g + 0.055, 2.4) / pow(1.055, 2.4);
+        if (c.b > 0.04045)
+            ret.b = pow(c.b + 0.055, 2.4) / pow(1.055, 2.4);
+        return ret;
+    }
+
+    static vec4 sRGBToLinearRGB(vec4 c)
+    {
+        return vec4(sRGBToLinearRGB(c.rgb), c.a);
+    }
+
+    /*
+     * Convert linear RGB to CIE XYZ
+     */
+    static vec3 LinearRGBToCIEXYZ(vec3 c)
+    {
+        mat3 m(vec3(3.2406, -0.9689, 0.0557),
+               vec3(-1.5372, 1.8758, -0.2040),
+               vec3(-0.4986, 0.0415, 1.0570));
+        return m * c;
+    }
+
+    static vec4 LinearRGBToCIEXYZ(vec4 c)
+    {
+        return vec4(LinearRGBToCIEXYZ(c.rgb), c.a);
+    }
+
+    /*
+     * Convert CIE XYZ to linear RGB
+     */
+    static vec3 CIEXYZToLinearRGB(vec3 c)
+    {
+        mat3 m(vec3(0.4124, 0.2126, 0.0193),
+               vec3(0.3576, 0.7152, 0.1192),
+               vec3(0.1805, 0.0722, 0.9505));
+        return m * c;
+    }
+
+    static vec4 CIEXYZToLinearRGB(vec4 c)
+    {
+        return vec4(CIEXYZToLinearRGB(c.rgb), c.a);
+    }
+};
+
+} /* namespace lol */
+
+#endif // __LOL_IMAGE_COLOR_H__
+
diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj
index fc18c83d..97037bb6 100644
--- a/src/lolcore.vcxproj
+++ b/src/lolcore.vcxproj
@@ -588,6 +588,7 @@
     <ClInclude Include="lol\base\string.h" />
     <ClInclude Include="lol\base\types.h" />
     <ClInclude Include="lol\debug.h" />
+    <ClInclude Include="lol\image\color.h" />
     <ClInclude Include="lol\math\half.h" />
     <ClInclude Include="lol\math\math.h" />
     <ClInclude Include="lol\math\real.h" />
diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters
index c8fb7c69..50d9a170 100644
--- a/src/lolcore.vcxproj.filters
+++ b/src/lolcore.vcxproj.filters
@@ -23,6 +23,9 @@
     <Filter Include="src\lol">
       <UniqueIdentifier>{0edcf1a5-3c9c-4425-918c-aa2cbebc51c1}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\lol\image">
+      <UniqueIdentifier>{f25b3187-b24c-469a-b038-5a968eaa83f6}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\lol\math">
       <UniqueIdentifier>{1e0b7a4c-425f-4d4f-945e-ba2ac9386ce0}</UniqueIdentifier>
     </Filter>
@@ -669,6 +672,9 @@
     <ClInclude Include="platform\sdl\sdlapp.h">
       <Filter>src\platform\sdl</Filter>
     </ClInclude>
+    <ClInclude Include="lol\image\color.h">
+      <Filter>src\lol\image</Filter>
+    </ClInclude>
     <ClInclude Include="lol\math\half.h">
       <Filter>src\lol\math</Filter>
     </ClInclude>
@@ -1651,4 +1657,4 @@
       <Filter>src\gpu</Filter>
     </None>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>