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