X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=color.h;h=bbb32852f8201995709db87e2eafa50be231f482;hb=bc662e293c854e1bdc9d46e9a410fe220247e6d4;hp=26a6390d2adf70c598652bc33183e5b15a421c23;hpb=c875478cdd823c7df8fdc859941bd9e5948c9315;p=chaz%2Frasterize diff --git a/color.h b/color.h index 26a6390..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. */ @@ -80,16 +90,16 @@ void color_print(color_t c) /* - * Add two colors together. Color may need to be clamped afterward. + * Add two colors together. */ 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); } /* - * Add three colors together. Color may need to be clamped afterward. + * Add three colors together. */ INLINE_MAYBE color_t color_add2(color_t c1, color_t c2, color_t c3) @@ -97,6 +107,48 @@ color_t color_add2(color_t c1, color_t c2, color_t c3) return color_add(color_add(c1, c2), c3); } +/* + * Multiply two colors together. + */ +INLINE_MAYBE +color_t color_mult(color_t c1, color_t c2) +{ + c1.r *= c2.r; + c1.g *= c2.g; + c1.b *= c2.b; + return c1; +} + +/* + * Scale a color by some scalar coefficient. + */ +INLINE_MAYBE +color_t color_scale(color_t c, scal_t k) +{ + c.r *= k; + c.g *= k; + c.b *= k; + return c; +} + +/* + * Scale a color by another color and some scalar coefficient. + */ +INLINE_MAYBE +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. */ @@ -119,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); } /* @@ -131,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); } @@ -142,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. */ @@ -167,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; }