11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <math.h>
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman.h"
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "gtk-utils.h"
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t
71176bdada62cabc6ec4b0308a930e83b679d5d36John Recklinear_argb_to_premult_argb (float a,
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			     float r,
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			     float g,
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			     float b)
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    r *= a;
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    g *= a;
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    b *= a;
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return (uint32_t) (a * 255.0f + 0.5f) << 24
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 | (uint32_t) (r * 255.0f + 0.5f) << 16
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 | (uint32_t) (g * 255.0f + 0.5f) <<  8
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 | (uint32_t) (b * 255.0f + 0.5f) <<  0;
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic float
221176bdada62cabc6ec4b0308a930e83b679d5d36John Recklin2srgb (float linear)
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (linear < 0.0031308f)
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return linear * 12.92f;
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return 1.055f * powf (linear, 1.0f/2.4f) - 0.055f;
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t
311176bdada62cabc6ec4b0308a930e83b679d5d36John Recklinear_argb_to_premult_srgb_argb (float a,
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				  float r,
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				  float g,
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				  float b)
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    r = lin2srgb (r * a);
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    g = lin2srgb (g * a);
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    b = lin2srgb (b * a);
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return (uint32_t) (a * 255.0f + 0.5f) << 24
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 | (uint32_t) (r * 255.0f + 0.5f) << 16
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 | (uint32_t) (g * 255.0f + 0.5f) <<  8
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 | (uint32_t) (b * 255.0f + 0.5f) <<  0;
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reckint
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reckmain (int argc, char **argv)
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define WIDTH 400
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define HEIGHT 200
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int y, x, p;
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    float alpha;
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t *src1 = malloc (WIDTH * HEIGHT * 4);
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *dest_img, *src1_img;
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8_sRGB,
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 WIDTH, HEIGHT,
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 dest,
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 WIDTH * 4);
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src1_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 WIDTH, HEIGHT,
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 src1,
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 WIDTH * 4);
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (y = 0; y < HEIGHT; y ++)
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	p = WIDTH * y;
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (x = 0; x < WIDTH; x ++)
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     alpha = (float) x / WIDTH;
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     src1[p + x] = linear_argb_to_premult_argb (alpha, 1, 0, 1);
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     dest[p + x] = linear_argb_to_premult_srgb_argb (1-alpha, 0, 1, 0);
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_composite (PIXMAN_OP_ADD, src1_img, NULL, dest_img,
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (src1_img);
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    free (src1);
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    show_image (dest_img);
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (dest_img);
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    free (dest);
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return 0;
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
88