[GRASS-dev] lib fn to convert int color number to RGB values?
Glynn Clements
glynn at gclements.plus.com
Wed Jan 30 11:09:47 EST 2008
Ivan Shmakov wrote:
> >> Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
> >> needed in lib/display/tran_colr.c?
>
> > Yes. E.g.:
>
> > int D_color_number_to_RGB(int color, int &r, int &g, int &b)
> > {
>
> That looks a lot like C++. Surely it will work with C89?
Oops. I meant:
int D_color_number_to_RGB(int color, int *r, int *g, int *b)
> > const struct color_rgb *c;
>
> > if (color <= 0)
> > return 0;
>
> BTW, is it a GRASS convention to use 0 to indicate failure?
> Standard C library functions tend to use -1 for failure, while
> using non-negative values to indicate success.
The GRASS convention is to use a different convention for each
function ;)
More seriously: functions which only return a success/failure
indication typically (but not always) return 1 for success and 0 for
failure, so that conditionals read naturally, i.e. "if (foo(...))"
means "if it succeeds" and "if (!foo(...))" means "if it fails".
Functions which normally return a non-negative integer normally return
a negative integer to indicate failure.
Functions which return 0 for success should ideally be tested using
"if (foo(...) == 0)" rather than "if (!foo(...))", as the use of "!"
connotes a negative (i.e. failure).
> Also, it seems feasible to set `errno' in the library functions
> like this. Do I understand correctly that it isn't done (with
> any regularity) in GRASS?
AFAIK, GRASS itself never sets errno.
> > if (color >= ncolors)
> > return 0;
>
> > c = &colors[color];
> > r = c->r;
> > g = c->g;
> > b = c->b;
>
> > return 1;
> > }
>
> [...]
>
> I'd suggest the following, but I don't know (yet) the
> appropriate conventions for the D_* functions.
>
> int
> D_color_number_to_RGB (int color, int *r, int *g, int *b)
> {
> const struct color_rgb *c;
>
> if (color <= 0 || color >= ncolors) {
> errno = EINVAL;
> return -1;
> }
>
> c = &colors[color];
> if (r != 0) *r = c->r;
> if (g != 0) *g = c->g;
> if (b != 0) *b = c->b;
>
> return 0;
> }
>
> With the `if (X != 0)' guards, the function may be used to query
> whether the given color index exists, while not asking for its
> components to be returned, like:
>
> if (D_color_number_to_RGB (INDEX, 0, 0, 0) < 0) {
> /* color INDEX doesn't exist */
> }
That makes sense, although I would omit the "!= 0", and just use e.g.
"if (r) ...". Generally, I prefer "if (x)" and "if (!x)" if zero/NULL
is a false/unset/etc indicator.
> If `struct color_rgb' is a ``public'' data type, then it might
> be appropriate to code this function as:
The problem is that we have both color_rgb (colors.h) and RGBA_Color
(gis.h) structures, and we should deprecate one of them (probably
color_rgb).
--
Glynn Clements <glynn at gclements.plus.com>
More information about the grass-dev
mailing list