GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-b3621474ad
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 */
24 static 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. */
43 static 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  */
66 struct 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  */
86 const 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  */
103 int 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 void 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  */
210 void 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 }
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
char * answer
Definition: gis.h:577
unsigned char g
Definition: colors.h:40
unsigned char b
Definition: colors.h:40
unsigned char r
Definition: colors.h:40