naev 0.12.5
colour.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
9
11#include <math.h>
13
14#include "colour.h"
15
16#include "nmath.h"
17
18/*
19 * http://en.wikipedia.org/wiki/SRGB#The_forward_transformation_.28CIE_xyY_or_CIE_XYZ_to_sRGB.29
20 */
21__attribute__( ( const ) ) double linearToGamma( double x )
22{
23 if ( x <= 0.0031308 )
24 return x * 12.92;
25 return 1.055 * pow( x, 1.0 / 2.4 ) - 0.055;
26}
27/*
28 * http://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
29 */
30__attribute__( ( const ) ) double gammaToLinear( double x )
31{
32 if ( x <= 0.04045 )
33 return x / 12.92;
34 return pow( ( x + 0.055 ) / 1.055, 2.4 );
35}
36
37void col_linearToGamma( glColour *c )
38{
39 c->r = linearToGamma( c->r );
40 c->g = linearToGamma( c->g );
41 c->b = linearToGamma( c->b );
42}
43
44void col_gammaToLinear( glColour *c )
45{
46 c->r = gammaToLinear( c->r );
47 c->g = gammaToLinear( c->g );
48 c->b = gammaToLinear( c->b );
49}
50
61void col_hsv2rgb( glColour *c, float h, float s, float v )
62{
63 float var_h, var_i, var_1, var_2, var_3;
64
65 if ( v > 1 )
66 v = 1;
67
68 if ( s == 0 ) {
69 c->r = v;
70 c->g = v;
71 c->b = v;
72 } else {
73 var_h = h * 6 / 360.;
74 var_i = floor( var_h );
75 var_1 = v * ( 1 - s );
76 var_2 = v * ( 1 - s * ( var_h - var_i ) );
77 var_3 = v * ( 1 - s * ( 1 - ( var_h - var_i ) ) );
78
79 if ( var_i == 0 ) {
80 c->r = v;
81 c->g = var_3;
82 c->b = var_1;
83 } else if ( var_i == 1 ) {
84 c->r = var_2;
85 c->g = v;
86 c->b = var_1;
87 } else if ( var_i == 2 ) {
88 c->r = var_1;
89 c->g = v;
90 c->b = var_3;
91 } else if ( var_i == 3 ) {
92 c->r = var_1;
93 c->g = var_2;
94 c->b = v;
95 } else if ( var_i == 4 ) {
96 c->r = var_3;
97 c->g = var_1;
98 c->b = v;
99 } else {
100 c->r = v;
101 c->g = var_1;
102 c->b = var_2;
103 }
104 }
105
106 c->r = gammaToLinear( c->r );
107 c->g = gammaToLinear( c->g );
108 c->b = gammaToLinear( c->b );
109}
110
125void col_rgb2hsv( float *H, float *S, float *V, float R, float G, float B )
126{
127 float H1, S1, V1;
128#ifdef HSV_TRAVIS
129 float R1, G1, B1;
130#endif /* HSV_TRAVIS */
131 float max, min, diff;
132
133 R = gammaToLinear( R );
134 G = gammaToLinear( G );
135 B = gammaToLinear( B );
136
137 max = max3( R, G, B );
138 min = min3( R, G, B );
139 diff = max - min;
140
141 if ( max == 0 )
142 H1 = S1 = V1 = 0;
143 else {
144 V1 = max;
145 S1 = diff / max;
146 if ( S1 == 0 )
147 /* H1 is undefined, but give it a value anyway */
148 H1 = 0;
149 else {
150#ifdef HSV_TRAVIS
151 R1 = ( max - R ) / diff;
152 G1 = ( max - G ) / diff;
153 B1 = ( max - B ) / diff;
154
155 if ( ( R == max ) && ( G == min ) )
156 H1 = 5 + B1;
157 else {
158 if ( ( R == max ) && ( G != min ) )
159 H1 = 1 - G1;
160 else {
161 if ( ( G == max ) && ( B == min ) )
162 H1 = 1 + R1;
163 else {
164 if ( ( G == max ) && ( B != min ) )
165 H1 = 3 - B1;
166 else {
167 if ( R == max )
168 H1 = 3 + G1;
169 else
170 H1 = 5 - R1;
171 }
172 }
173 }
174 }
175
176 H1 *= 60; /* convert to range [0, 360] degrees */
177#else /* HSV_TRAVIS */
178 H1 = 0.; /* Shuts up Clang. */
179 /* assume Foley & VanDam HSV */
180 if ( R == max )
181 H1 = ( G - B ) / diff;
182 if ( G == max )
183 H1 = 2 + ( B - R ) / diff;
184 if ( B == max )
185 H1 = 4 + ( R - G ) / diff;
186
187 H1 *= 60; /* convert to range [0, 360] degrees */
188 if ( H1 < 0 )
189 H1 += 360;
190#endif /* HSV_TRAVIS */
191 }
192 }
193 *H = H1;
194 *S = S1;
195 *V = V1;
196}
197
206void col_blend( glColour *blend, const glColour *fg, const glColour *bg,
207 float alpha )
208{
209 blend->r = ( 1. - alpha ) * bg->r + alpha * fg->r;
210 blend->g = ( 1. - alpha ) * bg->g + alpha * fg->g;
211 blend->b = ( 1. - alpha ) * bg->b + alpha * fg->b;
212 blend->a = ( 1. - alpha ) * bg->a + alpha * fg->a;
213}
void col_blend(glColour *blend, const glColour *fg, const glColour *bg, float alpha)
Blends two colours.
Definition colour.c:206
void col_rgb2hsv(float *H, float *S, float *V, float R, float G, float B)
Changes colour space from RGB to HSV.
Definition colour.c:125
void col_hsv2rgb(glColour *c, float h, float s, float v)
Changes colour space from HSV to RGB.
Definition colour.c:61
double min3(double v1, double v2, double v3)
Returns the minimum of 3 values.
Definition nmath.c:56
double max3(double v1, double v2, double v3)
Returns the maximum of 3 values.
Definition nmath.c:46
static const double c[]
Definition rng.c:256