Changeset 2193
 Timestamp:
 Jan 2, 2013, 1:54:08 PM (10 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

trunk/src/lol/image/color.h
r2189 r2193 29 29 * Convert linear RGB to sRGB 30 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;31 static vec3 LinearRGBTosRGB(vec3 src) 32 { 33 vec3 ret = 12.92f * src; 34 if (src.r > 0.0031308f) 35 ret.r = 1.055f * pow(src.r, 1.0f / 2.4f)  0.055f; 36 if (src.g > 0.0031308f) 37 ret.g = 1.055f * pow(src.g, 1.0f / 2.4f)  0.055f; 38 if (src.b > 0.0031308f) 39 ret.b = 1.055f * pow(src.b, 1.0f / 2.4f)  0.055f; 40 40 return ret; 41 41 } 42 42 43 static vec4 LinearRGBTosRGB(vec4 c)44 { 45 return vec4(LinearRGBTosRGB( c.rgb),c.a);43 static vec4 LinearRGBTosRGB(vec4 src) 44 { 45 return vec4(LinearRGBTosRGB(src.rgb), src.a); 46 46 } 47 47 … … 49 49 * Convert sRGB to linear RGB 50 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);51 static vec3 sRGBToLinearRGB(vec3 src) 52 { 53 vec3 ret = 1.0f / 12.92f * src; 54 if (src.r > 0.04045f) 55 ret.r = pow(src.r + 0.055f, 2.4f) / pow(1.055f, 2.4f); 56 if (src.g > 0.04045f) 57 ret.g = pow(src.g + 0.055f, 2.4f) / pow(1.055f, 2.4f); 58 if (src.b > 0.04045f) 59 ret.b = pow(src.b + 0.055f, 2.4f) / pow(1.055f, 2.4f); 60 60 return ret; 61 61 } 62 62 63 static vec4 sRGBToLinearRGB(vec4 c) 64 { 65 return vec4(sRGBToLinearRGB(c.rgb), c.a); 63 static vec4 sRGBToLinearRGB(vec4 src) 64 { 65 return vec4(sRGBToLinearRGB(src.rgb), src.a); 66 } 67 68 /* 69 * Convert linear HSV to linear RGB 70 */ 71 static vec3 HSVToLinearRGB(vec3 src) 72 { 73 vec3 tmp = abs(fract(vec3(src.x) + vec3(3.f, 2.f, 1.f) / 3.f) * 6.f  vec3(3.f)); 74 return mix(vec3(1.f), clamp(tmp  vec3(1.f), 0.f, 1.f), src.y) * src.z; 75 } 76 77 static vec4 HSVToLinearRGB(vec4 src) 78 { 79 return vec4(HSVToLinearRGB(src.rgb), src.a); 66 80 } 67 81 … … 69 83 * Convert linear RGB to CIE XYZ 70 84 */ 71 static vec3 LinearRGBToCIEXYZ(vec3 c)85 static vec3 LinearRGBToCIEXYZ(vec3 src) 72 86 { 73 87 mat3 m(vec3(3.2406f, 0.9689f, 0.0557f), 74 88 vec3(1.5372f, 1.8758f, 0.2040f), 75 89 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);90 return m * src; 91 } 92 93 static vec4 LinearRGBToCIEXYZ(vec4 src) 94 { 95 return vec4(LinearRGBToCIEXYZ(src.rgb), src.a); 82 96 } 83 97 … … 85 99 * Convert CIE XYZ to linear RGB 86 100 */ 87 static vec3 CIEXYZToLinearRGB(vec3 c)101 static vec3 CIEXYZToLinearRGB(vec3 src) 88 102 { 89 103 mat3 m(vec3(0.4124f, 0.2126f, 0.0193f), 90 104 vec3(0.3576f, 0.7152f, 0.1192f), 91 105 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);106 return m * src; 107 } 108 109 static vec4 CIEXYZToLinearRGB(vec4 src) 110 { 111 return vec4(CIEXYZToLinearRGB(src.rgb), src.a); 98 112 } 99 113 100 114 /* 101 115 * 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.85645167903563081e3; /* (6/29)^3 */ 108 float const b = 7.78703703703703703; /* 1/3 (29/6)^2 */ 109 float const c = 1.37931034482758620e1; /* 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); 116 * Note: XYZ values should be normalised, ie. divided by the 117 * corresponding components for white. 118 */ 119 static vec3 CIEXYZToCIELab(vec3 src) 120 { 121 float const a = (6.0 * 6.0 * 6.0) / (29 * 29 * 29); 122 float const b = (29.0 * 29.0) / (3 * 6 * 6); 123 float const c = 4.0 / 29; 124 float const d = 1.0 / 3; 125 126 vec3 f = b * src + vec3(c); 127 if (src.x > a) 128 f.x = pow(src.x, d); 129 if (src.y > a) 130 f.y = pow(src.y, d); 131 if (src.z > a) 132 f.z = pow(src.z, d); 133 134 return vec3(116.f * f.y  16.f, 135 500.f * (f.x  f.y), 136 200.f * (f.y  f.z)); 137 } 138 139 static vec4 CIEXYZToCIELab(vec4 src) 140 { 141 return vec4(CIEXYZToLinearRGB(src.rgb), src.a); 142 } 143 144 /* 145 * Return distance using the CIEDE2000 metric, 146 * input should be in CIE L*a*b*. 147 */ 148 static float DistanceCIEDE2000(vec3 lab1, vec3 lab2) 149 { 150 float const deg2rad = 6.28318530718f / 360.f; 151 float const rad2deg = 360.f / 6.28318530718f; 152 153 float C1 = length(lab1.yz); 154 float C2 = length(lab2.yz); 155 float C_ = 0.5f * (C1 + C2); 156 157 float L1 = lab1.x; 158 float L2 = lab2.x; 159 float dLp = L2  L1; 160 float L_ = 0.5f * (L1 + L2); 161 162 float tmp1 = pow(C_, 7.f); 163 float tmp2 = 1.5f  0.5f * sqrt(tmp1 / (tmp1 + pow(25.f, 7.f))); 164 float ap1 = lab1.y * tmp2; 165 float ap2 = lab2.y * tmp2; 166 float Cp1 = sqrt(ap1 * ap1 + lab1.z * lab1.z); 167 float Cp2 = sqrt(ap2 * ap2 + lab2.z * lab2.z); 168 float dCp = Cp2  Cp1; 169 float Cp_ = 0.5f * (Cp1 + Cp2); 170 171 float hp1 = fmod(atan2(lab1.z, ap1) * rad2deg, 360.f); 172 if (hp1 < 0.f) 173 hp1 += 360.f; 174 float hp2 = fmod(atan2(lab2.z, ap2) * rad2deg, 360.f); 175 if (hp2 < 0.f) 176 hp2 += 360.f; 177 float dhp; 178 if (abs(hp1  hp2) <= 180.f) 179 dhp = hp2  hp1; 180 else if (hp2 <= hp1) 181 dhp = hp2  hp1 + 360.f; 182 else 183 dhp = hp2  hp1  360.f; 184 float dHp = 2.f * sqrt(Cp1 * Cp2) * sin(dhp / 2.f * deg2rad); 185 float Hp_; 186 if (abs(hp1  hp2) > 180.f) 187 Hp_ = 0.5f * (hp1 + hp2 + 360.f); 188 else 189 Hp_ = 0.5f * (hp1 + hp2); 190 191 float T = 1.f  0.17f * cos((Hp_  30.f) * deg2rad) 192 + 0.24f * cos(2 * Hp_ * deg2rad) 193 + 0.32f * cos((3.f * Hp_ + 6.f) * deg2rad) 194  0.20f * cos((4.f * Hp_  63.f) * deg2rad); 195 float SL = 1.f + 0.015f * (L_  50) * (L_  50) 196 / sqrt(20.f + (L_  50) * (L_  50)); 197 float SC = 1.f + 0.045f * Cp_; 198 float SH = 1.f + 0.015f * Cp_ * T; 199 float RT = 2.f * sqrt(pow(Cp_, 7.f) / (pow(Cp_, 7.f) + pow(25.f, 7.f))) 200 * sin(60.f * deg2rad * exp(pow((Hp_  275.f) / 25.f, 2.f))); 201 202 dLp /= SL; 203 dCp /= SC; 204 dHp /= SH; 205 206 return sqrt(dLp * dLp + dCp * dCp + dHp * dHp + RT * dCp * dHp); 127 207 } 128 208 };
Note: See TracChangeset
for help on using the changeset viewer.