summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2007-01-12 18:32:10 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-01-22 14:26:14 +1100
commit7aaf0c93b6030b9789ae481a9a6d1155a9f74ec1 (patch)
tree010df1b67df34d5b9c3e7a4840b10817717ad884
parentc48266b56e7da69fe94785b62ac275517cf33f97 (diff)
Premultiply alpha channel on PNG images
libtwin expects pixmaps to be premultiplied with their alpha channel, but loaded PNGs aren't. This change adds a generic function to do alpha premulitplication, and uses it on pixmaps loaded from PNG. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--libtwin/twin.h2
-rw-r--r--libtwin/twin_draw.c24
-rw-r--r--libtwin/twin_png.c3
3 files changed, 29 insertions, 0 deletions
diff --git a/libtwin/twin.h b/libtwin/twin.h
index 065cdc9..04a9ac6 100644
--- a/libtwin/twin.h
+++ b/libtwin/twin.h
@@ -647,6 +647,8 @@ twin_fill (twin_pixmap_t *dst,
twin_coord_t right,
twin_coord_t bottom);
+void
+twin_premultiply_alpha (twin_pixmap_t *px);
/*
* twin_cursor.c
*/
diff --git a/libtwin/twin_draw.c b/libtwin/twin_draw.c
index 1c117a0..3b19984 100644
--- a/libtwin/twin_draw.c
+++ b/libtwin/twin_draw.c
@@ -641,6 +641,30 @@ void twin_composite (twin_pixmap_t *dst,
operator, width, height);
}
+void twin_premultiply_alpha(twin_pixmap_t *px)
+{
+ int x, y;
+ twin_pointer_t p;
+ uint16_t t1, t2, t3;
+
+ if (px->format != TWIN_ARGB32)
+ return;
+
+ for (y = 0; y < px->height; y++) {
+ p.b = px->p.b + y * px->stride;
+
+ for (x = 0; x < px->width; x++) {
+ twin_argb32_t v = p.argb32[x];
+ twin_a8_t a = twin_get_8(v, 24);
+
+ p.argb32[x] = (v & 0xff000000) |
+ twin_int_mult(twin_get_8(v, 16), a, t1) << 16 |
+ twin_int_mult(twin_get_8(v, 8), a, t2) << 8 |
+ twin_int_mult(twin_get_8(v, 0), a, t3);
+ }
+ }
+}
+
/*
* array primary index is OVER SOURCE
* array secondary index is ARGB32 RGB16 A8
diff --git a/libtwin/twin_png.c b/libtwin/twin_png.c
index afe492a..05bbd04 100644
--- a/libtwin/twin_png.c
+++ b/libtwin/twin_png.c
@@ -172,6 +172,9 @@ twin_pixmap_t *twin_png_to_pixmap(const char *filepath, twin_format_t fmt)
png_read_end(png, NULL);
+ if (fmt == TWIN_ARGB32)
+ twin_premultiply_alpha(pix);
+
fail_free:
if (rowp)
free(rowp);