1 /* $XConsortium: Xpmrgb.c /main/6 1996/09/20 08:16:01 pascale $ */
2 /*
3 * Copyright (C) 1989-95 GROUPE BULL
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of GROUPE BULL shall not be
23 * used in advertising or otherwise to promote the sale, use or other dealings
24 * in this Software without prior written authorization from GROUPE BULL.
25 */
26
27 /*****************************************************************************\
28 * rgb.c: *
29 * *
30 * XPM library *
31 * Rgb file utilities *
32 * *
33 * Developed by Arnaud Le Hors *
34 \*****************************************************************************/
35
36 /*
37 * The code related to FOR_MSW has been added by
38 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
39 */
40
41 /*
42 * Part of this code has been taken from the ppmtoxpm.c file written by Mark
43 * W. Snitily but has been modified for my special need
44 */
45
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49
50
51 #include "XpmI.h"
52 #include <ctype.h>
53
54 #ifndef FOR_MSW /* normal part first, MSW part at
55 * the end, (huge ifdef!) */
56 /*
57 * Read a rgb text file. It stores the rgb values (0->65535)
58 * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the
59 * number of entries stored.
60 */
61 int
xpmReadRgbNames(rgb_fname,rgbn)62 xpmReadRgbNames(rgb_fname, rgbn)
63 char *rgb_fname;
64 xpmRgbName rgbn[];
65
66 {
67 FILE *rgbf;
68 int n, items, red, green, blue;
69 char line[512], name[512], *rgbname, *s1, *s2;
70 xpmRgbName *rgb;
71
72 /* Open the rgb text file. Abort if error. */
73 if ((rgbf = fopen(rgb_fname, "r")) == NULL)
74 return 0;
75
76 /* Loop reading each line in the file. */
77 n = 0;
78 rgb = rgbn;
79 /* Quit if rgb text file has too many entries. */
80 while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
81
82 /* Skip silently if line is bad. */
83 items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
84 if (items != 4)
85 continue;
86
87 /*
88 * Make sure rgb values are within 0->255 range. Skip silently if
89 * bad.
90 */
91 if (red < 0 || red > 0xFF ||
92 green < 0 || green > 0xFF ||
93 blue < 0 || blue > 0xFF)
94 continue;
95
96 /* Allocate memory for ascii name. If error give up here. */
97 if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
98 break;
99
100 /* Copy string to ascii name and lowercase it. */
101 for (s1 = name, s2 = rgbname; *s1; s1++)
102 *s2++ = tolower(*s1);
103 *s2 = '\0';
104
105 /* Save the rgb values and ascii name in the array. */
106 rgb->r = red * 257; /* 65535/255 = 257 */
107 rgb->g = green * 257;
108 rgb->b = blue * 257;
109 rgb->name = rgbname;
110 rgb++;
111 n++;
112 }
113
114 fclose(rgbf);
115
116 /* Return the number of read rgb names. */
117 return n < 0 ? 0 : n;
118 }
119
120 /*
121 * Return the color name corresponding to the given rgb values
122 */
123 char *
xpmGetRgbName(rgbn,rgbn_max,red,green,blue)124 xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
125 xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file */
126 int rgbn_max; /* number of rgb mnemonics in table */
127 int red, green, blue; /* rgb values */
128
129 {
130 int i;
131 xpmRgbName *rgb;
132
133 /*
134 * Just perform a dumb linear search over the rgb values of the color
135 * mnemonics. One could speed things up by sorting the rgb values and
136 * using a binary search, or building a hash table, etc...
137 */
138 for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
139 if (red == rgb->r && green == rgb->g && blue == rgb->b)
140 return rgb->name;
141
142 /* if not found return NULL */
143 return NULL;
144 }
145
146 /*
147 * Free the strings which have been malloc'ed in xpmReadRgbNames
148 */
149 void
xpmFreeRgbNames(rgbn,rgbn_max)150 xpmFreeRgbNames(rgbn, rgbn_max)
151 xpmRgbName rgbn[];
152 int rgbn_max;
153
154 {
155 int i;
156 xpmRgbName *rgb;
157
158 for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
159 XpmFree(rgb->name);
160 }
161
162 #else /* here comes the MSW part, the
163 * second part of the huge ifdef */
164
165 #include "rgbtab.h" /* hard coded rgb.txt table */
166
167 int
xpmReadRgbNames(rgb_fname,rgbn)168 xpmReadRgbNames(rgb_fname, rgbn)
169 char *rgb_fname;
170 xpmRgbName rgbn[];
171 {
172 /*
173 * check for consistency???
174 * table has to be sorted for calls on strcasecmp
175 */
176 return (numTheRGBRecords);
177 }
178
179 /*
180 * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
181 * which has something like #0303 for one color
182 */
183 char *
xpmGetRgbName(rgbn,rgbn_max,red,green,blue)184 xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
185 xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file
186 * not used */
187 int rgbn_max; /* not used */
188 int red, green, blue; /* rgb values */
189
190 {
191 int i;
192 unsigned long rgbVal;
193
194 i = 0;
195 while (i < numTheRGBRecords) {
196 rgbVal = theRGBRecords[i].rgb;
197 if (GetRValue(rgbVal) == red &&
198 GetGValue(rgbVal) == green &&
199 GetBValue(rgbVal) == blue)
200 return (theRGBRecords[i].name);
201 i++;
202 }
203 return (NULL);
204 }
205
206 /* used in XParseColor in simx.c */
207 int
xpmGetRGBfromName(inname,r,g,b)208 xpmGetRGBfromName(inname, r, g, b)
209 char *inname;
210 int *r, *g, *b;
211 {
212 int left, right, middle;
213 int cmp;
214 unsigned long rgbVal;
215 char *name;
216 char *grey, *p;
217
218 name = xpmstrdup(inname);
219
220 /*
221 * the table in rgbtab.c has no names with spaces, and no grey, but a
222 * lot of gray
223 */
224 /* so first extract ' ' */
225 while (p = strchr(name, ' ')) {
226 while (*(p)) { /* till eof of string */
227 *p = *(p + 1); /* copy to the left */
228 p++;
229 }
230 }
231 /* fold to lower case */
232 p = name;
233 while (*p) {
234 *p = tolower(*p);
235 p++;
236 }
237
238 /*
239 * substitute Grey with Gray, else rgbtab.h would have more than 100
240 * 'duplicate' entries
241 */
242 if (grey = strstr(name, "grey"))
243 grey[2] = 'a';
244
245 /* binary search */
246 left = 0;
247 right = numTheRGBRecords - 1;
248 do {
249 middle = (left + right) / 2;
250 cmp = xpmstrcasecmp(name, theRGBRecords[middle].name);
251 if (cmp == 0) {
252 rgbVal = theRGBRecords[middle].rgb;
253 *r = GetRValue(rgbVal);
254 *g = GetGValue(rgbVal);
255 *b = GetBValue(rgbVal);
256 free(name);
257 return (1);
258 } else if (cmp < 0) {
259 right = middle - 1;
260 } else { /* > 0 */
261 left = middle + 1;
262 }
263 } while (left <= right);
264
265 /*
266 * I don't like to run in a ColorInvalid error and to see no pixmap at
267 * all, so simply return a red pixel. Should be wrapped in an #ifdef
268 * HeDu
269 */
270
271 *r = 255;
272 *g = 0;
273 *b = 0; /* red error pixel */
274
275 free(name);
276 return (1);
277 }
278
279 void
xpmFreeRgbNames(rgbn,rgbn_max)280 xpmFreeRgbNames(rgbn, rgbn_max)
281 xpmRgbName rgbn[];
282 int rgbn_max;
283
284 {
285 /* nothing to do */
286 }
287
288 #endif /* MSW part */
289