summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2011-05-20 22:16:51 -0600
committerTavian Barnes <tavianator@gmail.com>2011-05-20 22:16:51 -0600
commit07d784563af19c162945c60562819269e6fc4994 (patch)
treea37e984d281c1fccb5a4cdbe7b86defa16d04091
parent18b89c6edc29a009b1419e6d34bc3eef2dd911b9 (diff)
downloaddimension-07d784563af19c162945c60562819269e6fc4994.tar.xz
Calculate alpha correctly for canvas exports.
-rw-r--r--libdimension/color.c13
-rw-r--r--libdimension/dimension/color.h2
-rw-r--r--libdimension/gl.c4
-rw-r--r--libdimension/png.c3
4 files changed, 19 insertions, 3 deletions
diff --git a/libdimension/color.c b/libdimension/color.c
index 07d8ed8..6de8d0a 100644
--- a/libdimension/color.c
+++ b/libdimension/color.c
@@ -200,6 +200,19 @@ dmnsn_apply_filter(dmnsn_color color, dmnsn_color filter)
return dmnsn_apply_translucency(dmnsn_filter_light(color, filter), filter);
}
+/* Remove the filter channel */
+dmnsn_color
+dmnsn_remove_filter(dmnsn_color color)
+{
+ double intensity = dmnsn_color_intensity(color);
+ double newtrans = (1.0 - (1.0 - intensity)*color.filter)*color.trans;
+ if (1.0 - newtrans >= dmnsn_epsilon)
+ color = dmnsn_color_mul((1.0 - color.trans)/(1.0 - newtrans), color);
+ color.trans = newtrans;
+ color.filter = 0.0;
+ return color;
+}
+
/* Illuminates `color' with `light' */
dmnsn_color
dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color)
diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h
index be5dc3d..98d1530 100644
--- a/libdimension/dimension/color.h
+++ b/libdimension/dimension/color.h
@@ -91,5 +91,7 @@ dmnsn_color dmnsn_filter_light(dmnsn_color light, dmnsn_color filter);
dmnsn_color dmnsn_apply_translucency(dmnsn_color filtered, dmnsn_color filter);
/** Add the background contribution of \p color to \p filter. */
dmnsn_color dmnsn_apply_filter(dmnsn_color color, dmnsn_color filter);
+/** Convert the color into a close equivalent with only transmittance. */
+dmnsn_color dmnsn_remove_filter(dmnsn_color color);
/** Illuminate \p color with \p light. */
dmnsn_color dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color);
diff --git a/libdimension/gl.c b/libdimension/gl.c
index 7fd3cb9..f5f1c92 100644
--- a/libdimension/gl.c
+++ b/libdimension/gl.c
@@ -82,7 +82,7 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas)
for (size_t x = 0; x < width; ++x) {
pixel = pixels + 4*(y*width + x);
- color = dmnsn_get_pixel(canvas, x, y);
+ color = dmnsn_remove_filter(dmnsn_get_pixel(canvas, x, y));
/* Saturate R, G, and B to [0, UINT16_MAX] */
@@ -167,7 +167,7 @@ dmnsn_gl_optimizer_fn(const dmnsn_canvas *canvas,
dmnsn_canvas_optimizer optimizer, size_t x, size_t y)
{
GLushort *pixel = (GLushort *)optimizer.ptr + 4*(y*canvas->width + x);
- dmnsn_color color = dmnsn_get_pixel(canvas, x, y);
+ dmnsn_color color = dmnsn_remove_filter(dmnsn_get_pixel(canvas, x, y));
/* Saturate R, G, and B to [0, UINT16_MAX] */
diff --git a/libdimension/png.c b/libdimension/png.c
index 3920e7e..5b7f625 100644
--- a/libdimension/png.c
+++ b/libdimension/png.c
@@ -64,7 +64,7 @@ dmnsn_png_optimizer_fn(const dmnsn_canvas *canvas,
dmnsn_color color;
uint16_t *pixel = (uint16_t *)optimizer.ptr + 4*(y*canvas->width + x);
- color = dmnsn_get_pixel(canvas, x, y);
+ color = dmnsn_remove_filter(dmnsn_get_pixel(canvas, x, y));
/* Saturate R, G, and B to [0, UINT16_MAX] */
@@ -271,6 +271,7 @@ dmnsn_png_write_canvas_thread(void *ptr)
for (size_t x = 0; x < width; ++x) {
/* Invert the rows. PNG coordinates are fourth quadrant. */
dmnsn_color color = dmnsn_get_pixel(payload->canvas, x, height - y - 1);
+ color = dmnsn_remove_filter(color);
/* Saturate R, G, and B to [0, UINT16_MAX] */