1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gshsb.c 8250 2007-09-25 13:31:24Z giles $ */
15
/* HSB color operators for Ghostscript library */
18
#include "gshsb.h" /* interface definition */
21
/* Forward references */
22
static void color_hsb_to_rgb(floatp h, floatp s, floatp b, float rgb[3]);
23
static void color_rgb_to_hsb(floatp r, floatp g, floatp b, float hsb[3]);
25
/* Force a parameter into the range [0.0..1.0]. */
26
#define force_unit(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p)
30
gs_sethsbcolor(gs_state * pgs, floatp h, floatp s, floatp b)
34
color_hsb_to_rgb(force_unit(h), force_unit(s), force_unit(b), rgb);
35
return gs_setrgbcolor(pgs, rgb[0], rgb[1], rgb[2]);
40
gs_currenthsbcolor(const gs_state * pgs, float pr3[3])
44
gs_currentrgbcolor(pgs, rgb);
45
color_rgb_to_hsb(rgb[0], rgb[1], rgb[2], pr3);
49
/* ------ Internal routines ------ */
51
/* Note: the color model conversion algorithms are taken from */
52
/* Rogers, Procedural Elements for Computer Graphics, pp. 401-403. */
54
/* Convert RGB to HSB. */
56
color_rgb_to_hsb(floatp r, floatp g, floatp b, float hsb[3])
58
frac red = float2frac(r), green = float2frac(g), blue = float2frac(b);
63
if (red == green && green == blue) {
64
rhue = 0; /* arbitrary */
66
rbri = r; /* pick any one */
67
} else { /* Convert rgb to hsb */
71
V = (red > green ? red : green);
74
Temp = (red > green ? green : red);
79
H = (green - blue) * frac_1_long / diff;
81
H = (blue - red) * frac_1_long / diff + 2 * frac_1_long;
83
H = (red - green) * frac_1_long / diff + 4 * frac_1_long;
86
rhue = H / (frac_1 * 6.0);
87
rsat = diff / (float)V;
95
/* Convert HSB to RGB. */
97
color_hsb_to_rgb(floatp hue, floatp saturation, floatp brightness, float rgb[3])
99
if (saturation == 0) {
100
rgb[0] = rgb[1] = rgb[2] = brightness;
101
} else { /* Convert hsb to rgb. */
102
/* We rely on the fact that the product of two */
103
/* fracs fits into an unsigned long. */
105
ulong V = float2frac(brightness); /* force arithmetic to long */
106
frac S = float2frac(saturation);
108
ulong F = float2frac(h6 - I); /* ditto */
110
/* M = V*(1-S), N = V*(1-S*F), K = V*(1-S*(1-F)) = M-N+V */
111
frac M = V * (frac_1_long - S) / frac_1_long;
112
frac N = V * (frac_1_long - S * F / frac_1_long) / frac_1_long;
148
rgb[0] = frac2float(R);
149
rgb[1] = frac2float(G);
150
rgb[2] = frac2float(B);
152
if (gs_debug_c('c')) {
153
dlprintf7("[c]hsb(%g,%g,%g)->VSFI(%ld,%d,%ld,%d)->\n",
154
hue, saturation, brightness, V, S, F, I);
155
dlprintf6(" RGB(%d,%d,%d)->rgb(%g,%g,%g)\n",
156
R, G, B, rgb[0], rgb[1], rgb[2]);