1 /* Copyright (C) 1992-1998 The Geometry Center
2  * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3  *
4  * This file is part of Geomview.
5  *
6  * Geomview is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Geomview is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Geomview; see the file COPYING.  If not, write
18  * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19  * USA, or visit http://www.gnu.org.
20  */
21 
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25 
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30 
31 /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
32 
33 #include "color.h"
34 #include <stdlib.h>
35 
36 void
CoPrint(Color * c)37 CoPrint( Color *c )
38 {
39   (void)c;
40 }
41 
42 void
CoCopy(Color * c1,Color * c2)43 CoCopy( Color *c1, Color *c2 )
44 {
45     *c2 = *c1;
46 }
47 
48 void
CoACopy(ColorA * c1,ColorA * c2)49 CoACopy( ColorA *c1, ColorA *c2 )
50 {
51     *c2 = *c1;
52 }
53 
54 void
CoFrom(Color * c,float r,float g,float b)55 CoFrom( Color *c, float r, float g, float b )
56 {
57     c->r = r;
58     c->g = g;
59     c->b = b;
60 }
61 
62 void
CoAdd(Color * c1,Color * c2,Color * c3)63 CoAdd( Color *c1,Color *c2, Color *c3 )
64 {
65     c3->r = c1->r + c2->r;
66     c3->g = c1->g + c2->g;
67     c3->b = c1->b + c2->b;
68 }
69 
70 void
CoSub(Color * c1,Color * c2,Color * c3)71 CoSub( Color *c1, Color *c2, Color *c3 )
72 {
73     c3->r = c1->r - c2->r;
74     c3->g = c1->g - c2->g;
75     c3->b = c1->b - c2->b;
76 }
77 void
CoFilter(Color * c1,Color * c2,Color * c3)78 CoFilter( Color *c1, Color *c2, Color *c3 )
79 {
80     c3->r = c1->r * c2->r;
81     c3->g = c1->g * c2->g;
82     c3->b = c1->b * c2->b;
83 }
84 
85 
86 #define vH (hsv->r)
87 #define vS (hsv->g)
88 #define vV (hsv->b)
89 
90 /* HSV to RGB conversion from Ken Fishkin, pixar!fishkin */
hsv2rgb(Color * hsv,Color * rgb)91 void hsv2rgb(Color *hsv, Color *rgb)
92 {
93     float h = 6.0 * (vH < 0 ? vH + (1 - (int)vH) : vH - (int)vH);
94     int sextant = (int) h; /* implicit floor */
95     float fract = h - sextant;
96     float vsf = vS*vV*fract;
97     float min = (1-vS)*vV;
98     float mid1 = min + vsf;
99     float mid2 = vV - vsf;
100     switch (sextant%6) {
101     case 0: rgb->r = vV;   rgb->g = mid1; rgb->b = min; break;
102     case 1: rgb->r = mid2; rgb->g = vV;	  rgb->b = min; break;
103     case 2: rgb->r = min;  rgb->g = vV;	  rgb->b = mid1; break;
104     case 3: rgb->r = min;  rgb->g = mid2; rgb->b = vV; break;
105     case 4: rgb->r = mid1; rgb->g = min;  rgb->b = vV; break;
106     case 5: rgb->r = vV;   rgb->g = min;  rgb->b = mid2; break;
107     }
108 }
109 
rgb2hsv(Color * rgb,Color * hsv)110 void rgb2hsv(Color *rgb, Color *hsv)
111 {
112 
113 #define cRGB (&rgb->r)
114 
115     int min, max;
116     float dv;
117     if(cRGB[0] < cRGB[1])
118 	min = 0, max = 1;
119     else
120 	min = 1, max = 0;
121     if(cRGB[min] > cRGB[2]) min = 2;
122     else if(cRGB[max] < cRGB[2]) max = 2;
123 
124     vV = cRGB[max];
125     dv = cRGB[max] - cRGB[min];
126     if(dv == 0) {
127 	vH = 0;	/* hue undefined, use 0 */
128 	vS = 0;
129     } else {
130 	float dh = (cRGB[3 - max - min] - cRGB[min]) / (6*dv);
131 	vH = (3+max-min)%3==1 ? max/3.0 + dh : max/3.0 - dh;
132 	if(vH < 0) vH += 1 + (int)vH;
133 	if(vH > 1) vH -= (int)vH;
134 	vS = dv / cRGB[max];
135     }
136 }
137