Edit

IABSD.fr/xenocara/lib/libXpm/src/rgb.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2006-11-25 17:32:04
    Hash : d8e9d107
    Message : import from X.Org 7.1

  • lib/libXpm/src/rgb.c
  • /*
     * 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
     */
    
    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    #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 */