X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=color.h;h=bbb32852f8201995709db87e2eafa50be231f482;hb=bc662e293c854e1bdc9d46e9a410fe220247e6d4;hp=2c5bf8040cc2ee0ff7cbd9ecf7665902a930fdb0;hpb=e16cf0578f4baaf879e4ab9d3528a765bfd29be0;p=chaz%2Frasterize diff --git a/color.h b/color.h index 2c5bf80..bbb3285 100644 --- a/color.h +++ b/color.h @@ -64,6 +64,16 @@ color_t color_new(colorchan_t r, colorchan_t g, colorchan_t b, colorchan_t a) #define COLOR_WHITE color_new(S(1.0), S(1.0), S(1.0), S(1.0)) +/* + * Get a pointer to the color data. + */ +INLINE_MAYBE +const scal_t* color_data(const color_t* c) +{ + return &c->r; +} + + /* * Print the color to stdout. */ @@ -85,7 +95,7 @@ void color_print(color_t c) INLINE_MAYBE color_t color_add(color_t c1, color_t c2) { - return color_new(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b, c1.a + c2.a); + return color_new(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b, c1.a); } /* @@ -106,7 +116,6 @@ color_t color_mult(color_t c1, color_t c2) c1.r *= c2.r; c1.g *= c2.g; c1.b *= c2.b; - c1.a *= c2.a; return c1; } @@ -119,7 +128,6 @@ color_t color_scale(color_t c, scal_t k) c.r *= k; c.g *= k; c.b *= k; - c.a *= k; return c; } @@ -132,6 +140,15 @@ color_t color_scale2(color_t c1, color_t c2, scal_t k) return color_scale(color_mult(c1, c2), k); } +INLINE_MAYBE +color_t color_blend(color_t d, color_t s) +{ + d.r = (S(1.0) - s.a) * d.r + s.a * s.r; + d.g = (S(1.0) - s.a) * d.g + s.a * s.g; + d.b = (S(1.0) - s.a) * d.b + s.a * s.b; + return d; +} + /* * Clamp a color's channels to the normal range of 0.0 to 1.0. */ @@ -154,8 +171,7 @@ color_t color_interp(color_t c1, color_t c2, scal_t a) { return color_new(c1.r * (S(1.0) - a) + c2.r * a, c1.g * (S(1.0) - a) + c2.g * a, - c1.b * (S(1.0) - a) + c2.b * a, - c1.a * (S(1.0) - a) + c2.a * a); + c1.b * (S(1.0) - a) + c2.b * a, c1.a); } /* @@ -166,8 +182,7 @@ color_t color_interp2(color_t c1, color_t c2, color_t c3, scal_t b[3]) { return color_new(c1.r * b[0] + c2.r * b[1] + c3.r * b[2], c1.g * b[0] + c2.g * b[1] + c3.g * b[2], - c1.b * b[0] + c2.b * b[1] + c3.b * b[2], - S(1.0)); + c1.b * b[0] + c2.b * b[1] + c3.b * b[2], c1.a); } @@ -177,19 +192,6 @@ color_t color_interp2(color_t c1, color_t c2, color_t c3, scal_t b[3]) typedef uint8_t rgbachan_t; typedef uint32_t rgba_t; -/* - * Create a new color from a 32-bit RGBA value. - */ -INLINE_MAYBE -color_t color_from_rgba(rgba_t n) -{ - colorchan_t r = (colorchan_t)UNPACK(n, 3) / S(255.0); - colorchan_t g = (colorchan_t)UNPACK(n, 2) / S(255.0); - colorchan_t b = (colorchan_t)UNPACK(n, 1) / S(255.0); - colorchan_t a = (colorchan_t)UNPACK(n, 0) / S(255.0); - return color_new(r, g, b, a); -} - /* * Split a color into 8-bit RGBA channels. */ @@ -202,15 +204,40 @@ void color_split(color_t c, rgbachan_t* r, rgbachan_t* g, rgbachan_t* b, rgbacha if (a) *a = (rgbachan_t)(c.a * S(255.0)); } +/* + * Create a new color from a 32-bit RGBA value. + */ +INLINE_MAYBE +color_t color_from_rgba(rgba_t n) +{ + union { + rgba_t rgba; + struct { + rgbachan_t r, g, b, a; + } chan; + } u; + u.rgba = n; + colorchan_t r = (colorchan_t)u.chan.r / S(255.0); + colorchan_t g = (colorchan_t)u.chan.g / S(255.0); + colorchan_t b = (colorchan_t)u.chan.b / S(255.0); + colorchan_t a = (colorchan_t)u.chan.a / S(255.0); + return color_new(r, g, b, a); +} + /* * Convert a color to a 32-bit RGBA value. */ INLINE_MAYBE rgba_t rgba_from_color(color_t c) { - rgbachan_t r, g, b, a; - color_split(c, &r, &g, &b, &a); - return ((rgba_t)r << 24) | ((rgba_t)g << 16) | ((rgba_t)b << 8) | (rgba_t)a; + union { + rgba_t rgba; + struct { + rgbachan_t r, g, b, a; + } chan; + } u; + color_split(c, &u.chan.r, &u.chan.g, &u.chan.b, &u.chan.a); + return u.rgba; }