Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1994, 1997, 1998 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gshsb.c,v 1.5 2002/06/16 05:48:55 lpd Exp $ */
18
/* HSB color operators for Ghostscript library */
19
#include "gx.h"
20
#include "gscolor.h"
21
#include "gshsb.h"		/* interface definition */
22
#include "gxfrac.h"
23
 
24
/* Forward references */
25
private void color_hsb_to_rgb(floatp h, floatp s, floatp b, float rgb[3]);
26
private void color_rgb_to_hsb(floatp r, floatp g, floatp b, float hsb[3]);
27
 
28
/* Force a parameter into the range [0.0..1.0]. */
29
#define force_unit(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p)
30
 
31
/* sethsbcolor */
32
int
33
gs_sethsbcolor(gs_state * pgs, floatp h, floatp s, floatp b)
34
{
35
    float rgb[3];
36
 
37
    color_hsb_to_rgb(force_unit(h), force_unit(s), force_unit(b), rgb);
38
    return gs_setrgbcolor(pgs, rgb[0], rgb[1], rgb[2]);
39
}
40
 
41
/* currenthsbcolor */
42
int
43
gs_currenthsbcolor(const gs_state * pgs, float pr3[3])
44
{
45
    float rgb[3];
46
 
47
    gs_currentrgbcolor(pgs, rgb);
48
    color_rgb_to_hsb(rgb[0], rgb[1], rgb[2], pr3);
49
    return 0;
50
}
51
 
52
/* ------ Internal routines ------ */
53
 
54
/* Note: the color model conversion algorithms are taken from */
55
/* Rogers, Procedural Elements for Computer Graphics, pp. 401-403. */
56
 
57
/* Convert RGB to HSB. */
58
private void
59
color_rgb_to_hsb(floatp r, floatp g, floatp b, float hsb[3])
60
{
61
    frac red = float2frac(r), green = float2frac(g), blue = float2frac(b);
62
 
63
#define rhue hsb[0]
64
#define rsat hsb[1]
65
#define rbri hsb[2]
66
    if (red == green && green == blue) {
67
	rhue = 0;		/* arbitrary */
68
	rsat = 0;
69
	rbri = r;		/* pick any one */
70
    } else {			/* Convert rgb to hsb */
71
	frac V, Temp, diff;
72
	long H;
73
 
74
	V = (red > green ? red : green);
75
	if (blue > V)
76
	    V = blue;
77
	Temp = (red > green ? green : red);
78
	if (blue < Temp)
79
	    Temp = blue;
80
	diff = V - Temp;
81
	if (V == red)
82
	    H = (green - blue) * frac_1_long / diff;
83
	else if (V == green)
84
	    H = (blue - red) * frac_1_long / diff + 2 * frac_1_long;
85
	else			/* V == blue */
86
	    H = (red - green) * frac_1_long / diff + 4 * frac_1_long;
87
	if (H < 0)
88
	    H += 6 * frac_1_long;
89
	rhue = H / (frac_1 * 6.0);
90
	rsat = diff / (float)V;
91
	rbri = frac2float(V);
92
    }
93
#undef rhue
94
#undef rsat
95
#undef rbri
96
}
97
 
98
/* Convert HSB to RGB. */
99
private void
100
color_hsb_to_rgb(floatp hue, floatp saturation, floatp brightness, float rgb[3])
101
{
102
    if (saturation == 0) {
103
	rgb[0] = rgb[1] = rgb[2] = brightness;
104
    } else {			/* Convert hsb to rgb. */
105
	/* We rely on the fact that the product of two */
106
	/* fracs fits into an unsigned long. */
107
	floatp h6 = hue * 6;
108
	ulong V = float2frac(brightness);	/* force arithmetic to long */
109
	frac S = float2frac(saturation);
110
	int I = (int)h6;
111
	ulong F = float2frac(h6 - I);	/* ditto */
112
 
113
	/* M = V*(1-S), N = V*(1-S*F), K = V*(1-S*(1-F)) = M-N+V */
114
	frac M = V * (frac_1_long - S) / frac_1_long;
115
	frac N = V * (frac_1_long - S * F / frac_1_long) / frac_1_long;
116
	frac K = M - N + V;
117
	frac R, G, B;
118
 
119
	switch (I) {
120
	    default:
121
		R = V;
122
		G = K;
123
		B = M;
124
		break;
125
	    case 1:
126
		R = N;
127
		G = V;
128
		B = M;
129
		break;
130
	    case 2:
131
		R = M;
132
		G = V;
133
		B = K;
134
		break;
135
	    case 3:
136
		R = M;
137
		G = N;
138
		B = V;
139
		break;
140
	    case 4:
141
		R = K;
142
		G = M;
143
		B = V;
144
		break;
145
	    case 5:
146
		R = V;
147
		G = M;
148
		B = N;
149
		break;
150
	}
151
	rgb[0] = frac2float(R);
152
	rgb[1] = frac2float(G);
153
	rgb[2] = frac2float(B);
154
#ifdef DEBUG
155
	if (gs_debug_c('c')) {
156
	    dlprintf7("[c]hsb(%g,%g,%g)->VSFI(%ld,%d,%ld,%d)->\n",
157
		      hue, saturation, brightness, V, S, F, I);
158
	    dlprintf6("   RGB(%d,%d,%d)->rgb(%g,%g,%g)\n",
159
		      R, G, B, rgb[0], rgb[1], rgb[2]);
160
	}
161
#endif
162
    }
163
}