summaryrefslogtreecommitdiff
path: root/src/rgb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgb.c')
-rw-r--r--src/rgb.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/src/rgb.c b/src/rgb.c
new file mode 100644
index 0000000..b26ee3f
--- /dev/null
+++ b/src/rgb.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* rgb.c: *
+* *
+* XPM library *
+* Rgb file utilities *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * Part of this code has been taken from the ppmtoxpm.c file written by Mark
+ * W. Snitily but has been modified for my special need
+ */
+
+#include "XpmI.h"
+#include <ctype.h>
+
+#ifndef FOR_MSW /* normal part first, MSW part at
+ * the end, (huge ifdef!) */
+/*
+ * Read a rgb text file. It stores the rgb values (0->65535)
+ * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the
+ * number of entries stored.
+ */
+int
+xpmReadRgbNames(rgb_fname, rgbn)
+ char *rgb_fname;
+ xpmRgbName rgbn[];
+
+{
+ FILE *rgbf;
+ int n, items, red, green, blue;
+ char line[512], name[512], *rgbname, *s1, *s2;
+ xpmRgbName *rgb;
+
+ /* Open the rgb text file. Abort if error. */
+ if ((rgbf = fopen(rgb_fname, "r")) == NULL)
+ return 0;
+
+ /* Loop reading each line in the file. */
+ n = 0;
+ rgb = rgbn;
+ /* Quit if rgb text file has too many entries. */
+ while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
+
+ /* Skip silently if line is bad. */
+ items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
+ if (items != 4)
+ continue;
+
+ /*
+ * Make sure rgb values are within 0->255 range. Skip silently if
+ * bad.
+ */
+ if (red < 0 || red > 0xFF ||
+ green < 0 || green > 0xFF ||
+ blue < 0 || blue > 0xFF)
+ continue;
+
+ /* Allocate memory for ascii name. If error give up here. */
+ if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
+ break;
+
+ /* Copy string to ascii name and lowercase it. */
+ for (s1 = name, s2 = rgbname; *s1; s1++)
+ *s2++ = tolower(*s1);
+ *s2 = '\0';
+
+ /* Save the rgb values and ascii name in the array. */
+ rgb->r = red * 257; /* 65535/255 = 257 */
+ rgb->g = green * 257;
+ rgb->b = blue * 257;
+ rgb->name = rgbname;
+ rgb++;
+ n++;
+ }
+
+ fclose(rgbf);
+
+ /* Return the number of read rgb names. */
+ return n < 0 ? 0 : n;
+}
+
+/*
+ * Return the color name corresponding to the given rgb values
+ */
+char *
+xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
+ xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file */
+ int rgbn_max; /* number of rgb mnemonics in table */
+ int red, green, blue; /* rgb values */
+
+{
+ int i;
+ xpmRgbName *rgb;
+
+ /*
+ * Just perform a dumb linear search over the rgb values of the color
+ * mnemonics. One could speed things up by sorting the rgb values and
+ * using a binary search, or building a hash table, etc...
+ */
+ for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
+ if (red == rgb->r && green == rgb->g && blue == rgb->b)
+ return rgb->name;
+
+ /* if not found return NULL */
+ return NULL;
+}
+
+/*
+ * Free the strings which have been malloc'ed in xpmReadRgbNames
+ */
+void
+xpmFreeRgbNames(rgbn, rgbn_max)
+ xpmRgbName rgbn[];
+ int rgbn_max;
+
+{
+ int i;
+ xpmRgbName *rgb;
+
+ for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
+ XpmFree(rgb->name);
+}
+
+#else /* here comes the MSW part, the
+ * second part of the huge ifdef */
+
+#include "rgbtab.h" /* hard coded rgb.txt table */
+
+int
+xpmReadRgbNames(rgb_fname, rgbn)
+ char *rgb_fname;
+ xpmRgbName rgbn[];
+{
+ /*
+ * check for consistency???
+ * table has to be sorted for calls on strcasecmp
+ */
+ return (numTheRGBRecords);
+}
+
+/*
+ * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
+ * which has something like #0303 for one color
+ */
+char *
+xpmGetRgbName(rgbn, rgbn_max, red, green, blue)
+ xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file
+ * not used */
+ int rgbn_max; /* not used */
+ int red, green, blue; /* rgb values */
+
+{
+ int i;
+ unsigned long rgbVal;
+
+ i = 0;
+ while (i < numTheRGBRecords) {
+ rgbVal = theRGBRecords[i].rgb;
+ if (GetRValue(rgbVal) == red &&
+ GetGValue(rgbVal) == green &&
+ GetBValue(rgbVal) == blue)
+ return (theRGBRecords[i].name);
+ i++;
+ }
+ return (NULL);
+}
+
+/* used in XParseColor in simx.c */
+int
+xpmGetRGBfromName(inname, r, g, b)
+ char *inname;
+ int *r, *g, *b;
+{
+ int left, right, middle;
+ int cmp;
+ unsigned long rgbVal;
+ char *name;
+ char *grey, *p;
+
+ name = xpmstrdup(inname);
+
+ /*
+ * the table in rgbtab.c has no names with spaces, and no grey, but a
+ * lot of gray
+ */
+ /* so first extract ' ' */
+ while (p = strchr(name, ' ')) {
+ while (*(p)) { /* till eof of string */
+ *p = *(p + 1); /* copy to the left */
+ p++;
+ }
+ }
+ /* fold to lower case */
+ p = name;
+ while (*p) {
+ *p = tolower(*p);
+ p++;
+ }
+
+ /*
+ * substitute Grey with Gray, else rgbtab.h would have more than 100
+ * 'duplicate' entries
+ */
+ if (grey = strstr(name, "grey"))
+ grey[2] = 'a';
+
+ /* binary search */
+ left = 0;
+ right = numTheRGBRecords - 1;
+ do {
+ middle = (left + right) / 2;
+ cmp = xpmstrcasecmp(name, theRGBRecords[middle].name);
+ if (cmp == 0) {
+ rgbVal = theRGBRecords[middle].rgb;
+ *r = GetRValue(rgbVal);
+ *g = GetGValue(rgbVal);
+ *b = GetBValue(rgbVal);
+ free(name);
+ return (1);
+ } else if (cmp < 0) {
+ right = middle - 1;
+ } else { /* > 0 */
+ left = middle + 1;
+ }
+ } while (left <= right);
+
+ /*
+ * I don't like to run in a ColorInvalid error and to see no pixmap at
+ * all, so simply return a red pixel. Should be wrapped in an #ifdef
+ * HeDu
+ */
+
+ *r = 255;
+ *g = 0;
+ *b = 0; /* red error pixel */
+
+ free(name);
+ return (1);
+}
+
+void
+xpmFreeRgbNames(rgbn, rgbn_max)
+ xpmRgbName rgbn[];
+ int rgbn_max;
+
+{
+ /* nothing to do */
+}
+
+#endif /* MSW part */