]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/rgb.c
wxX11:
[wxWidgets.git] / src / xpm / rgb.c
1 /*
2 * Copyright (C) 1989-95 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 "XpmI.h"
46 #include <ctype.h>
47
48 #ifndef FOR_MSW /* normal part first, MSW part at
49 * the end, (huge ifdef!) */
50 /*
51 * Read a rgb text file. It stores the rgb values (0->65535)
52 * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the
53 * number of entries stored.
54 */
55 int
56 xpmReadRgbNames(rgb_fname, rgbn)
57 char *rgb_fname;
58 xpmRgbName rgbn[];
59
60 {
61 FILE *rgbf;
62 int n, items, red, green, blue;
63 char line[512], name[512], *rgbname, *s1, *s2;
64 xpmRgbName *rgb;
65
66 /* Open the rgb text file. Abort if error. */
67 if ((rgbf = fopen(rgb_fname, "r")) == NULL)
68 return 0;
69
70 /* Loop reading each line in the file. */
71 n = 0;
72 rgb = rgbn;
73 /* Quit if rgb text file has too many entries. */
74 while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
75
76 /* Skip silently if line is bad. */
77 items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
78 if (items != 4)
79 continue;
80
81 /*
82 * Make sure rgb values are within 0->255 range. Skip silently if
83 * bad.
84 */
85 if (red < 0 || red > 0xFF ||
86 green < 0 || green > 0xFF ||
87 blue < 0 || blue > 0xFF)
88 continue;
89
90 /* Allocate memory for ascii name. If error give up here. */
91 if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
92 break;
93
94 /* Copy string to ascii name and lowercase it. */
95 for (s1 = name, s2 = rgbname; *s1; s1++)
96 *s2++ = tolower(*s1);
97 *s2 = '\0';
98
99 /* Save the rgb values and ascii name in the array. */
100 rgb->r = red * 257; /* 65535/255 = 257 */
101 rgb->g = green * 257;
102 rgb->b = blue * 257;
103 rgb->name = rgbname;
104 rgb++;
105 n++;
106 }
107
108 fclose(rgbf);
109
110 /* Return the number of read rgb names. */
111 return n < 0 ? 0 : n;
112 }
113
114 /*
115 * Return the color name corresponding to the given rgb values
116 */
117 char *
118 xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
119 xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file */
120 int rgbn_max; /* number of rgb mnemonics in table */
121 int red, green, blue; /* rgb values */
122
123 {
124 int i;
125 xpmRgbName *rgb;
126
127 /*
128 * Just perform a dumb linear search over the rgb values of the color
129 * mnemonics. One could speed things up by sorting the rgb values and
130 * using a binary search, or building a hash table, etc...
131 */
132 for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
133 if (red == rgb->r && green == rgb->g && blue == rgb->b)
134 return rgb->name;
135
136 /* if not found return NULL */
137 return NULL;
138 }
139
140 /*
141 * Free the strings which have been malloc'ed in xpmReadRgbNames
142 */
143 void
144 xpmFreeRgbNames(rgbn, rgbn_max)
145 xpmRgbName rgbn[];
146 int rgbn_max;
147
148 {
149 int i;
150 xpmRgbName *rgb;
151
152 for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
153 XpmFree(rgb->name);
154 }
155
156 #else /* here comes the MSW part, the
157 * second part of the huge ifdef */
158
159 #include "rgbtab.h" /* hard coded rgb.txt table */
160
161 #ifdef __OS2__
162 /* Visual Age cannot deal with old, non-ansi, code */
163 int xpmReadRgbNames(char* rgb_fname, xpmRgbName rgbn[])
164 #else
165 int
166 xpmReadRgbNames(rgb_fname, rgbn)
167 char *rgb_fname;
168 xpmRgbName rgbn[];
169 #endif
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 #ifdef __OS2__
183 /* Visual Age cannot deal with old, non-ansi, code */
184 char* xpmGetRgbName(xpmRgbName rgbn[], int rgbn_max, int red, int green, int blue)
185 #else
186 char *
187 xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
188 xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file
189 * not used */
190 int rgbn_max; /* not used */
191 int red, green, blue; /* rgb values */
192 #endif
193 {
194 int i;
195 unsigned long rgbVal;
196
197 i = 0;
198 while (i < numTheRGBRecords) {
199 rgbVal = theRGBRecords[i].rgb;
200 if (GetRValue(rgbVal) == red &&
201 GetGValue(rgbVal) == green &&
202 GetBValue(rgbVal) == blue)
203 return (theRGBRecords[i].name);
204 i++;
205 }
206 return (NULL);
207 }
208
209 /* used in XParseColor in simx.c */
210 #ifdef __OS2__
211 /* Visual Age cannot deal with old, non-ansi, code */
212 int xpmGetRGBfromName(char* inname, int* r, int* g, int* b)
213 #else
214 int
215 xpmGetRGBfromName(inname, r, g, b)
216 char *inname;
217 int *r, *g, *b;
218 #endif
219 {
220 int left, right, middle;
221 int cmp;
222 unsigned long rgbVal;
223 char *name;
224 char *grey, *p;
225
226 name = xpmstrdup(inname);
227
228 /*
229 * the table in rgbtab.c has no names with spaces, and no grey, but a
230 * lot of gray
231 */
232 /* so first extract ' ' */
233 while (p = strchr(name, ' ')) {
234 while (*(p)) { /* till eof of string */
235 *p = *(p + 1); /* copy to the left */
236 p++;
237 }
238 }
239 /* fold to lower case */
240 p = name;
241 while (*p) {
242 *p = tolower(*p);
243 p++;
244 }
245
246 /*
247 * substitute Grey with Gray, else rgbtab.h would have more than 100
248 * 'duplicate' entries
249 */
250 if (grey = strstr(name, "grey"))
251 grey[2] = 'a';
252
253 /* binary search */
254 left = 0;
255 right = numTheRGBRecords - 1;
256 do {
257 middle = (left + right) / 2;
258 cmp = xpmstrcasecmp(name, theRGBRecords[middle].name);
259 if (cmp == 0) {
260 rgbVal = theRGBRecords[middle].rgb;
261 *r = GetRValue(rgbVal);
262 *g = GetGValue(rgbVal);
263 *b = GetBValue(rgbVal);
264 free(name);
265 return (1);
266 } else if (cmp < 0) {
267 right = middle - 1;
268 } else { /* > 0 */
269 left = middle + 1;
270 }
271 } while (left <= right);
272
273 /*
274 * I don't like to run in a ColorInvalid error and to see no pixmap at
275 * all, so simply return a red pixel. Should be wrapped in an #ifdef
276 * HeDu
277 */
278
279 *r = 255;
280 *g = 0;
281 *b = 0; /* red error pixel */
282
283 free(name);
284 return (1);
285 }
286
287 #ifdef __OS2__
288 /* Visual Age cannot deal with old, non-ansi, code */
289 void xpmFreeRgbNames(xpmRgbName rgbn[], int rgbn_max)
290 #else
291 void
292 xpmFreeRgbNames(rgbn, rgbn_max)
293 xpmRgbName rgbn[];
294 int rgbn_max;
295 #endif
296 {
297 /* nothing to do */
298 }
299
300 #endif /* MSW part */