Fix pixbuf_from_argb32() to take premultiplied alpha into account
authorSøren Sandmann Pedersen <ssp@dhcp-100-2-40.bos.redhat.com>
Sat, 4 Apr 2009 10:04:42 +0000 (06:04 -0400)
committerSøren Sandmann Pedersen <ssp@dhcp-100-2-40.bos.redhat.com>
Sat, 4 Apr 2009 10:04:42 +0000 (06:04 -0400)
test/clip-test.c
test/composite-test.c
test/gradient-test.c

index 457e97a..4995083 100644 (file)
@@ -20,14 +20,27 @@ pixbuf_from_argb32 (uint32_t *bits,
        for (w = 0; w < width; ++w)
        {
            uint32_t argb = bits[h * stride + w];
-           guint32 abgr;
-           
-           abgr = (argb & 0xff000000) |
-               (argb & 0xff) << 16 |
-               (argb & 0x00ff00) |
-               (argb & 0xff0000) >> 16;
-           
-           p_bits[h * (p_stride / 4) + w] = abgr;
+           guint r, g, b, a;
+           char *pb = p_bits;
+
+           pb += h * p_stride + w * 4;
+
+           r = (argb & 0x00ff0000) >> 16;
+           g = (argb & 0x0000ff00) >> 8;
+           b = (argb & 0x000000ff) >> 0;
+           a = (argb & 0xff000000) >> 24;
+
+           if (a)
+           {
+               r = (r * 255) / a;
+               g = (g * 255) / a;
+               b = (b * 255) / a;
+           }
+
+           pb[0] = r;
+           pb[1] = g;
+           pb[2] = b;
+           pb[3] = a;
        }
     }
     
index d6596f4..388c8e6 100644 (file)
@@ -1,10 +1,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include "pixman.h"
-
 #include <gtk/gtk.h>
 
-static GdkPixbuf *
+GdkPixbuf *
 pixbuf_from_argb32 (uint32_t *bits,
                    int width,
                    int height,
@@ -15,20 +14,36 @@ pixbuf_from_argb32 (uint32_t *bits,
     int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
     guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
     int w, h;
-
+    
     for (h = 0; h < height; ++h)
     {
        for (w = 0; w < width; ++w)
        {
            uint32_t argb = bits[h * stride + w];
-           guint32 rgba;
-
-           rgba = (argb << 8) | (argb >> 24);
-
-           p_bits[h * (p_stride / 4) + w] = rgba;
+           guint r, g, b, a;
+           char *pb = p_bits;
+
+           pb += h * p_stride + w * 4;
+
+           r = (argb & 0x00ff0000) >> 16;
+           g = (argb & 0x0000ff00) >> 8;
+           b = (argb & 0x000000ff) >> 0;
+           a = (argb & 0xff000000) >> 24;
+
+           if (a)
+           {
+               r = (r * 255) / a;
+               g = (g * 255) / a;
+               b = (b * 255) / a;
+           }
+
+           pb[0] = r;
+           pb[1] = g;
+           pb[2] = b;
+           pb[3] = a;
        }
     }
-
+    
     return pixbuf;
 }
 
index 8a99ff0..806256b 100644 (file)
@@ -20,14 +20,27 @@ pixbuf_from_argb32 (uint32_t *bits,
        for (w = 0; w < width; ++w)
        {
            uint32_t argb = bits[h * stride + w];
-           guint32 abgr;
-           
-           abgr = (argb & 0xff000000) |
-               (argb & 0xff) << 16 |
-               (argb & 0x00ff00) |
-               (argb & 0xff0000) >> 16;
-           
-           p_bits[h * (p_stride / 4) + w] = abgr;
+           guint r, g, b, a;
+           char *pb = p_bits;
+
+           pb += h * p_stride + w * 4;
+
+           r = (argb & 0x00ff0000) >> 16;
+           g = (argb & 0x0000ff00) >> 8;
+           b = (argb & 0x000000ff) >> 0;
+           a = (argb & 0xff000000) >> 24;
+
+           if (a)
+           {
+               r = (r * 255) / a;
+               g = (g * 255) / a;
+               b = (b * 255) / a;
+           }
+
+           pb[0] = r;
+           pb[1] = g;
+           pb[2] = b;
+           pb[3] = a;
        }
     }