implement fountain fills similar to most paint programs
[imager.git] / color.c
CommitLineData
6607600c
TC
1#include "image.h"
2
3/*
4=head1 NAME
5
6color.c - color manipulation functions
7
8=head1 SYNOPSIS
9
10 i_fcolor color;
11 i_rgb_to_hsvf(&color);
12 i_hsv_to_rgbf(&color);
13
14=head1 DESCRIPTION
15
16A collection of utility functions for converting between color spaces.
17
18*/
19
20#define EPSILON (1e-8)
21
22/*
23=item i_rgb2hsvf(&color)
24
25Converts the first 3 channels of color into hue, saturation and value.
26
27Each value is scaled into the range 0 to 1.0.
28
29=cut
30*/
31void i_rgb_to_hsvf(i_fcolor *color) {
32 double h, s, v;
33 double temp;
34 double Cr, Cg, Cb;
35
36 v = max(max(color->rgb.r, color->rgb.g), color->rgb.b);
37 temp = min(min(color->rgb.r, color->rgb.g), color->rgb.b);
38 if (v < EPSILON)
39 s = 0;
40 else
41 s = (v-temp)/v;
42 if (s == 0)
43 h = 0;
44 else {
45 Cr = (v - color->rgb.r)/(v-temp);
46 Cg = (v - color->rgb.g)/(v-temp);
47 Cb = (v - color->rgb.b)/(v-temp);
48 if (color->rgb.r == v)
49 h = Cb - Cg;
50 else if (color->rgb.g == v)
51 h = 2 + Cr - Cb;
52 else if (color->rgb.b == v)
53 h = 4 + Cg - Cr;
54 h = 60 * h;
55 if (h < 0)
56 h += 360;
57 }
58 color->channel[0] = h / 360.0;
59 color->channel[1] = s;
60 color->channel[2] = v;
61}
62
63/*
64=item i_hsv_to_rgbf(&color)
65
66Convert a HSV value to an RGB value, each value ranges from 0 to 1.
67
68=cut
69*/
70
71void i_hsv_to_rgbf(i_fcolor *color) {
72 double h = color->channel[0];
73 double s = color->channel[1];
74 double v = color->channel[2];
75
76 if (color->channel[1] < EPSILON) {
77 /* ignore h in this case */
78 color->rgb.r = color->rgb.g = color->rgb.b = v;
79 }
80 else {
81 int i;
82 double f, m, n, k;
83 h = fmod(h, 1.0) * 6;
84 i = h;
85 f = h - i;
86 m = v * (1 - s);
87 n = v * (1 - s * f);
88 k = v * (1 - s * (1 - f));
89 switch (i) {
90 case 0:
91 color->rgb.r = v; color->rgb.g = k; color->rgb.b = m;
92 break;
93 case 1:
94 color->rgb.r = n; color->rgb.g = v; color->rgb.b = m;
95 break;
96 case 2:
97 color->rgb.r = m; color->rgb.g = v; color->rgb.b = k;
98 break;
99 case 3:
100 color->rgb.r = m; color->rgb.g = n; color->rgb.b = v;
101 break;
102 case 4:
103 color->rgb.r = k; color->rgb.g = m; color->rgb.b = v;
104 break;
105 case 5:
106 color->rgb.r = v; color->rgb.g = m; color->rgb.b = n;
107 break;
108 }
109 }
110}
111
112/*
113=back
114
115=head1 AUTHOR
116
117Tony Cook <tony@develop-help.com>
118
119=head1 SEE ALSO
120
121Imager
122
123=cut
124*/