Skip to content
Snippets Groups Projects
Commit a161a6ba authored by Antti S. Lankila's avatar Antti S. Lankila Committed by Søren Sandmann Pedersen
Browse files

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.
parent 7460457f
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
......@@ -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)
......
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment