GRASS 8 Programmer's Manual 8.6.0dev(2026)-745b61fbf6
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 SPDX-FileCopyrightText: 2001-2016 GRASS Development Team
7 SPDX-License-Identifier: GPL-2.0-or-later
8
9 \author Original author CERL
10 */
11
12#include <math.h>
13#include <string.h>
14
15#include <grass/gis.h>
16#include <grass/glocale.h>
17#include <grass/colors.h>
18
19/* The order in this table is important! It will be indexed by color number */
20static const struct color_rgb standard_colors_rgb[] = {
21 {0, 0, 0}, /* This is a dummy value to make lookup easier */
22 {0, 0, 0}, /* BLACK */
23 {255, 0, 0}, /* RED */
24 {0, 255, 0}, /* GREEN */
25 {0, 0, 255}, /* BLUE */
26 {255, 255, 0}, /* YELLOW */
27 {0, 255, 255}, /* CYAN */
28 {255, 0, 255}, /* MAGENTA */
29 {255, 255, 255}, /* WHITE */
30 {128, 128, 128}, /* GRAY */
31 {255, 128, 0}, /* ORANGE */
32 {100, 128, 255}, /* AQUA */
33 {0, 128, 255}, /* INDIGO */
34 {128, 0, 255}, /* VIOLET */
35 {180, 77, 25} /* BROWN */
36};
37
38/* The order in this table has no meaning. */
39static const struct color_name standard_color_names[] = {
40 {"black", BLACK}, {"red", RED}, {"green", GREEN},
41 {"blue", BLUE}, {"yellow", YELLOW}, {"cyan", CYAN},
42 {"magenta", MAGENTA}, {"white", WHITE}, {"grey", GREY},
43 {"gray", GRAY}, {"orange", ORANGE}, {"aqua", AQUA},
44 {"indigo", INDIGO}, {"violet", VIOLET}, {"purple", PURPLE},
45 {"brown", BROWN}};
46
47/*!
48 \brief Get number of named colors (RGB triplets)
49
50 \return number of colors
51 */
53{
54 return sizeof(standard_colors_rgb) / sizeof(standard_colors_rgb[0]);
55}
56
57/*!
58 \brief Get RGB triplet of given color
59
60 \param n color index
61 */
63{
64 return standard_colors_rgb[n];
65}
66
67/*!
68 \brief Get number of named colors (color names)
69
70 \return number of colors
71 */
73{
74 return sizeof(standard_color_names) / sizeof(standard_color_names[0]);
75}
76
77/*!
78 \brief Get color name
79
80 \param n color index
81 */
83{
84 return &standard_color_names[n];
85}
86
87/*!
88 \brief Parse color string and set red,green,blue
89
90 \param str color string
91 \param[out] red red value
92 \param[out] grn green value
93 \param[out] blu blue value
94
95 \return 1 OK
96 \return 2 NONE
97 \return 0 on error
98 */
99int G_str_to_color(const char *str, int *red, int *grn, int *blu)
100{
101 char buf[100];
103 int i;
104
105 G_strlcpy(buf, str, sizeof(buf));
106 G_chop(buf);
107
108 G_debug(3, "G_str_to_color(): str = '%s'", buf);
109
110 if (G_strcasecmp(buf, "NONE") == 0)
111 return 2;
112
113 if (sscanf(buf, "%d%*[,:; ]%d%*[,:; ]%d", red, grn, blu) == 3) {
114 if (*red < 0 || *red > 255 || *grn < 0 || *grn > 255 || *blu < 0 ||
115 *blu > 255)
116 return 0;
117
118 return 1;
119 }
120
121 unsigned int hex;
122
123 if (sscanf(buf, "#%x", &hex) == 1) {
124 *red = (hex >> 16) & 0xFF;
125 *grn = (hex >> 8) & 0xFF;
126 *blu = hex & 0xFF;
127 if (*red < 0 || *red > 255 || *grn < 0 || *grn > 255 || *blu < 0 ||
128 *blu > 255)
129 return 0;
130
131 return 1;
132 }
133
134 /* Look for this color in the standard (preallocated) colors */
135 for (i = 0; i < num_names; i++) {
136 const struct color_name *name = &standard_color_names[i];
137
138 if (G_strcasecmp(buf, name->name) == 0) {
139 struct color_rgb rgb = standard_colors_rgb[name->number];
140
141 *red = (int)rgb.r;
142 *grn = (int)rgb.g;
143 *blu = (int)rgb.b;
144
145 return 1;
146 }
147 }
148
149 return 0;
150}
151
152/*!
153 \brief Converts RGB color values to HSV format.
154
155 \note This implementation is experimental and may be subject to change.
156
157 \param r red component of the RGB color
158 \param g green component of the RGB color
159 \param b blue component of the RGB color
160 \param[out] h pointer to store the calculated hue
161 \param[out] s pointer to store the calculated saturation
162 \param[out] v pointer to store the calculated value
163
164 \since version 8.5
165 */
166void G_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
167{
168 float r_norm = (float)r / 255.0f;
169 float g_norm = (float)g / 255.0f;
170 float b_norm = (float)b / 255.0f;
171
172 float cmax = MAX(r_norm, MAX(g_norm, b_norm));
173 float cmin = MIN(r_norm, MIN(g_norm, b_norm));
174 float diff = cmax - cmin;
175
176 if (cmax == cmin) {
177 *h = 0;
178 }
179 else if (cmax == r_norm) {
180 *h = fmodf((60.0f * ((g_norm - b_norm) / diff) + 360.0f), 360.0f);
181 }
182 else if (cmax == g_norm) {
183 *h = fmodf((60.0f * ((b_norm - r_norm) / diff) + 120.0f), 360.0f);
184 }
185 else {
186 *h = fmodf((60.0f * ((r_norm - g_norm) / diff) + 240.0f), 360.0f);
187 }
188
189 if (cmax == 0) {
190 *s = 0;
191 }
192 else {
193 *s = (diff / cmax) * 100.0f;
194 }
195
196 *v = cmax * 100.0f;
197}
198
199/*!
200 \brief Parse red,green,blue and set color string
201
202 \param r red component of RGB color
203 \param g green component of RGB color
204 \param b blue component of RGB color
205 \param clr_frmt color format to be used (RGB, HEX, HSV, TRIPLET).
206 \param[out] str color string
207
208 \since version 8.5
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
254 \since version 8.5
255 */
257{
258 if (strcmp(option->answer, "rgb") == 0) {
259 return RGB;
260 }
261 if (strcmp(option->answer, "triplet") == 0) {
262 return TRIPLET;
263 }
264 if (strcmp(option->answer, "hsv") == 0) {
265 return HSV;
266 }
267 if (strcmp(option->answer, "hex") == 0) {
268 return HEX;
269 }
270
271 G_fatal_error(_("Unknown color format '%s'"), option->answer);
272}
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:256
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:166
int G_num_standard_colors(void)
Get number of named colors (RGB triplets)
Definition color_str.c:52
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:99
int G_num_standard_color_names(void)
Get number of named colors (color names)
Definition color_str.c:72
struct color_rgb G_standard_color_rgb(int n)
Get RGB triplet of given color.
Definition color_str.c:62
const struct color_name * G_standard_color_name(int n)
Get color name.
Definition color_str.c:82
#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:45
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition strings.c:330
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:54
#define MIN(a, b)
Definition gis.h:150
#define MAX(a, b)
Definition gis.h:145
#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:37
double r
Definition r_raster.c:37
Structure that stores option information.
Definition gis.h:560