GRASS 8 Programmer's Manual 8.5.0(2026)-8d6ceba290
Loading...
Searching...
No Matches
color_str.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/color_str.c
3
4 \brief GIS library - color management, named color to RGB triplet
5
6 (C) 2001-2016 by the GRASS Development Team
7
8 This program is free software under the
9 GNU General Public License (>=v2).
10 Read the file COPYING that comes with GRASS
11 for details.
12
13 \author Original author CERL
14 */
15
16#include <math.h>
17#include <string.h>
18
19#include <grass/gis.h>
20#include <grass/glocale.h>
21#include <grass/colors.h>
22
23/* The order in this table is important! It will be indexed by color number */
24static const struct color_rgb standard_colors_rgb[] = {
25 {0, 0, 0}, /* This is a dummy value to make lookup easier */
26 {0, 0, 0}, /* BLACK */
27 {255, 0, 0}, /* RED */
28 {0, 255, 0}, /* GREEN */
29 {0, 0, 255}, /* BLUE */
30 {255, 255, 0}, /* YELLOW */
31 {0, 255, 255}, /* CYAN */
32 {255, 0, 255}, /* MAGENTA */
33 {255, 255, 255}, /* WHITE */
34 {128, 128, 128}, /* GRAY */
35 {255, 128, 0}, /* ORANGE */
36 {100, 128, 255}, /* AQUA */
37 {0, 128, 255}, /* INDIGO */
38 {128, 0, 255}, /* VIOLET */
39 {180, 77, 25} /* BROWN */
40};
41
42/* The order in this table has no meaning. */
43static const struct color_name standard_color_names[] = {
44 {"black", BLACK}, {"red", RED}, {"green", GREEN},
45 {"blue", BLUE}, {"yellow", YELLOW}, {"cyan", CYAN},
46 {"magenta", MAGENTA}, {"white", WHITE}, {"grey", GREY},
47 {"gray", GRAY}, {"orange", ORANGE}, {"aqua", AQUA},
48 {"indigo", INDIGO}, {"violet", VIOLET}, {"purple", PURPLE},
49 {"brown", BROWN}};
50
51/*!
52 \brief Get number of named colors (RGB triplets)
53
54 \return number of colors
55 */
57{
58 return sizeof(standard_colors_rgb) / sizeof(standard_colors_rgb[0]);
59}
60
61/*!
62 \brief Get RGB triplet of given color
63
64 \param n color index
65 */
66struct color_rgb G_standard_color_rgb(int n)
67{
68 return standard_colors_rgb[n];
69}
70
71/*!
72 \brief Get number of named colors (color names)
73
74 \return number of colors
75 */
77{
78 return sizeof(standard_color_names) / sizeof(standard_color_names[0]);
79}
80
81/*!
82 \brief Get color name
83
84 \param n color index
85 */
86const struct color_name *G_standard_color_name(int n)
87{
88 return &standard_color_names[n];
89}
90
91/*!
92 \brief Parse color string and set red,green,blue
93
94 \param str color string
95 \param[out] red red value
96 \param[out] grn green value
97 \param[out] blu blue value
98
99 \return 1 OK
100 \return 2 NONE
101 \return 0 on error
102 */
103int G_str_to_color(const char *str, int *red, int *grn, int *blu)
104{
105 char buf[100];
106 int num_names = G_num_standard_color_names();
107 int i;
108
109 G_strlcpy(buf, str, sizeof(buf));
110 G_chop(buf);
111
112 G_debug(3, "G_str_to_color(): str = '%s'", buf);
113
114 if (G_strcasecmp(buf, "NONE") == 0)
115 return 2;
116
117 if (sscanf(buf, "%d%*[,:; ]%d%*[,:; ]%d", red, grn, blu) == 3) {
118 if (*red < 0 || *red > 255 || *grn < 0 || *grn > 255 || *blu < 0 ||
119 *blu > 255)
120 return 0;
121
122 return 1;
123 }
124
125 unsigned int hex;
126
127 if (sscanf(buf, "#%x", &hex) == 1) {
128 *red = (hex >> 16) & 0xFF;
129 *grn = (hex >> 8) & 0xFF;
130 *blu = hex & 0xFF;
131 if (*red < 0 || *red > 255 || *grn < 0 || *grn > 255 || *blu < 0 ||
132 *blu > 255)
133 return 0;
134
135 return 1;
136 }
137
138 /* Look for this color in the standard (preallocated) colors */
139 for (i = 0; i < num_names; i++) {
140 const struct color_name *name = &standard_color_names[i];
141
142 if (G_strcasecmp(buf, name->name) == 0) {
143 struct color_rgb rgb = standard_colors_rgb[name->number];
144
145 *red = (int)rgb.r;
146 *grn = (int)rgb.g;
147 *blu = (int)rgb.b;
148
149 return 1;
150 }
151 }
152
153 return 0;
154}
155
156/*!
157 \brief Converts RGB color values to HSV format.
158
159 \note This implementation is experimental and may be subject to change.
160
161 \param r red component of the RGB color
162 \param g green component of the RGB color
163 \param b blue component of the RGB color
164 \param[out] h pointer to store the calculated hue
165 \param[out] s pointer to store the calculated saturation
166 \param[out] v pointer to store the calculated value
167
168 \since version 8.5
169 */
170void G_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
171{
172 float r_norm = (float)r / 255.0f;
173 float g_norm = (float)g / 255.0f;
174 float b_norm = (float)b / 255.0f;
175
176 float cmax = MAX(r_norm, MAX(g_norm, b_norm));
177 float cmin = MIN(r_norm, MIN(g_norm, b_norm));
178 float diff = cmax - cmin;
179
180 if (cmax == cmin) {
181 *h = 0;
182 }
183 else if (cmax == r_norm) {
184 *h = fmodf((60.0f * ((g_norm - b_norm) / diff) + 360.0f), 360.0f);
185 }
186 else if (cmax == g_norm) {
187 *h = fmodf((60.0f * ((b_norm - r_norm) / diff) + 120.0f), 360.0f);
188 }
189 else {
190 *h = fmodf((60.0f * ((r_norm - g_norm) / diff) + 240.0f), 360.0f);
191 }
192
193 if (cmax == 0) {
194 *s = 0;
195 }
196 else {
197 *s = (diff / cmax) * 100.0f;
198 }
199
200 *v = cmax * 100.0f;
201}
202
203/*!
204 \brief Parse red,green,blue and set color string
205
206 \param r red component of RGB color
207 \param g green component of RGB color
208 \param b blue component of RGB color
209 \param clr_frmt color format to be used (RGB, HEX, HSV, TRIPLET).
210 \param[out] str color string
211
212 \since version 8.5
213 */
214void G_color_to_str(int r, int g, int b, ColorFormat clr_frmt, char *str)
215{
216 float h, s, v;
217
218 switch (clr_frmt) {
219 case RGB:
220 snprintf(str, COLOR_STRING_LENGTH, "rgb(%d, %d, %d)", r, g, b);
221 break;
222
223 case HEX:
224 snprintf(str, COLOR_STRING_LENGTH, "#%02X%02X%02X", r, g, b);
225 break;
226
227 case HSV:
228 G_rgb_to_hsv(r, g, b, &h, &s, &v);
229 snprintf(str, COLOR_STRING_LENGTH, "hsv(%d, %d, %d)", (int)h, (int)s,
230 (int)v);
231 break;
232
233 case TRIPLET:
234 snprintf(str, COLOR_STRING_LENGTH, "%d:%d:%d", r, g, b);
235 break;
236 }
237}
238
239/*!
240 \brief Get color format from the option.
241
242 \code
243 ColorFormat colorFormat;
244 struct Option *color_format;
245
246 color_format = G_define_standard_option(G_OPT_C_FORMAT);
247
248 if (G_parser(argc, argv))
249 exit(EXIT_FAILURE);
250
251 colorFormat = G_option_to_color_format(color_format);
252 \endcode
253
254 \param option pointer to color format option
255
256 \return allocated ColorFormat
257
258 \since version 8.5
259 */
260ColorFormat G_option_to_color_format(const struct Option *option)
261{
262 if (strcmp(option->answer, "rgb") == 0) {
263 return RGB;
264 }
265 if (strcmp(option->answer, "triplet") == 0) {
266 return TRIPLET;
267 }
268 if (strcmp(option->answer, "hsv") == 0) {
269 return HSV;
270 }
271 if (strcmp(option->answer, "hex") == 0) {
272 return HEX;
273 }
274
275 G_fatal_error(_("Unknown color format '%s'"), option->answer);
276}
ColorFormat G_option_to_color_format(const struct Option *option)
Get color format from the option.
Definition color_str.c:260
void G_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
Converts RGB color values to HSV format.
Definition color_str.c:170
int G_num_standard_colors(void)
Get number of named colors (RGB triplets).
Definition color_str.c:56
void G_color_to_str(int r, int g, int b, ColorFormat clr_frmt, char *str)
Parse red,green,blue and set color string.
Definition color_str.c:214
int G_str_to_color(const char *str, int *red, int *grn, int *blu)
Parse color string and set red,green,blue.
Definition color_str.c:103
int G_num_standard_color_names(void)
Get number of named colors (color names).
Definition color_str.c:76
struct color_rgb G_standard_color_rgb(int n)
Get RGB triplet of given color.
Definition color_str.c:66
const struct color_name * G_standard_color_name(int n)
Get color name.
Definition color_str.c:86
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
double b
double r
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition gis/error.c:159
float g
Definition named_colr.c:7
const char * name
Definition named_colr.c:6
#define MAX(a, b)
Definition parson.c:91
#define MIN(a, b)
Definition shpopen.c:33
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition strings.c:332
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower).
Definition strings.c:47
size_t G_strlcpy(char *dst, const char *src, size_t dsize)
Safe string copy function.
Definition strlcpy.c:54