Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright  2013 Soeren Sandmann
      3  * Copyright  2013 Red Hat, Inc.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  */
     24 #include <stdio.h>
     25 #include <stdlib.h> /* abort() */
     26 #include <math.h>
     27 #include <time.h>
     28 #include "utils.h"
     29 
     30 typedef struct pixel_combination_t pixel_combination_t;
     31 struct pixel_combination_t
     32 {
     33     pixman_op_t			op;
     34     pixman_format_code_t	src_format;
     35     uint32_t			src_pixel;
     36     pixman_format_code_t	dest_format;
     37     uint32_t			dest_pixel;
     38 };
     39 
     40 static const pixel_combination_t regressions[] =
     41 {
     42     { PIXMAN_OP_OVER,
     43       PIXMAN_a8r8g8b8,	0x0f00c300,
     44       PIXMAN_x14r6g6b6,	0x003c0,
     45     },
     46     { PIXMAN_OP_DISJOINT_XOR,
     47       PIXMAN_a4r4g4b4,	0xd0c0,
     48       PIXMAN_a8r8g8b8,	0x5300ea00,
     49     },
     50     { PIXMAN_OP_OVER,
     51       PIXMAN_a8r8g8b8,	0x20c6bf00,
     52       PIXMAN_r5g6b5,	0xb9ff
     53     },
     54     { PIXMAN_OP_OVER,
     55       PIXMAN_a8r8g8b8,	0x204ac7ff,
     56       PIXMAN_r5g6b5,	0xc1ff
     57     },
     58     { PIXMAN_OP_OVER_REVERSE,
     59       PIXMAN_r5g6b5,	0xffc3,
     60       PIXMAN_a8r8g8b8,	0x102d00dd
     61     },
     62     { PIXMAN_OP_OVER_REVERSE,
     63       PIXMAN_r5g6b5,	0x1f00,
     64       PIXMAN_a8r8g8b8,	0x1bdf0c89
     65     },
     66     { PIXMAN_OP_OVER_REVERSE,
     67       PIXMAN_r5g6b5,	0xf9d2,
     68       PIXMAN_a8r8g8b8,	0x1076bcf7
     69     },
     70     { PIXMAN_OP_OVER_REVERSE,
     71       PIXMAN_r5g6b5,	0x00c3,
     72       PIXMAN_a8r8g8b8,	0x1bfe9ae5
     73     },
     74     { PIXMAN_OP_OVER_REVERSE,
     75       PIXMAN_r5g6b5,	0x09ff,
     76       PIXMAN_a8r8g8b8,	0x0b00c16c
     77     },
     78     { PIXMAN_OP_DISJOINT_ATOP,
     79       PIXMAN_a2r2g2b2,	0xbc,
     80       PIXMAN_a8r8g8b8,	0x9efff1ff
     81     },
     82     { PIXMAN_OP_DISJOINT_ATOP,
     83       PIXMAN_a4r4g4b4,	0xae5f,
     84       PIXMAN_a8r8g8b8,	0xf215b675
     85     },
     86     { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
     87       PIXMAN_a8r8g8b8,	0xce007980,
     88       PIXMAN_a8r8g8b8,	0x80ffe4ad
     89     },
     90     { PIXMAN_OP_DISJOINT_XOR,
     91       PIXMAN_a8r8g8b8,	0xb8b07bea,
     92       PIXMAN_a4r4g4b4,	0x939c
     93     },
     94     { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
     95       PIXMAN_r5g6b5,	0x0063,
     96       PIXMAN_a8r8g8b8,	0x10bb1ed7,
     97     },
     98 };
     99 
    100 static void
    101 fill (pixman_image_t *image, uint32_t pixel)
    102 {
    103     uint8_t *data = (uint8_t *)pixman_image_get_data (image);
    104     int bytes_per_pixel = PIXMAN_FORMAT_BPP (pixman_image_get_format (image)) / 8;
    105     int n_bytes = pixman_image_get_stride (image) * pixman_image_get_height (image);
    106     int i;
    107 
    108     switch (bytes_per_pixel)
    109     {
    110     case 4:
    111 	for (i = 0; i < n_bytes / 4; ++i)
    112 	    ((uint32_t *)data)[i] = pixel;
    113 	break;
    114 
    115     case 2:
    116 	pixel &= 0xffff;
    117 	for (i = 0; i < n_bytes / 2; ++i)
    118 	    ((uint16_t *)data)[i] = pixel;
    119 	break;
    120 
    121     case 1:
    122 	pixel &= 0xff;
    123 	for (i = 0; i < n_bytes; ++i)
    124 	    ((uint8_t *)data)[i] = pixel;
    125 	break;
    126 
    127     default:
    128 	assert (0);
    129 	break;
    130     }
    131 }
    132 
    133 static uint32_t
    134 access (pixman_image_t *image, int x, int y)
    135 {
    136     int bytes_per_pixel;
    137     int stride;
    138     uint32_t result;
    139     uint8_t *location;
    140 
    141     if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height)
    142         return 0;
    143 
    144     bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
    145     stride = image->bits.rowstride * 4;
    146 
    147     location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel;
    148 
    149     if (bytes_per_pixel == 4)
    150         result = *(uint32_t *)location;
    151     else if (bytes_per_pixel == 2)
    152         result = *(uint16_t *)location;
    153     else if (bytes_per_pixel == 1)
    154         result = *(uint8_t *)location;
    155     else
    156 	assert (0);
    157 
    158     return result;
    159 }
    160 
    161 static pixman_bool_t
    162 verify (int test_no, const pixel_combination_t *combination, int size)
    163 {
    164     pixman_image_t *src, *dest;
    165     pixel_checker_t src_checker, dest_checker;
    166     color_t source_color, dest_color, reference_color;
    167     pixman_bool_t result = TRUE;
    168     int i, j;
    169 
    170     /* Compute reference color */
    171     pixel_checker_init (&src_checker, combination->src_format);
    172     pixel_checker_init (&dest_checker, combination->dest_format);
    173     pixel_checker_convert_pixel_to_color (
    174 	&src_checker, combination->src_pixel, &source_color);
    175     pixel_checker_convert_pixel_to_color (
    176 	&dest_checker, combination->dest_pixel, &dest_color);
    177     do_composite (combination->op,
    178 		  &source_color, NULL, &dest_color,
    179 		  &reference_color, FALSE);
    180 
    181     src = pixman_image_create_bits (
    182 	combination->src_format, size, size, NULL, -1);
    183     dest = pixman_image_create_bits (
    184 	combination->dest_format, size, size, NULL, -1);
    185 
    186     fill (src, combination->src_pixel);
    187     fill (dest, combination->dest_pixel);
    188 
    189     pixman_image_composite32 (
    190 	combination->op, src, NULL, dest, 0, 0, 0, 0, 0, 0, size, size);
    191 
    192     for (j = 0; j < size; ++j)
    193     {
    194 	for (i = 0; i < size; ++i)
    195 	{
    196 	    uint32_t computed = access (dest, i, j);
    197 	    int32_t a, r, g, b;
    198 
    199 	    if (!pixel_checker_check (&dest_checker, computed, &reference_color))
    200 	    {
    201 		printf ("----------- Test %d failed ----------\n", test_no);
    202 
    203 		printf ("   operator:         %s\n", operator_name (combination->op));
    204 		printf ("   src format:       %s\n", format_name (combination->src_format));
    205 		printf ("   dest format:      %s\n", format_name (combination->dest_format));
    206                 printf (" - source ARGB:      %f  %f  %f  %f   (pixel: %8x)\n",
    207                         source_color.a, source_color.r, source_color.g, source_color.b,
    208                         combination->src_pixel);
    209 		pixel_checker_split_pixel (&src_checker, combination->src_pixel,
    210 					   &a, &r, &g, &b);
    211                 printf ("                     %8d  %8d  %8d  %8d\n", a, r, g, b);
    212 
    213                 printf (" - dest ARGB:        %f  %f  %f  %f   (pixel: %8x)\n",
    214                         dest_color.a, dest_color.r, dest_color.g, dest_color.b,
    215                         combination->dest_pixel);
    216 		pixel_checker_split_pixel (&dest_checker, combination->dest_pixel,
    217 					   &a, &r, &g, &b);
    218                 printf ("                     %8d  %8d  %8d  %8d\n", a, r, g, b);
    219 
    220                 pixel_checker_split_pixel (&dest_checker, computed, &a, &r, &g, &b);
    221                 printf (" - expected ARGB:    %f  %f  %f  %f\n",
    222                         reference_color.a, reference_color.r, reference_color.g, reference_color.b);
    223 
    224                 pixel_checker_get_min (&dest_checker, &reference_color, &a, &r, &g, &b);
    225                 printf ("   min acceptable:   %8d  %8d  %8d  %8d\n", a, r, g, b);
    226 
    227                 pixel_checker_split_pixel (&dest_checker, computed, &a, &r, &g, &b);
    228                 printf ("   got:              %8d  %8d  %8d  %8d   (pixel: %8x)\n", a, r, g, b, computed);
    229 
    230                 pixel_checker_get_max (&dest_checker, &reference_color, &a, &r, &g, &b);
    231                 printf ("   max acceptable:   %8d  %8d  %8d  %8d\n", a, r, g, b);
    232 
    233 		result = FALSE;
    234 		goto done;
    235 	    }
    236 	}
    237     }
    238 
    239 done:
    240     pixman_image_unref (src);
    241     pixman_image_unref (dest);
    242 
    243     return result;
    244 }
    245 
    246 int
    247 main (int argc, char **argv)
    248 {
    249     int result = 0;
    250     int i, j;
    251 
    252     for (i = 0; i < ARRAY_LENGTH (regressions); ++i)
    253     {
    254 	const pixel_combination_t *combination = &(regressions[i]);
    255 
    256 	for (j = 1; j < 34; ++j)
    257 	{
    258 	    if (!verify (i, combination, j))
    259 	    {
    260 		result = 1;
    261 		break;
    262 	    }
    263 	}
    264     }
    265 
    266     return result;
    267 }
    268