Initialize Tizen 2.3
[framework/uifw/xorg/lib/libxpm.git] / src / 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 #ifdef HAVE_CONFIG_H
46 #include <config.h>
47 #endif
48 #include "XpmI.h"
49 #include <ctype.h>
50
51 #ifndef FOR_MSW                         /* normal part first, MSW part at
52                                          * the end, (huge ifdef!) */
53 /*
54  * Read a rgb text file.  It stores the rgb values (0->65535)
55  * and the rgb mnemonics (malloc'ed) into the "rgbn" array.  Returns the
56  * number of entries stored.
57  */
58 int
59 xpmReadRgbNames(
60     char        *rgb_fname,
61     xpmRgbName   rgbn[])
62 {
63     FILE *rgbf;
64     int n, items, red, green, blue;
65     char line[512], name[512], *rgbname, *s1, *s2;
66     xpmRgbName *rgb;
67
68     /* Open the rgb text file.  Abort if error. */
69     if ((rgbf = fopen(rgb_fname, "r")) == NULL)
70         return 0;
71
72     /* Loop reading each line in the file. */
73     n = 0;
74     rgb = rgbn;
75     /* Quit if rgb text file has too many entries. */
76     while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
77
78         /* Skip silently if line is bad. */
79         items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
80         if (items != 4)
81             continue;
82
83         /*
84          * Make sure rgb values are within 0->255 range. Skip silently if
85          * bad.
86          */
87         if (red < 0 || red > 0xFF ||
88             green < 0 || green > 0xFF ||
89             blue < 0 || blue > 0xFF)
90             continue;
91
92         /* Allocate memory for ascii name. If error give up here. */
93         if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
94             break;
95
96         /* Copy string to ascii name and lowercase it. */
97         for (s1 = name, s2 = rgbname; *s1; s1++)
98             *s2++ = tolower(*s1);
99         *s2 = '\0';
100
101         /* Save the rgb values and ascii name in the array. */
102         rgb->r = red * 257;             /* 65535/255 = 257 */
103         rgb->g = green * 257;
104         rgb->b = blue * 257;
105         rgb->name = rgbname;
106         rgb++;
107         n++;
108     }
109
110     fclose(rgbf);
111
112     /* Return the number of read rgb names. */
113     return n < 0 ? 0 : n;
114 }
115
116 /*
117  * Return the color name corresponding to the given rgb values
118  */
119 char *
120 xpmGetRgbName(
121     xpmRgbName  rgbn[],         /* rgb mnemonics from rgb text file */
122     int         rgbn_max,       /* number of rgb mnemonics in table */
123     int         red,            /* rgb values */
124     int         green,
125     int         blue)
126 {
127     int i;
128     xpmRgbName *rgb;
129
130     /*
131      * Just perform a dumb linear search over the rgb values of the color
132      * mnemonics.  One could speed things up by sorting the rgb values and
133      * using a binary search, or building a hash table, etc...
134      */
135     for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
136         if (red == rgb->r && green == rgb->g && blue == rgb->b)
137             return rgb->name;
138
139     /* if not found return NULL */
140     return NULL;
141 }
142
143 /*
144  * Free the strings which have been malloc'ed in xpmReadRgbNames
145  */
146 void
147 xpmFreeRgbNames(
148     xpmRgbName  rgbn[],
149     int         rgbn_max)
150 {
151     int i;
152     xpmRgbName *rgb;
153
154     for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
155         XpmFree(rgb->name);
156 }
157
158 #else                                   /* here comes the MSW part, the
159                                          * second part of the  huge ifdef */
160
161 #include "rgbtab.h"                     /* hard coded rgb.txt table */
162
163 int
164 xpmReadRgbNames(
165     char        *rgb_fname,
166     xpmRgbName   rgbn[])
167 {
168     /*
169      * check for consistency???
170      * table has to be sorted for calls on strcasecmp
171      */
172     return (numTheRGBRecords);
173 }
174
175 /*
176  * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
177  * which has something like #0303 for one color
178  */
179 char *
180 xpmGetRgbName(
181     xpmRgbName rgbn[],          /* rgb mnemonics from rgb text file
182                                  * not used */
183     int         rgbn_max,       /* not used */
184     int         red,            /* rgb values */
185     int         green,
186     int         blue)
187
188 {
189     int i;
190     unsigned long rgbVal;
191
192     i = 0;
193     while (i < numTheRGBRecords) {
194         rgbVal = theRGBRecords[i].rgb;
195         if (GetRValue(rgbVal) == red &&
196             GetGValue(rgbVal) == green &&
197             GetBValue(rgbVal) == blue)
198             return (theRGBRecords[i].name);
199         i++;
200     }
201     return (NULL);
202 }
203
204 /* used in XParseColor in simx.c */
205 int
206 xpmGetRGBfromName(
207     char        *inname,
208     int         *r,
209     int         *g,
210     int         *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
280 xpmFreeRgbNames(
281     xpmRgbName  rgbn[],
282     int         rgbn_max)
283 {
284     /* nothing to do */
285 }
286
287 #endif                                  /* MSW part */