summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorAntti S. Lankila <alankila@bel.fi>2012-07-29 21:56:18 +0300
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-07-30 15:40:16 -0400
commita161a6ba2394aed68148304de83b8f2c185f4c32 (patch)
treea21ed26fb62a8e918f9316ebff5db66e8e70bd33 /demos
parent7460457f80b1482338318f0ddcdf5311659fae7b (diff)
Add sRGB blending demo program
Simple sRGB color blender test can be used to determine if the sRGB processing works as expected. It blends alpha ramps of purple and green together such that at midpoint of image, 50 % blend of both is realized. At that point, sRGB-aware processing yields a result close to #bbb rather than #888, which is the linear light blending result. The demo also contains the sample computation for sRGB premultiplied alpha.
Diffstat (limited to 'demos')
-rw-r--r--demos/Makefile.am4
-rw-r--r--demos/srgb-test.c96
2 files changed, 99 insertions, 1 deletions
diff --git a/demos/Makefile.am b/demos/Makefile.am
index 9aac1f5..d8fb0da 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -20,7 +20,8 @@ DEMOS = \
trap-test \
tri-test \
quad2quad \
- checkerboard
+ checkerboard \
+ srgb-test
EXTRA_DIST = parrot.c parrot.jpg
@@ -35,6 +36,7 @@ convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
radial_test_SOURCES = radial-test.c $(GTK_UTILS)
tri_test_SOURCES = tri-test.c $(GTK_UTILS)
checkerboard_SOURCES = checkerboard.c $(GTK_UTILS)
+srgb_test_SOURCES = srgb-test.c $(GTK_UTILS)
noinst_PROGRAMS = $(DEMOS)
diff --git a/demos/srgb-test.c b/demos/srgb-test.c
new file mode 100644
index 0000000..bc07349
--- /dev/null
+++ b/demos/srgb-test.c
@@ -0,0 +1,96 @@
+#include <math.h>
+
+#include "pixman.h"
+#include "gtk-utils.h"
+
+static uint32_t
+linear_argb_to_premult_argb (float a,
+ float r,
+ float g,
+ float b)
+{
+ r *= a;
+ g *= a;
+ b *= a;
+ return (uint32_t) (a * 255.0f + 0.5f) << 24
+ | (uint32_t) (r * 255.0f + 0.5f) << 16
+ | (uint32_t) (g * 255.0f + 0.5f) << 8
+ | (uint32_t) (b * 255.0f + 0.5f) << 0;
+}
+
+static float
+lin2srgb (float linear)
+{
+ if (linear < 0.0031308f)
+ return linear * 12.92f;
+ else
+ return 1.055f * powf (linear, 1.0f/2.4f) - 0.055f;
+}
+
+static uint32_t
+linear_argb_to_premult_srgb_argb (float a,
+ float r,
+ float g,
+ float b)
+{
+ r = lin2srgb (r * a);
+ g = lin2srgb (g * a);
+ b = lin2srgb (b * a);
+ return (uint32_t) (a * 255.0f + 0.5f) << 24
+ | (uint32_t) (r * 255.0f + 0.5f) << 16
+ | (uint32_t) (g * 255.0f + 0.5f) << 8
+ | (uint32_t) (b * 255.0f + 0.5f) << 0;
+}
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 400
+#define HEIGHT 200
+ int y, x, p;
+ float alpha;
+
+ uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
+ uint32_t *src1 = malloc (WIDTH * HEIGHT * 4);
+ pixman_image_t *dest_img, *src1_img;
+
+ dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8_sRGB,
+ WIDTH, HEIGHT,
+ dest,
+ WIDTH * 4);
+ src1_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+ WIDTH, HEIGHT,
+ src1,
+ WIDTH * 4);
+
+ for (y = 0; y < HEIGHT; y ++)
+ {
+ p = WIDTH * y;
+ for (x = 0; x < WIDTH; x ++)
+ {
+ alpha = (float) x / WIDTH;
+ src1[p + x] = linear_argb_to_premult_argb (alpha, 1, 0, 1);
+ dest[p + x] = linear_argb_to_premult_srgb_argb (1-alpha, 0, 1, 0);
+ }
+ }
+
+ pixman_image_composite (PIXMAN_OP_ADD, src1_img, NULL, dest_img,
+ 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+ pixman_image_unref (src1_img);
+ free (src1);
+
+ pixman_image_unref (dest_img);
+
+ /* Now that the picture has been correctly constructed,
+ * we hand it over to our support library as argb which it
+ * knows how to handle (it doesn't understand _sRGB format). */
+ dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+ WIDTH, HEIGHT,
+ dest,
+ WIDTH * 4);
+ show_image (dest_img);
+ pixman_image_unref (dest_img);
+ free (dest);
+
+ return 0;
+}