summaryrefslogtreecommitdiff
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
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.
-rw-r--r--.gitignore1
-rw-r--r--demos/Makefile.am4
-rw-r--r--demos/srgb-test.c96
3 files changed, 100 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 3cdf3c1..a4d9f99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@ demos/gradient-test
demos/quad2quad
demos/radial-test
demos/screen-test
+demos/srgb-test
demos/trap-test
demos/tri-test
pixman/pixman-combine32.c
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;
+}