GRASS 8 Programmer's Manual 8.6.0dev(2026)-56a9afeb9f
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 */
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 */
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];
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 */
168void G_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
169{
170 float r_norm = (float)r / 255.0f;
171 float g_norm = (float)g / 255.0f;
172 float b_norm = (float)b / 255.0f;
173
174 float cmax = MAX(r_norm, MAX(g_norm, b_norm));
175 float cmin = MIN(r_norm, MIN(g_norm, b_norm));
176 float diff = cmax - cmin;
177
178 if (cmax == cmin) {
179 *h = 0;
180 }
181 else if (cmax == r_norm) {
182 *h = fmodf((60.0f * ((g_norm - b_norm) / diff) + 360.0f), 360.0f);
183 }
184 else if (cmax == g_norm) {
185 *h = fmodf((60.0f * ((b_norm - r_norm) / diff) + 120.0f), 360.0f);
186 }
187 else {
188 *h = fmodf((60.0f * ((r_norm - g_norm) / diff) + 240.0f), 360.0f);
189 }
190
191 if (cmax == 0) {
192 *s = 0;
193 }
194 else {
195 *s = (diff / cmax) * 100.0f;
196 }
197
198 *v = cmax * 100.0f;
199}
200
201/*!
202 \brief Parse red,green,blue and set color string
203
204 \param r red component of RGB color
205 \param g green component of RGB color
206 \param b blue component of RGB color
207 \param clr_frmt color format to be used (RGB, HEX, HSV, TRIPLET).
208 \param[out] str color string
209 */
210void G_color_to_str(int r, int g, int b, ColorFormat clr_frmt, char *str)
211{
212 float h, s, v;
213
214 switch (clr_frmt) {
215 case RGB:
216 snprintf(str, COLOR_STRING_LENGTH, "rgb(%d, %d, %d)", r, g, b);
217 break;
218
219 case HEX:
220 snprintf(str, COLOR_STRING_LENGTH, "#%02X%02X%02X", r, g, b);
221 break;
222
223 case HSV:
224 G_rgb_to_hsv(r, g, b, &h, &s, &v);
225 snprintf(str, COLOR_STRING_LENGTH, "hsv(%d, %d, %d)", (int)h, (int)s,
226 (int)v);
227 break;
228
229 case TRIPLET:
230 snprintf(str, COLOR_STRING_LENGTH, "%d:%d:%d", r, g, b);
231 break;
232 }
233}
234
235/*!
236 \brief Get color format from the option.
237
238 \code
239 ColorFormat colorFormat;
240 struct Option *color_format;
241
242 color_format = G_define_standard_option(G_OPT_C_FORMAT);
243
244 if (G_parser(argc, argv))
245 exit(EXIT_FAILURE);
246
247 colorFormat = G_option_to_color_format(color_format);
248 \endcode
249
250 \param option pointer to color format option
251
252 \return allocated ColorFormat
253 */
255{
256 if (strcmp(option->answer, "rgb") == 0) {
257 return RGB;
258 }
259 if (strcmp(option->answer, "triplet") == 0) {
260 return TRIPLET;
261 }
262 if (strcmp(option->answer, "hsv") == 0) {
263 return HSV;
264 }
265 if (strcmp(option->answer, "hex") == 0) {
266 return HEX;
267 }
268
269 G_fatal_error(_("Unknown color format '%s'"), option->answer);
270}
AMI_err name(char **stream_name)
Definition ami_stream.h:426
ColorFormat G_option_to_color_format(const struct Option *option)
Get color format from the option.
Definition color_str.c:254
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:168
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:210
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
#define AQUA
Definition colors.h:20
ColorFormat
Color format identifiers (enum)
Definition colors.h:55
@ HSV
Definition colors.h:55
@ RGB
Definition colors.h:55
@ TRIPLET
Definition colors.h:55
@ HEX
Definition colors.h:55
#define PURPLE
Definition colors.h:26
#define INDIGO
Definition colors.h:21
#define MAGENTA
Definition colors.h:16
#define BLUE
Definition colors.h:13
#define BLACK
Definition colors.h:10
#define WHITE
Definition colors.h:17
#define RED
Definition colors.h:11
#define VIOLET
Definition colors.h:22
#define BROWN
Definition colors.h:23
#define COLOR_STRING_LENGTH
Definition colors.h:28
#define YELLOW
Definition colors.h:14
#define ORANGE
Definition colors.h:19
#define GREEN
Definition colors.h:12
#define CYAN
Definition colors.h:15
#define GREY
Definition colors.h:25
#define GRAY
Definition colors.h:18
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition strings.c:47
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition strings.c:332
int G_debug(int, const char *,...) __attribute__((format(printf
size_t G_strlcpy(char *, const char *, size_t)
Safe string copy function.
Definition strlcpy.c:52
#define MIN(a, b)
Definition gis.h:153
#define MAX(a, b)
Definition gis.h:148
#define _(str)
Definition glocale.h:10
float g
Definition named_colr.c:7
const char * name
Definition named_colr.c:6
double b
Definition r_raster.c:39
double r
Definition r_raster.c:39
Structure that stores option information.
Definition gis.h:563