diff options
author | Antti S. Lankila <alankila@bel.fi> | 2012-07-29 21:56:18 +0300 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-07-30 15:40:16 -0400 |
commit | a161a6ba2394aed68148304de83b8f2c185f4c32 (patch) | |
tree | a21ed26fb62a8e918f9316ebff5db66e8e70bd33 /demos | |
parent | 7460457f80b1482338318f0ddcdf5311659fae7b (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.am | 4 | ||||
-rw-r--r-- | demos/srgb-test.c | 96 |
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; +} |