File: colors.c

package info (click to toggle)
fig2dev 1:3.2.7a-5+deb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 4,556 kB
  • sloc: ansic: 35,809; sh: 5,401; makefile: 177; perl: 13; csh: 12
file content (166 lines) | stat: -rw-r--r-- 4,567 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * Fig2dev: Translate Fig code to various Devices
 * Copyright (c) 1991 by Micah Beck
 * Parts Copyright (c) 1985-1988 by Supoj Sutanthavibul
 * Parts Copyright (c) 1989-2002 by Brian V. Smith
 * Parts Copyright (c) 2015-2017 by Thomas Loimer
 *
 * Any party obtaining a copy of these files is granted, free of charge, a
 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
 * nonexclusive right and license to deal in this software and documentation
 * files (the "Software"), including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense and/or sell copies
 * of the Software, and to permit persons who receive copies from any such
 * party to do so, with the only requirement being that the above copyright
 * and this permission notice remain intact.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef	HAVE_STRINGS_H
#include <strings.h>
#endif
#include "pi.h"

#include "fig2dev.h"	/* includes "bool.h" */

struct color_db {
	char		*name;
	unsigned short	red, green, blue;
};

static int		read_colordb(void);
static int		numXcolors = 0;
static struct color_db	*Xcolors;

int
lookup_X_color(char *name, RGB *rgb)
{
	static bool	have_read_X_colors = false;
	int		i, n = 0;
	unsigned short	r, g, b;
	struct color_db *col;

	if (name[0] == '#') {			/* hex color parse it now */
	    if (strlen(name) == 4) {		/* #rgb */
		    n = sscanf(name,"#%1hx%1hx%1hx",&r,&g,&b);
		    rgb->red   = ((r << 4) + r) << 8;
		    rgb->green = ((g << 4) + g) << 8;
		    rgb->blue  = ((b << 4) + b) << 8;
	    } else if (strlen(name) == 7) {		/* #rrggbb */
		    n = sscanf(name,"#%2hx%2hx%2hx",&r,&g,&b);
		    rgb->red   = r << 8;
		    rgb->green = g << 8;
		    rgb->blue  = b << 8;
	    } else if (strlen(name) == 10) {	/* #rrrgggbbb */
		    n = sscanf(name,"#%3hx%3hx%3hx",&r,&g,&b);
		    rgb->red   = r << 4;
		    rgb->green = g << 4;
		    rgb->blue  = b << 4;
	    } else if (strlen(name) == 13) {	/* #rrrrggggbbbb */
		    n = sscanf(name,"#%4hx%4hx%4hx",&r,&g,&b);
		    rgb->red   = r;
		    rgb->green = g;
		    rgb->blue  = b;
	    }
	    if (n == 3) {
		/* ok */
		return 0;
	    }
	} else {
	    /* read the X color database file if we haven't done that yet */
	    if (!have_read_X_colors) {
		if (read_colordb() != 0) {
		    /* error reading color database, return black */
		    rgb->red = rgb->green = rgb->blue = 0u;
		    return -1;
		}
		have_read_X_colors = true;
	    }

	    /* named color, look in the database we read in */
	    for (col = Xcolors, i=0; i<numXcolors; ++col, ++i) {
		if (strcasecmp(col->name, name) == 0) {
		    /* found it */
		    rgb->red = col->red;
		    rgb->green = col->green;
		    rgb->blue = col->blue;
		    return 0;
		}
	    }
	}
	/* not found or bad #rgb spec, set to black */
	rgb->red = rgb->green = rgb->blue = 0;
	return -1;
}

/* read the X11 RGB color database (ASCII .txt) file */

int
read_colordb(void)
{
    static int		maxcolors = 400;
    FILE		*fp;
    char		s[100], s1[100], *c1, *c2;
    unsigned short	r,g,b;
    struct color_db	*col;
    char		*rgbfile;

    rgbfile = getenv("FIG2DEV_RGBFILE");
    if (rgbfile == NULL) {
      rgbfile = RGB_FILE;
    }
    fp = fopen(rgbfile, "r");
    if (fp == NULL) {
      fprintf(stderr,"Couldn't open the RGB database file '%s'\n", rgbfile);
      return -1;
    }
    if ((Xcolors = (struct color_db*) malloc(maxcolors*sizeof(struct color_db)))
		== NULL) {
      fprintf(stderr,"Couldn't allocate space for the RGB database file\n");
      return -1;
    }

    while (fgets(s, sizeof(s), fp)) {
	if (numXcolors >= maxcolors) {
	    maxcolors += 500;
	    if ((Xcolors = (struct color_db*) realloc(Xcolors, maxcolors*sizeof(struct color_db))) == NULL) {
	      fprintf(stderr,"Couldn't allocate space for the RGB database file\n");
	      return -1;
	    }
	}
	if (sscanf(s, "%hu %hu %hu %[^\n]", &r, &g, &b, s1) == 4) {
	    /* remove any white space from the color name */
	    for (c1=s1, c2=s1; *c2; ++c2) {
		if (*c2 != ' ' && *c2 != '\t') {
		   *c1 = *c2;
		   ++c1;
		}
	    }
	    *c1 = '\0';
	    col = (Xcolors+numXcolors);
	    col->red = r << 8;
	    col->green = g << 8;
	    col->blue = b << 8;
	    col->name = malloc(strlen(s1)+1);
	    strcpy(col->name, s1);
	    ++numXcolors;
	}
    }
    fclose(fp);
    return 0;
}

/* convert rgb to gray scale using the classic luminance conversion factors */

float
rgb2luminance (float r, float g, float b)
{
      return (float) (0.3*r + 0.59*g + 0.11*b);
}