1/* Color utilities
2 *
3 * Copyright (C) 1999 The Free Software Foundation
4 *
5 * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
6 * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
7 * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GTK+ Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 */
29
30#include "config.h"
31
32#include <math.h>
33#include <string.h>
34
35#include "gtkcolorutils.h"
36
37/* Converts from RGB to HSV */
38static void
39rgb_to_hsv (float *r,
40 float *g,
41 float *b)
42{
43 float red, green, blue;
44 float h, s, v;
45 float min, max;
46 float delta;
47
48 red = *r;
49 green = *g;
50 blue = *b;
51
52 h = 0.0;
53
54 if (red > green)
55 {
56 if (red > blue)
57 max = red;
58 else
59 max = blue;
60
61 if (green < blue)
62 min = green;
63 else
64 min = blue;
65 }
66 else
67 {
68 if (green > blue)
69 max = green;
70 else
71 max = blue;
72
73 if (red < blue)
74 min = red;
75 else
76 min = blue;
77 }
78
79 v = max;
80
81 if (max != 0.0)
82 s = (max - min) / max;
83 else
84 s = 0.0;
85
86 if (s == 0.0)
87 h = 0.0;
88 else
89 {
90 delta = max - min;
91
92 if (red == max)
93 h = (green - blue) / delta;
94 else if (green == max)
95 h = 2 + (blue - red) / delta;
96 else if (blue == max)
97 h = 4 + (red - green) / delta;
98
99 h /= 6.0;
100
101 if (h < 0.0)
102 h += 1.0;
103 else if (h > 1.0)
104 h -= 1.0;
105 }
106
107 *r = h;
108 *g = s;
109 *b = v;
110}
111
112/**
113 * gtk_hsv_to_rgb:
114 * @h: Hue
115 * @s: Saturation
116 * @v: Value
117 * @r: (out): Return value for the red component
118 * @g: (out): Return value for the green component
119 * @b: (out): Return value for the blue component
120 *
121 * Converts a color from HSV space to RGB.
122 *
123 * Input values must be in the [0.0, 1.0] range;
124 * output values will be in the same range.
125 */
126void
127gtk_hsv_to_rgb (float h, float s, float v,
128 float *r, float *g, float *b)
129{
130 float hue;
131 float f, p;
132 int ihue;
133
134 g_return_if_fail (h >= 0.0 && h <= 1.0);
135 g_return_if_fail (s >= 0.0 && s <= 1.0);
136 g_return_if_fail (v >= 0.0 && v <= 1.0);
137 g_return_if_fail (r);
138 g_return_if_fail (g);
139 g_return_if_fail (b);
140
141 if (s == 0.0)
142 {
143 *r = v;
144 *g = v;
145 *b = v;
146 return;
147 }
148
149 hue = h * 6.0;
150
151 if (hue == 6.0)
152 hue = 0.0;
153
154 ihue = (int)hue;
155 f = hue - ihue;
156 p = v * (1.0 - s);
157
158 if (ihue == 0)
159 {
160 *r = v;
161 *g = v * (1.0 - s * (1.0 - f));
162 *b = p;
163 }
164 else if (ihue == 1)
165 {
166 *r = v * (1.0 - s * f);
167 *g = v;
168 *b = p;
169 }
170 else if (ihue == 2)
171 {
172 *r = p;
173 *g = v;
174 *b = v * (1.0 - s * (1.0 - f));
175 }
176 else if (ihue == 3)
177 {
178 *r = p;
179 *g = v * (1.0 - s * f);
180 *b = v;
181 }
182 else if (ihue == 4)
183 {
184 *r = v * (1.0 - s * (1.0 - f));
185 *g = p;
186 *b = v;
187 }
188 else if (ihue == 5)
189 {
190 *r = v;
191 *g = p;
192 *b = v * (1.0 - s * f);
193 }
194}
195
196/**
197 * gtk_rgb_to_hsv:
198 * @r: Red
199 * @g: Green
200 * @b: Blue
201 * @h: (out): Return value for the hue component
202 * @s: (out): Return value for the saturation component
203 * @v: (out): Return value for the value component
204 *
205 * Converts a color from RGB space to HSV.
206 *
207 * Input values must be in the [0.0, 1.0] range;
208 * output values will be in the same range.
209 */
210void
211gtk_rgb_to_hsv (float r, float g, float b,
212 float *h, float *s, float *v)
213{
214 g_return_if_fail (r >= 0.0 && r <= 1.0);
215 g_return_if_fail (g >= 0.0 && g <= 1.0);
216 g_return_if_fail (b >= 0.0 && b <= 1.0);
217
218 rgb_to_hsv (r: &r, g: &g, b: &b);
219
220 if (h)
221 *h = r;
222
223 if (s)
224 *s = g;
225
226 if (v)
227 *v = b;
228}
229

source code of gtk/gtk/gtkcolorutils.c