Back to index

plt-scheme  4.2.1
rgb.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1989-95 GROUPE BULL
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00017  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00018  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00019  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00020  *
00021  * Except as contained in this notice, the name of GROUPE BULL shall not be
00022  * used in advertising or otherwise to promote the sale, use or other dealings
00023  * in this Software without prior written authorization from GROUPE BULL.
00024  */
00025 
00026 /*****************************************************************************\
00027 * rgb.c:                                                                      *
00028 *                                                                             *
00029 *  XPM library                                                                *
00030 *  Rgb file utilities                                                         *
00031 *                                                                             *
00032 *  Developed by Arnaud Le Hors                                                *
00033 \*****************************************************************************/
00034 
00035 /*
00036  * The code related to FOR_MSW has been added by
00037  * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
00038  */
00039 
00040 /*
00041  * Part of this code has been taken from the ppmtoxpm.c file written by Mark
00042  * W. Snitily but has been modified for my special need
00043  */
00044 
00045 #include "xpmP.h"
00046 #include <ctype.h>
00047 #if defined(SYSV) || defined(SVR4) || defined(VMS) || defined(__GNUC__)
00048 #include <string.h>
00049 #else
00050 #include <strings.h>
00051 #endif
00052 
00053 #ifndef FOR_MSW                           /* normal part first, MSW part at
00054                                     * the end, (huge ifdef!) */
00055 /*
00056  * Read a rgb text file.  It stores the rgb values (0->65535)
00057  * and the rgb mnemonics (malloc'ed) into the "rgbn" array.  Returns the
00058  * number of entries stored.
00059  */
00060 int
00061 xpmReadRgbNames(rgb_fname, rgbn)
00062     char *rgb_fname;
00063     xpmRgbName rgbn[];
00064 
00065 {
00066     FILE *rgbf;
00067     int n, items, red, green, blue;
00068     char line[512], name[512], *rgbname, *s1, *s2;
00069     xpmRgbName *rgb;
00070 
00071     /* Open the rgb text file.  Abort if error. */
00072     if ((rgbf = fopen(rgb_fname, "r")) == NULL)
00073        return 0;
00074 
00075     /* Loop reading each line in the file. */
00076     n = 0;
00077     rgb = rgbn; 
00078     /* Quit if rgb text file has too many entries. */
00079     while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
00080 
00081        /* Skip silently if line is bad. */
00082        items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
00083        if (items != 4)
00084            continue;
00085 
00086        /*
00087         * Make sure rgb values are within 0->255 range. Skip silently if
00088         * bad.
00089         */
00090        if (red < 0 || red > 0xFF ||
00091            green < 0 || green > 0xFF ||
00092            blue < 0 || blue > 0xFF)
00093            continue;
00094 
00095        /* Allocate memory for ascii name. If error give up here. */
00096        if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
00097            break;
00098 
00099        /* Copy string to ascii name and lowercase it. */
00100        for (s1 = name, s2 = rgbname; *s1; s1++)
00101            *s2++ = tolower(*s1);
00102        *s2 = '\0';
00103 
00104        /* Save the rgb values and ascii name in the array. */
00105        rgb->r = red * 257;         /* 65535/255 = 257 */
00106        rgb->g = green * 257;
00107        rgb->b = blue * 257;
00108        rgb->name = rgbname;
00109        rgb++;
00110        n++;
00111     }
00112 
00113     fclose(rgbf);
00114 
00115     /* Return the number of read rgb names. */
00116     return n < 0 ? 0 : n;
00117 }
00118 
00119 /*
00120  * Return the color name corresponding to the given rgb values
00121  */
00122 char *
00123 xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
00124     xpmRgbName rgbn[];                    /* rgb mnemonics from rgb text file */
00125     int rgbn_max;                  /* number of rgb mnemonics in table */
00126     int red, green, blue;          /* rgb values */
00127 
00128 {
00129     int i;
00130     xpmRgbName *rgb;
00131 
00132     /*
00133      * Just perform a dumb linear search over the rgb values of the color
00134      * mnemonics.  One could speed things up by sorting the rgb values and
00135      * using a binary search, or building a hash table, etc...
00136      */
00137     for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
00138        if (red == rgb->r && green == rgb->g && blue == rgb->b)
00139            return rgb->name;
00140 
00141     /* if not found return NULL */
00142     return NULL;
00143 }
00144 
00145 /*
00146  * Free the strings which have been malloc'ed in xpmReadRgbNames
00147  */
00148 void
00149 xpmFreeRgbNames(rgbn, rgbn_max)
00150     xpmRgbName rgbn[];
00151     int rgbn_max;
00152 
00153 {
00154     int i;
00155     xpmRgbName *rgb;
00156 
00157     for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
00158        XpmFree(rgb->name);
00159 }
00160 
00161 #else                              /* here comes the MSW part, the
00162                                     * second part of the  huge ifdef */
00163 
00164 #include "rgbtab.h"                /* hard coded rgb.txt table */
00165 
00166 int
00167 xpmReadRgbNames(rgb_fname, rgbn)
00168     char *rgb_fname;
00169     xpmRgbName rgbn[];
00170 {
00171     /*
00172      * check for consistency???
00173      * table has to be sorted for calls on strcasecmp
00174      */
00175     return (numTheRGBRecords);
00176 }
00177 
00178 /*
00179  * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
00180  * which has something like #0303 for one color
00181  */
00182 char *
00183 xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
00184     xpmRgbName rgbn[];                    /* rgb mnemonics from rgb text file
00185                                     * not used */
00186     int rgbn_max;                  /* not used */
00187     int red, green, blue;          /* rgb values */
00188 
00189 {
00190     int i;
00191     unsigned long rgbVal;
00192 
00193     i = 0;
00194     while (i < numTheRGBRecords) {
00195        rgbVal = theRGBRecords[i].rgb;
00196        if (GetRValue(rgbVal) == red &&
00197            GetGValue(rgbVal) == green &&
00198            GetBValue(rgbVal) == blue)
00199            return (theRGBRecords[i].name);
00200        i++;
00201     }
00202     return (NULL);
00203 }
00204 
00205 /* used in XParseColor in simx.c */
00206 int
00207 xpmGetRGBfromName(inname, r, g, b)
00208     char *inname;
00209     int *r, *g, *b;
00210 {
00211     int left, right, middle;
00212     int cmp;
00213     unsigned long rgbVal;
00214     char *name;
00215     char *grey, *p;
00216 
00217     name = strdup(inname);
00218 
00219     /*
00220      * the table in rgbtab.c has no names with spaces, and no grey, but a
00221      * lot of gray
00222      */
00223     /* so first extract ' ' */
00224     while (p = strchr(name, ' ')) {
00225        while (*(p)) {                     /* till eof of string */
00226            *p = *(p + 1);          /* copy to the left */
00227            p++;
00228        }
00229     }
00230     /* fold to lower case */
00231     p = name;
00232     while (*p) {
00233        *p = tolower(*p);
00234        p++;
00235     }
00236 
00237     /*
00238      * substitute Grey with Gray, else rgbtab.h would have more than 100
00239      * 'duplicate' entries
00240      */
00241     if (grey = strstr(name, "grey"))
00242        grey[2] = 'a';
00243 
00244     /* binary search */
00245     left = 0;
00246     right = numTheRGBRecords - 1;
00247     do {
00248        middle = (left + right) / 2;
00249        cmp = strcasecmp(name, theRGBRecords[middle].name);
00250        if (cmp == 0) {
00251            rgbVal = theRGBRecords[middle].rgb;
00252            *r = GetRValue(rgbVal);
00253            *g = GetGValue(rgbVal);
00254            *b = GetBValue(rgbVal);
00255            free(name);
00256            return (1);
00257        } else if (cmp < 0) {
00258            right = middle - 1;
00259        } else {                    /* > 0 */
00260            left = middle + 1;
00261        }
00262     } while (left <= right);
00263 
00264     /*
00265      * I don't like to run in a ColorInvalid error and to see no pixmap at
00266      * all, so simply return a red pixel. Should be wrapped in an #ifdef
00267      * HeDu
00268      */
00269 
00270     *r = 255;
00271     *g = 0;
00272     *b = 0;                        /* red error pixel */
00273 
00274     free(name);
00275     return (1);
00276 }
00277 
00278 void
00279 xpmFreeRgbNames(rgbn, rgbn_max)
00280     xpmRgbName rgbn[];
00281     int rgbn_max;
00282 
00283 {
00284     /* nothing to do */
00285 }
00286 
00287 #endif                             /* MSW part */