From 72ba0b955504ecdc69f4cbf96a677b82be18b0cb Mon Sep 17 00:00:00 2001 From: "Antti S. Lankila" Date: Sun, 29 Jul 2012 22:14:34 +0300 Subject: [PATCH] Add tests to validate new sRGB behavior Composite checks random combinations of operations that now also have sRGB sources, masks and destinations, and stress-test validates the read/write primitives. --- test/composite.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++---- test/stress-test.c | 1 + test/utils.c | 36 ++++++++++++++++++++++++++++- test/utils.h | 6 +++++ 4 files changed, 104 insertions(+), 6 deletions(-) diff --git a/test/composite.c b/test/composite.c index 81c416e..2930fb7 100644 --- a/test/composite.c +++ b/test/composite.c @@ -99,6 +99,9 @@ static const format_t formats[] = P(x2b10g10r10), P(a2r10g10b10), P(a2b10g10r10), + + /* sRGB formats */ + P(a8r8g8b8_sRGB), /* 24 bpp formats */ P(r8g8b8), @@ -544,17 +547,56 @@ composite_test (image_t *dst, } 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 @@ -564,6 +606,21 @@ composite_test (image_t *dst, } } + 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, diff --git a/test/stress-test.c b/test/stress-test.c index 9280802..54ab1c5 100644 --- a/test/stress-test.c +++ b/test/stress-test.c @@ -25,6 +25,7 @@ static const pixman_format_code_t image_formats[] = PIXMAN_x14r6g6b6, PIXMAN_r8g8b8, PIXMAN_b8g8r8, + PIXMAN_a8r8g8b8_sRGB, PIXMAN_r5g6b5, PIXMAN_b5g6r5, PIXMAN_x2r10g10b10, diff --git a/test/utils.c b/test/utils.c index 563b33d..85b58d0 100644 --- a/test/utils.c +++ b/test/utils.c @@ -1,6 +1,7 @@ #define _GNU_SOURCE #include "utils.h" +#include #include #include @@ -765,6 +766,24 @@ aligned_malloc (size_t align, size_t size) (((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) { @@ -868,6 +887,7 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format) 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); @@ -968,11 +988,25 @@ pixel_checker_get_min (const pixel_checker_t *checker, color_t *color, 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); diff --git a/test/utils.h b/test/utils.h index ac2decd..faf427f 100644 --- a/test/utils.h +++ b/test/utils.h @@ -163,6 +163,12 @@ write_png (pixman_image_t *image, const char *filename); void * aligned_malloc (size_t align, size_t size); +double +convert_srgb_to_linear (double component); + +double +convert_linear_to_srgb (double component); + void initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb); -- 2.7.4