P(x2b10g10r10),
P(a2r10g10b10),
P(a2b10g10r10),
+
+ /* sRGB formats */
+ P(a8r8g8b8_sRGB),
/* 24 bpp formats */
P(r8g8b8),
}
tdst = *dst->color;
- round_color (dst->format->format, &tdst);
-
tsrc = *src->color;
- if (src->size)
- round_color (src->format->format, &tsrc);
if (mask)
{
tmsk = *mask->color;
- if (mask->size)
+ }
+
+ /* It turns out that by construction all source, mask etc. colors are
+ * linear because they are made from fills, and fills are always in linear
+ * color space. However, if they have been converted to bitmaps, we need
+ * to simulate the sRGB approximation to pass the test cases.
+ */
+ if (src->size)
+ {
+ if (PIXMAN_FORMAT_TYPE (src->format->format) == PIXMAN_TYPE_ARGB_SRGB)
+ {
+ tsrc.r = convert_linear_to_srgb (tsrc.r);
+ tsrc.g = convert_linear_to_srgb (tsrc.g);
+ tsrc.b = convert_linear_to_srgb (tsrc.b);
+ round_color (src->format->format, &tsrc);
+ tsrc.r = convert_srgb_to_linear (tsrc.r);
+ tsrc.g = convert_srgb_to_linear (tsrc.g);
+ tsrc.b = convert_srgb_to_linear (tsrc.b);
+ }
+ else
+ {
+ round_color (src->format->format, &tsrc);
+ }
+ }
+
+ if (mask && mask->size)
+ {
+ if (PIXMAN_FORMAT_TYPE (mask->format->format) == PIXMAN_TYPE_ARGB_SRGB)
+ {
+ tmsk.r = convert_linear_to_srgb (tmsk.r);
+ tmsk.g = convert_linear_to_srgb (tmsk.g);
+ tmsk.b = convert_linear_to_srgb (tmsk.b);
round_color (mask->format->format, &tmsk);
+ tmsk.r = convert_srgb_to_linear (tmsk.r);
+ tmsk.g = convert_srgb_to_linear (tmsk.g);
+ tmsk.b = convert_srgb_to_linear (tmsk.b);
+ }
+ else
+ {
+ round_color (mask->format->format, &tmsk);
+ }
+ }
+
+ if (mask)
+ {
if (component_alpha && PIXMAN_FORMAT_R (mask->format->format) == 0)
{
/* Ax component-alpha masks expand alpha into
}
}
+ if (PIXMAN_FORMAT_TYPE (dst->format->format) == PIXMAN_TYPE_ARGB_SRGB)
+ {
+ tdst.r = convert_linear_to_srgb (tdst.r);
+ tdst.g = convert_linear_to_srgb (tdst.g);
+ tdst.b = convert_linear_to_srgb (tdst.b);
+ round_color (dst->format->format, &tdst);
+ tdst.r = convert_srgb_to_linear (tdst.r);
+ tdst.g = convert_srgb_to_linear (tdst.g);
+ tdst.b = convert_srgb_to_linear (tdst.b);
+ }
+ else
+ {
+ round_color (dst->format->format, &tdst);
+ }
+
do_composite (op->op,
&tsrc,
mask? &tmsk : NULL,
#define _GNU_SOURCE
#include "utils.h"
+#include <math.h>
#include <signal.h>
#include <stdlib.h>
(((c) >> 8) & 0xff) * 301 + \
(((c) ) & 0xff) * 58) >> 2))
+double
+convert_srgb_to_linear (double c)
+{
+ if (c <= 0.04045)
+ return c / 12.92;
+ else
+ return powf ((c + 0.055) / 1.055, 2.4);
+}
+
+double
+convert_linear_to_srgb (double c)
+{
+ if (c <= 0.0031308)
+ return c * 12.92;
+ else
+ return 1.055 * powf (c, 1.0/2.4) - 0.055;
+}
+
void
initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
{
break;
case PIXMAN_TYPE_ARGB:
+ case PIXMAN_TYPE_ARGB_SRGB:
checker->bs = 0;
checker->gs = checker->bs + PIXMAN_FORMAT_B (format);
checker->rs = checker->gs + PIXMAN_FORMAT_G (format);
pixman_bool_t
pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel,
- color_t *color)
+ color_t *color_in)
{
int32_t a_lo, a_hi, r_lo, r_hi, g_lo, g_hi, b_lo, b_hi;
int32_t ai, ri, gi, bi;
pixman_bool_t result;
+ color_t tmp, *color;
+
+ if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
+ {
+ tmp.a = color_in->a;
+ tmp.r = convert_linear_to_srgb (color_in->r);
+ tmp.g = convert_linear_to_srgb (color_in->g);
+ tmp.b = convert_linear_to_srgb (color_in->b);
+ color = &tmp;
+ }
+ else
+ {
+ color = color_in;
+ }
pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo);
pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi);