Blame lib/Xm/Xpmrgb.c

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