rgb.c revision 52dc082b
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 */ 58int 59xpmReadRgbNames( 60 const 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" FOPEN_CLOEXEC)) == 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 */ 119char * 120xpmGetRgbName( 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 */ 146void 147xpmFreeRgbNames( 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 163int 164xpmReadRgbNames( 165 const 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 */ 179char * 180xpmGetRgbName( 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 */ 205int 206xpmGetRGBfromName( 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 279void 280xpmFreeRgbNames( 281 xpmRgbName rgbn[], 282 int rgbn_max) 283{ 284 /* nothing to do */ 285} 286 287#endif /* MSW part */ 288