📄 color.c
字号:
/*..........................................................................*//* *//* L a s t W a v e K e r n e l 3 . 0 *//* *//* Copyright (C) 1998-2002 Emmanuel Bacry. *//* email : lastwave@cmap.polytechnique.fr *//* *//*..........................................................................*//* *//* This program is a free software, you can redistribute it and/or *//* modify it under the terms of the GNU General Public License as *//* published by the Free Software Foundation; either version 2 of the *//* License, or (at your option) any later version *//* *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU General Public License for more details. *//* *//* You should have received a copy of the GNU General Public License *//* along with this program (in a file named COPYRIGHT); *//* if not, write to the Free Software Foundation, Inc., *//* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* *//*..........................................................................*//****************************************************************************//* *//* color.c Functions which deal with the colors *//* *//****************************************************************************/#include "lastwave.h"/**************************************************************** * * The color structures * ****************************************************************/ /* * A color will be adressed by a unsigned long of the form * * cciiiiii * * where each letter represents a group of 4 bits. * The colormaps are coded on the high byte (cc) and the iiiiii codes the color index inside this colormap. * Actually the colormaps are coded just in the 7 high bits of 'cc'. The higher bit is used for inversing a * color map (thus there are 128 possible colormaps which are decomposed as 64 color maps and their inversed). * The lowest bit of 'cc' is used to code the color. It is always off unless the color corresponds to the special * value 'invisible'. * * When parsing a color the whole 'cciiiiii' is returned. When parsing a colormap the unsigned long * 'cc000000' is returned (not just 'cc') so that you can just add a colormap number to a color index * (for building images). */ /* * The color structure */typedef struct color { char *name; /* The name of the color (or NULL) */ unsigned short red,blue,green; /* Values for Red Blue and Green */ unsigned long pixel; /* The corresponding pixel value */ unsigned short index; /* Index for internal use */} Color, *COLOR;/* * The colormap structure */typedef struct colorMap { char *name; /* Name of the colormap */ Color *colors; /* The colors of the colormap */ int size; /* The number of colors */} ColorMap, *COLORMAP;/* * The global array of all the colormaps * The first one (index 0) corresponds to the colors that are named (maximum is 256) * The other ones correspond to regular colormaps */#define ColorMapNMax 64static COLORMAP theColorMaps[ColorMapNMax];/* The current number of defined colormaps in "theColorMaps" (except index 0) */static int nColorMaps;/* The current colormap (could be inversed) */static int colorMapCur;/* Some colors */unsigned long bgColor, fgColor, mColor;const unsigned long invisibleColor = 0x1000000;static int theMouseMode = MouseInverse;/**************************************************************** * * Miscellenaous functions * ****************************************************************/ /* * Check RGB values */ static char CheckRGB(LWFLOAT *pr,LWFLOAT *pg,LWFLOAT *pb){ char flagOK = YES; if (*pr < 0 || *pr > 65535) { flagOK = NO; PrintfErr("Warning : Bad value for red value of color %.8g\n",*pr); *pr = MAX(*pr,0); *pr = MIN(*pr,65535); } if (*pg < 0 || *pg > 65535) { flagOK = NO; PrintfErr("Warning : Bad value for green value of color %.8g\n",*pr); *pg = MAX(*pg,0); *pg = MIN(*pg,65535); } if (*pb < 0 || *pb > 65535) { flagOK = NO; PrintfErr("Warning : Bad value for blue value of color %.8g\n",*pb); *pb = MAX(*pb,0); *pr = MIN(*pb,65535); } return(flagOK);}/* * Check HSV values */static char CheckHSV(LWFLOAT *ph,LWFLOAT *ps,LWFLOAT *pv){ char flagOK = YES; if (*ph < 0 || *ph > 360) { *ph += 100*360; *ph = *ph - ((int) (*ph/360))*360; } if (*ps < 0 || *ps > 1) { flagOK = NO; PrintfErr("Warning : Bad value for saturation value of color %.8g\n",*ps); *ps = MAX(*ps,0); *ps = MIN(*ps,1); } if (*pv < 0 || *pv > 1) { flagOK = NO; PrintfErr("Warning : Bad value for saturation value of color %.8g\n",*pv); *pv = MAX(*pv,0); *pv = MIN(*pv,1); } return(flagOK);}/* * Convert hue, saturation and value to red, blue green * Hue : 0 is red, 240 blue and 360 red again * Saturation and value : between 0 and 1 */static void HSVToRGB_(LWFLOAT *h, LWFLOAT *s, LWFLOAT *v){ int ih; LWFLOAT f,p,q,t; LWFLOAT r,g,b; b= g = r = 0; CheckHSV(h,s,v); f = p = q = t = 0; *h = (*h)/60.; ih = (int) (*h); f = (*h) - ih; p = (*v)*(1.-(*s)); q = (*v)*(1.-(*s)*f); t = (*v)*(1.-((*s)*(1.-f))); switch (ih % 6) { case 0: r = *v; g = t; b = p; break; case 1: r = q; g = *v; b = p; break; case 2: r = p; g = *v; b = t; break; case 3: r = p; g = q; b = *v; break; case 4: r = t; g = p; b = *v; break; case 5: r = *v; g = p; b = q; break; } *h = (int) 65535*r; *s = (int) 65535*g; *v = (int) 65535*b;}/**************************************************************** * * Dealing with named colors * ****************************************************************//* Get the named color "name" (or return new index) */static int GetNamedColor(char *name){ int i; for (i=0;i<theColorMaps[0]->size;i++) { if (theColorMaps[0]->colors[i].name == NULL) break; if (!strcmp(name,theColorMaps[0]->colors[i].name)) break; } if (i == theColorMaps[0]->size) return(-1); return(i);}/* Defining a named color using rgb values */void DefineNamedColorRGB(char *name,LWFLOAT red, LWFLOAT green, LWFLOAT blue){ int c; COLOR color; CheckRGB(&red,&green,&blue); c = GetNamedColor(name); if (c == -1) Errorf("DefineNamedColorRGB() : Sorry, too many named colors (there are %d)",theColorMaps[0]->size); /* Get the color */ color = &(theColorMaps[0]->colors[c]); /* If it exists we just modify the values */ if (color->name != NULL) { /* We display a message if values are different */ if (color->red != (unsigned short) red || color->green != (unsigned short) green || color->blue != (unsigned short) blue) PrintfErr("Color '%s' = [%d %d %d] becomes [%d %d %d]\n",name,(int) color->red,(int) color->green,(int) color->blue, (int) red,(int) green,(int) blue); color->red = (unsigned short) red; color->blue = (unsigned short) blue; color->green = (unsigned short) green; color->pixel = 0; color->index = 0; } /* Otherwise we create the color */ else { color->name = CopyStr(name); color->red = (unsigned short) red; color->blue = (unsigned short) blue; color->green = (unsigned short) green; color->pixel = 0; color->index = 0; }}/* Defining a named color using hsv values */void DefineNamedColorHSV(char *name,LWFLOAT hue, LWFLOAT saturation, LWFLOAT value){ CheckHSV(&hue,&saturation,&value); HSVToRGB_(&hue,&saturation,&value); DefineNamedColorRGB(name,hue,saturation,value);}/**************************************************************** * * Dealing with regular colors * ****************************************************************/ /* Defining a color using rgb values */void DefineColorRGB(int cm, int col,LWFLOAT red, LWFLOAT green, LWFLOAT blue){ COLOR color; CheckRGB(&red,&green,&blue); if (theColorMaps[cm] == NULL) Errorf("DefineColorRGB() : Undefined colormap index %d",cm); if (col >= theColorMaps[cm]->size) Errorf("DefineColorRGB() : Color index too large %d",col); /* Get the color */ color = &(theColorMaps[cm]->colors[col]); color->red = (unsigned short)red; color->blue = (unsigned short) blue; color->green = (unsigned short) green; color->pixel = 0; color->index = 0;}/* Defining a color using hsv values */void DefineColorHSV(int cm, int col,LWFLOAT hue, LWFLOAT saturation, LWFLOAT value){ CheckHSV(&hue,&saturation,&value); HSVToRGB_(&hue,&saturation,&value); DefineColorRGB(cm,col,hue,saturation,value);}/**************************************************************** * * Dealing with color maps * ****************************************************************/#define ColorMapMask 0xBF#define ColorMapInverseMask 0x40#define ColorMapShift 25/* Getting a colormap named "name" */static int GetColorMap(char *name){ int i; int n = nColorMaps; if (name == NULL) { if (theColorMaps[0] != NULL) return(0); return(-1); } if (*name == '_') Errorf("GetColorMap() : Weird error"); for (i=1;i<ColorMapNMax && n != 0;i++) { if (theColorMaps[i] == NULL) continue; if (!strcmp(name,theColorMaps[i]->name)) return(i); n--; } return(-1);} /* Deleting a colormap */static void DeleteColorMap(char *name){ int cm,i; if (name == NULL) return; cm = GetColorMap(name); if (cm == -1) Errorf("DeleteColorMap() : color map '%s' does not exist",name); if (theColorMaps[cm]->colors != NULL) { Free(theColorMaps[cm]->colors); theColorMaps[cm]->colors = NULL; } if (theColorMaps[cm]->name != NULL) Free(theColorMaps[cm]->name); Free(theColorMaps[cm]); theColorMaps[cm] = NULL; nColorMaps--; if (cm == (colorMapCur&ColorMapMask) && nColorMaps != 0) { for (i=1;i<ColorMapNMax;i++) { if (theColorMaps[i] != NULL) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -