26a6390d2adf70c598652bc33183e5b15a421c23
[chaz/rasterize] / color.h
1
2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
7
8 #ifndef _COLOR_H_
9 #define _COLOR_H_
10
11 #include "common.h"
12
13
14 /*
15 * A color channel will be the same as a scalar.
16 */
17 typedef scal_t colorchan_t;
18
19 /*
20 * A color class.
21 * Colors are represented by RGBA values between 0.0 and 1.0.
22 */
23 struct color
24 {
25 colorchan_t r;
26 colorchan_t g;
27 colorchan_t b;
28 colorchan_t a;
29 };
30 typedef struct color color_t;
31
32 /*
33 * Initialize a color.
34 */
35 INLINE_MAYBE
36 void color_init(color_t* c, colorchan_t r, colorchan_t g, colorchan_t b, colorchan_t a)
37 {
38 c->r = r;
39 c->g = g;
40 c->b = b;
41 c->a = a;
42 }
43
44
45 /*
46 * Create a new color, copied by value.
47 */
48 INLINE_MAYBE
49 color_t color_new(colorchan_t r, colorchan_t g, colorchan_t b, colorchan_t a)
50 {
51 color_t c;
52 color_init(&c, r, g, b, a);
53 return c;
54 }
55
56 #define COLOR_CLEAR color_new(S(0.0), S(0.0), S(0.0), S(0.0))
57 #define COLOR_BLACK color_new(S(0.0), S(0.0), S(0.0), S(1.0))
58 #define COLOR_RED color_new(S(1.0), S(0.0), S(0.0), S(1.0))
59 #define COLOR_GREEN color_new(S(0.0), S(1.0), S(0.0), S(1.0))
60 #define COLOR_BLUE color_new(S(0.0), S(0.0), S(1.0), S(1.0))
61 #define COLOR_YELLOW color_new(S(1.0), S(1.0), S(0.0), S(1.0))
62 #define COLOR_MAGENTA color_new(S(1.0), S(0.0), S(1.0), S(1.0))
63 #define COLOR_CYAN color_new(S(0.0), S(1.0), S(1.0), S(1.0))
64 #define COLOR_WHITE color_new(S(1.0), S(1.0), S(1.0), S(1.0))
65
66
67 /*
68 * Print the color to stdout.
69 */
70 INLINE_MAYBE
71 void color_print(color_t c)
72 {
73 #if (SCALAR_SIZE == 8)
74 const char* fmt = "[ %9.5lf %9.5lf %9.5lf %9.5lf ]";
75 #else
76 const char* fmt = "[ %9.5f %9.5f %9.5f %9.5f ]";
77 #endif
78 printf(fmt, c.r, c.g, c.b, c.a);
79 }
80
81
82 /*
83 * Add two colors together. Color may need to be clamped afterward.
84 */
85 INLINE_MAYBE
86 color_t color_add(color_t c1, color_t c2)
87 {
88 return color_new(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b, c1.a + c2.a);
89 }
90
91 /*
92 * Add three colors together. Color may need to be clamped afterward.
93 */
94 INLINE_MAYBE
95 color_t color_add2(color_t c1, color_t c2, color_t c3)
96 {
97 return color_add(color_add(c1, c2), c3);
98 }
99
100 /*
101 * Clamp a color's channels to the normal range of 0.0 to 1.0.
102 */
103 INLINE_MAYBE
104 color_t color_clamp(color_t c)
105 {
106 c.r = scal_clamp(c.r, S(0.0), S(1.0));
107 c.g = scal_clamp(c.g, S(0.0), S(1.0));
108 c.b = scal_clamp(c.b, S(0.0), S(1.0));
109 c.a = scal_clamp(c.a, S(0.0), S(1.0));
110 return c;
111 }
112
113
114 /*
115 * Interpolate smoothly between two colors with an alpha value.
116 */
117 INLINE_MAYBE
118 color_t color_interp(color_t c1, color_t c2, scal_t a)
119 {
120 return color_new(c1.r * (S(1.0) - a) + c2.r * a,
121 c1.g * (S(1.0) - a) + c2.g * a,
122 c1.b * (S(1.0) - a) + c2.b * a,
123 c1.a * (S(1.0) - a) + c2.a * a);
124 }
125
126 /*
127 * Interpolate smoothly between three colors with barycentric coordinates.
128 */
129 INLINE_MAYBE
130 color_t color_interp2(color_t c1, color_t c2, color_t c3, scal_t b[3])
131 {
132 return color_new(c1.r * b[0] + c2.r * b[1] + c3.r * b[2],
133 c1.g * b[0] + c2.g * b[1] + c3.g * b[2],
134 c1.b * b[0] + c2.b * b[1] + c3.b * b[2],
135 S(1.0));
136 }
137
138
139 /*
140 * Define integer types for a 32-bit RGBA color representation.
141 */
142 typedef uint8_t rgbachan_t;
143 typedef uint32_t rgba_t;
144
145 /*
146 * Create a new color from a 32-bit RGBA value.
147 */
148 INLINE_MAYBE
149 color_t color_from_rgba(rgba_t n)
150 {
151 colorchan_t r = (colorchan_t)UNPACK(n, 3) / S(255.0);
152 colorchan_t g = (colorchan_t)UNPACK(n, 2) / S(255.0);
153 colorchan_t b = (colorchan_t)UNPACK(n, 1) / S(255.0);
154 colorchan_t a = (colorchan_t)UNPACK(n, 0) / S(255.0);
155 return color_new(r, g, b, a);
156 }
157
158 /*
159 * Split a color into 8-bit RGBA channels.
160 */
161 INLINE_MAYBE
162 void color_split(color_t c, rgbachan_t* r, rgbachan_t* g, rgbachan_t* b, rgbachan_t* a)
163 {
164 if (r) *r = (rgbachan_t)(c.r * S(255.0));
165 if (g) *g = (rgbachan_t)(c.g * S(255.0));
166 if (b) *b = (rgbachan_t)(c.b * S(255.0));
167 if (a) *a = (rgbachan_t)(c.a * S(255.0));
168 }
169
170 /*
171 * Convert a color to a 32-bit RGBA value.
172 */
173 INLINE_MAYBE
174 rgba_t rgba_from_color(color_t c)
175 {
176 rgbachan_t r, g, b, a;
177 color_split(c, &r, &g, &b, &a);
178 return ((rgba_t)r << 24) | ((rgba_t)g << 16) | ((rgba_t)b << 8) | (rgba_t)a;
179 }
180
181
182 #endif // _COLOR_H_
183
This page took 0.050083 seconds and 3 git commands to generate.