diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | demos/Makefile.am | 4 | ||||
-rw-r--r-- | demos/srgb-test.c | 96 |
3 files changed, 100 insertions, 1 deletions
@@ -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; +} |