pixel-test.c revision 1176bdada62cabc6ec4b0308a930e83b679d5d36
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
30typedef struct pixel_combination_t pixel_combination_t;
31struct 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
40static 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
100static void
101fill (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
133static uint32_t
134access (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
161static pixman_bool_t
162verify (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
239done:
240    pixman_image_unref (src);
241    pixman_image_unref (dest);
242
243    return result;
244}
245
246int
247main (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