diff options
author | Darin Adler <darin@src.gnome.org> | 2000-05-05 02:50:24 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2000-05-05 02:50:24 +0000 |
commit | 0f038c9e320c4ef3306e17b136c39909cd7baa57 (patch) | |
tree | e10f49d7c4d6b09a872989c28f0da091d207a104 | |
parent | 24fa8a64bcd200b1c2f15ffb9d8d5c34e279601f (diff) | |
download | gtk+-0f038c9e320c4ef3306e17b136c39909cd7baa57.tar.gz |
Now that Owen explained the algorithm, I think I implemented it right for
* gdk-pixbuf/pixops/pixops.c: (pixops_composite_nearest),
(composite_pixel), (composite_line):
* gdk-pixbuf/test-gdk-pixbuf.c: (simple_composite_test_one_type):
Now that Owen explained the algorithm, I think I implemented it
right for the cases where the destination pixbuf is not opaque.
The test does seem to confirm it.
-rw-r--r-- | gdk-pixbuf/ChangeLog | 9 | ||||
-rw-r--r-- | gdk-pixbuf/pixops/pixops.c | 66 | ||||
-rw-r--r-- | gdk-pixbuf/test-gdk-pixbuf.c | 3 |
3 files changed, 63 insertions, 15 deletions
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index d41d8e664f..5f7ef08437 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,5 +1,14 @@ 2000-05-04 Darin Adler <darin@eazel.com> + * gdk-pixbuf/pixops/pixops.c: (pixops_composite_nearest), + (composite_pixel), (composite_line): + * gdk-pixbuf/test-gdk-pixbuf.c: (simple_composite_test_one_type): + Now that Owen explained the algorithm, I think I implemented it + right for the cases where the destination pixbuf is not opaque. + The test does seem to confirm it. + +2000-05-04 Darin Adler <darin@eazel.com> + * gdk-pixbuf/.cvsignore: * gdk-pixbuf/Makefile.am: * gdk-pixbuf/test-gdk-pixbuf.c (store_pixel), (fill_with_pixel), diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c index 00652d5c67..ae0ff5ee7c 100644 --- a/gdk-pixbuf/pixops/pixops.c +++ b/gdk-pixbuf/pixops/pixops.c @@ -177,10 +177,24 @@ pixops_composite_nearest (guchar *dest_buf, if (dest_has_alpha) { - dest[0] = (a0 * src[0] + (0xff - a0) * dest[0]) / 0xff; - dest[1] = (a0 * src[1] + (0xff - a0) * dest[1]) / 0xff; - dest[2] = (a0 * src[2] + (0xff - a0) * dest[2]) / 0xff; - dest[3] = (0xff * a0 + (0xff - a0) * dest[3]) / 0xff; + unsigned int w0 = 0xff * a0; + unsigned int w1 = (0xff - a0) * dest[3]; + unsigned int w = w0 + w1; + + if (w != 0) + { + dest[0] = (w0 * src[0] + w1 * dest[0]) / w; + dest[1] = (w0 * src[1] + w1 * dest[1]) / w; + dest[2] = (w0 * src[2] + w1 * dest[2]) / w; + dest[3] = w / 0xff; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } } else { @@ -296,12 +310,24 @@ composite_pixel (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha { if (dest_has_alpha) { - unsigned int w = (0xff0000 - a) * dest[3]; + unsigned int w0 = a - (a >> 8); + unsigned int w1 = ((0xff0000 - a) >> 8) * dest[3]; + unsigned int w = w0 + w1; - dest[0] = (r + (0xff0000 - a) * dest[0]) / 0xff0000; - dest[1] = (g + (0xff0000 - a) * dest[1]) / 0xff0000; - dest[2] = (b + (0xff0000 - a) * dest[2]) / 0xff0000; - dest[3] = (0xff * a + (0xff0000 - a) * dest[3]) / 0xff0000; + if (w != 0) + { + dest[0] = (r - (r >> 8) + w1 * dest[0]) / w; + dest[1] = (g - (g >> 8) + w1 * dest[1]) / w; + dest[2] = (b - (b >> 8) + w1 * dest[2]) / w; + dest[3] = w / 0xff00; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } } else { @@ -354,12 +380,24 @@ composite_line (int *weights, int n_x, int n_y, if (dest_has_alpha) { - unsigned int w = (0xff0000 - a) * dest[3]; + unsigned int w0 = a - (a >> 8); + unsigned int w1 = ((0xff0000 - a) >> 8) * dest[3]; + unsigned int w = w0 + w1; - dest[0] = (r + (0xff0000 - a) * dest[0]) / 0xff0000; - dest[1] = (g + (0xff0000 - a) * dest[1]) / 0xff0000; - dest[2] = (b + (0xff0000 - a) * dest[2]) / 0xff0000; - dest[3] = (0xff * a + (0xff0000 - a) * dest[3]) / 0xff0000; + if (w != 0) + { + dest[0] = (r - (r >> 8) + w1 * dest[0]) / w; + dest[1] = (g - (g >> 8) + w1 * dest[1]) / w; + dest[2] = (b - (b >> 8) + w1 * dest[2]) / w; + dest[3] = w / 0xff00; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } } else { diff --git a/gdk-pixbuf/test-gdk-pixbuf.c b/gdk-pixbuf/test-gdk-pixbuf.c index b75f2e65e1..c4e22d1c4b 100644 --- a/gdk-pixbuf/test-gdk-pixbuf.c +++ b/gdk-pixbuf/test-gdk-pixbuf.c @@ -201,7 +201,8 @@ simple_composite_test_one_type (GdkInterpType type) success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFF0000FF, TRUE, 0xFF0000FF); success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00FF00FF, TRUE, 0x00FF00FF); success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x0000FFFF, TRUE, 0x0000FFFF); - success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF00, TRUE, 0x7FFF7F80); + success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF00, TRUE, 0x00FF0080); + success &= simple_composite_test_one (type, 0xFF000080, TRUE, 0x00FF0040, TRUE, 0xCC32009F); success &= simple_composite_test_one (type, 0xFFFFFFFF, TRUE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF); return success; |