~ubuntu-branches/debian/sid/pixman/sid

« back to all changes in this revision

Viewing changes to test/tolerance-test.c

  • Committer: Package Import Robot
  • Author(s): Julien Cristau, Andreas Boll, intrigeri
  • Date: 2015-09-12 13:08:02 UTC
  • mfrom: (1.1.29)
  • Revision ID: package-import@ubuntu.com-20150912130802-0egoj4agog1fsobn
Tags: 0.33.2-1
[ Andreas Boll ]
* New upstream release candidate.
* Enable vmx on ppc64el (closes: #786345).
* Update Vcs-* fields.
* Add upstream url.
* Drop XC- prefix from Package-Type field.
* Bump standards version to 3.9.6.

[ intrigeri ]
* Simplify hardening build flags handling (closes: #760100).
  Thanks to Simon Ruderich <simon@ruderich.org> for the patch.
* Enable all hardening build flags. Thanks to Simon Ruderich too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <assert.h>
 
2
#include <stdlib.h>
 
3
#include <stdio.h>
 
4
#include <float.h>
 
5
#include <math.h>
 
6
#include "utils.h"
 
7
 
 
8
#define MAX_WIDTH  16
 
9
#define MAX_HEIGHT 16
 
10
#define MAX_STRIDE 4
 
11
 
 
12
static const pixman_format_code_t formats[] =
 
13
{
 
14
    PIXMAN_a2r10g10b10,
 
15
    PIXMAN_x2r10g10b10,
 
16
    PIXMAN_a8r8g8b8,
 
17
    PIXMAN_a4r4g4b4,
 
18
    PIXMAN_a2r2g2b2,
 
19
    PIXMAN_r5g6b5,
 
20
    PIXMAN_r3g3b2,
 
21
};
 
22
 
 
23
static const pixman_op_t operators[] =
 
24
{
 
25
    PIXMAN_OP_CLEAR,
 
26
    PIXMAN_OP_SRC,
 
27
    PIXMAN_OP_DST,
 
28
    PIXMAN_OP_OVER,
 
29
    PIXMAN_OP_OVER_REVERSE,
 
30
    PIXMAN_OP_IN,
 
31
    PIXMAN_OP_IN_REVERSE,
 
32
    PIXMAN_OP_OUT,
 
33
    PIXMAN_OP_OUT_REVERSE,
 
34
    PIXMAN_OP_ATOP,
 
35
    PIXMAN_OP_ATOP_REVERSE,
 
36
    PIXMAN_OP_XOR,
 
37
    PIXMAN_OP_ADD,
 
38
    PIXMAN_OP_SATURATE,
 
39
 
 
40
    PIXMAN_OP_DISJOINT_CLEAR,
 
41
    PIXMAN_OP_DISJOINT_SRC,
 
42
    PIXMAN_OP_DISJOINT_DST,
 
43
    PIXMAN_OP_DISJOINT_OVER,
 
44
    PIXMAN_OP_DISJOINT_OVER_REVERSE,
 
45
    PIXMAN_OP_DISJOINT_IN,
 
46
    PIXMAN_OP_DISJOINT_IN_REVERSE,
 
47
    PIXMAN_OP_DISJOINT_OUT,
 
48
    PIXMAN_OP_DISJOINT_OUT_REVERSE,
 
49
    PIXMAN_OP_DISJOINT_ATOP,
 
50
    PIXMAN_OP_DISJOINT_ATOP_REVERSE,
 
51
    PIXMAN_OP_DISJOINT_XOR,
 
52
 
 
53
    PIXMAN_OP_CONJOINT_CLEAR,
 
54
    PIXMAN_OP_CONJOINT_SRC,
 
55
    PIXMAN_OP_CONJOINT_DST,
 
56
    PIXMAN_OP_CONJOINT_OVER,
 
57
    PIXMAN_OP_CONJOINT_OVER_REVERSE,
 
58
    PIXMAN_OP_CONJOINT_IN,
 
59
    PIXMAN_OP_CONJOINT_IN_REVERSE,
 
60
    PIXMAN_OP_CONJOINT_OUT,
 
61
    PIXMAN_OP_CONJOINT_OUT_REVERSE,
 
62
    PIXMAN_OP_CONJOINT_ATOP,
 
63
    PIXMAN_OP_CONJOINT_ATOP_REVERSE,
 
64
    PIXMAN_OP_CONJOINT_XOR,
 
65
 
 
66
    PIXMAN_OP_MULTIPLY,
 
67
    PIXMAN_OP_SCREEN,
 
68
    PIXMAN_OP_OVERLAY,
 
69
    PIXMAN_OP_DARKEN,
 
70
    PIXMAN_OP_LIGHTEN,
 
71
    PIXMAN_OP_COLOR_DODGE,
 
72
    PIXMAN_OP_COLOR_BURN,
 
73
    PIXMAN_OP_HARD_LIGHT,
 
74
    PIXMAN_OP_SOFT_LIGHT,
 
75
    PIXMAN_OP_DIFFERENCE,
 
76
    PIXMAN_OP_EXCLUSION,
 
77
};
 
78
 
 
79
#define RANDOM_ELT(array)                                               \
 
80
    (array[prng_rand_n (ARRAY_LENGTH (array))])
 
81
 
 
82
static void
 
83
free_bits (pixman_image_t *image, void *data)
 
84
{
 
85
    free (image->bits.bits);
 
86
}
 
87
 
 
88
static pixman_image_t *
 
89
create_image (pixman_image_t **clone)
 
90
{
 
91
    pixman_format_code_t format = RANDOM_ELT (formats);
 
92
    pixman_image_t *image;
 
93
    int width = prng_rand_n (MAX_WIDTH);
 
94
    int height = prng_rand_n (MAX_HEIGHT);
 
95
    int stride = ((width * (PIXMAN_FORMAT_BPP (format) / 8)) + 3) & ~3;
 
96
    uint32_t *bytes = malloc (stride * height);
 
97
 
 
98
    prng_randmemset (bytes, stride * height, RANDMEMSET_MORE_00_AND_FF);
 
99
 
 
100
    image = pixman_image_create_bits (
 
101
        format, width, height, bytes, stride);
 
102
 
 
103
    pixman_image_set_destroy_function (image, free_bits, NULL);
 
104
 
 
105
    assert (image);
 
106
 
 
107
    if (clone)
 
108
    {
 
109
        uint32_t *bytes_dup = malloc (stride * height);
 
110
 
 
111
        memcpy (bytes_dup, bytes, stride * height);
 
112
 
 
113
        *clone = pixman_image_create_bits (
 
114
            format, width, height, bytes_dup, stride);
 
115
 
 
116
        pixman_image_set_destroy_function (*clone, free_bits, NULL);
 
117
    }
 
118
    
 
119
    return image;
 
120
}
 
121
 
 
122
static pixman_bool_t
 
123
access (pixman_image_t *image, int x, int y, uint32_t *pixel)
 
124
{
 
125
    int bytes_per_pixel;
 
126
    int stride;
 
127
    uint8_t *location;
 
128
 
 
129
    if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height)
 
130
        return FALSE;
 
131
    
 
132
    bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
 
133
    stride = image->bits.rowstride * 4;
 
134
    
 
135
    location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel;
 
136
 
 
137
    if (bytes_per_pixel == 4)
 
138
        *pixel = *(uint32_t *)location;
 
139
    else if (bytes_per_pixel == 2)
 
140
        *pixel = *(uint16_t *)location;
 
141
    else if (bytes_per_pixel == 1)
 
142
        *pixel = *(uint8_t *)location;
 
143
    else
 
144
        assert (0);
 
145
 
 
146
    return TRUE;
 
147
}
 
148
 
 
149
static void
 
150
get_color (pixel_checker_t *checker,
 
151
           pixman_image_t *image,
 
152
           int x, int y,
 
153
           color_t *color,
 
154
           uint32_t *pixel)
 
155
{
 
156
    if (!access (image, x, y, pixel))
 
157
    {
 
158
        color->a = 0.0;
 
159
        color->r = 0.0;
 
160
        color->g = 0.0;
 
161
        color->b = 0.0;
 
162
    }
 
163
    else
 
164
    {
 
165
        pixel_checker_convert_pixel_to_color (
 
166
            checker, *pixel, color);
 
167
    }
 
168
}
 
169
            
 
170
static pixman_bool_t
 
171
verify (int test_no,
 
172
        pixman_op_t op,
 
173
        pixman_image_t *source,
 
174
        pixman_image_t *mask,
 
175
        pixman_image_t *dest,
 
176
        pixman_image_t *orig_dest,
 
177
        int x, int y,
 
178
        int width, int height,
 
179
        pixman_bool_t component_alpha)
 
180
{
 
181
    pixel_checker_t dest_checker, src_checker, mask_checker;
 
182
    int i, j;
 
183
 
 
184
    pixel_checker_init (&src_checker, source->bits.format);
 
185
    pixel_checker_init (&dest_checker, dest->bits.format);
 
186
    pixel_checker_init (&mask_checker, mask->bits.format);
 
187
 
 
188
    assert (dest->bits.format == orig_dest->bits.format);
 
189
 
 
190
    for (j = y; j < y + height; ++j)
 
191
    {
 
192
        for (i = x; i < x + width; ++i)
 
193
        {
 
194
            color_t src_color, mask_color, orig_dest_color, result;
 
195
            uint32_t dest_pixel, orig_dest_pixel, src_pixel, mask_pixel;
 
196
 
 
197
            access (dest, i, j, &dest_pixel);
 
198
 
 
199
            get_color (&src_checker,
 
200
                       source, i - x, j - y,
 
201
                       &src_color, &src_pixel);
 
202
 
 
203
            get_color (&mask_checker,
 
204
                       mask, i - x, j - y,
 
205
                       &mask_color, &mask_pixel);
 
206
 
 
207
            get_color (&dest_checker, 
 
208
                       orig_dest, i, j,
 
209
                       &orig_dest_color, &orig_dest_pixel);
 
210
 
 
211
            do_composite (op, 
 
212
                          &src_color, &mask_color, &orig_dest_color,
 
213
                          &result, component_alpha);
 
214
 
 
215
            if (!pixel_checker_check (&dest_checker, dest_pixel, &result))
 
216
            {
 
217
                int a, r, g, b;
 
218
 
 
219
                printf ("--------- Test 0x%x failed ---------\n", test_no);
 
220
                
 
221
                printf ("   operator:         %s (%s alpha)\n", operator_name (op),
 
222
                        component_alpha? "component" : "unified");
 
223
                printf ("   dest_x, dest_y:   %d %d\n", x, y);
 
224
                printf ("   width, height:    %d %d\n", width, height);
 
225
                printf ("   source:           format: %-14s  size: %2d x %2d\n",
 
226
                        format_name (source->bits.format),
 
227
                        source->bits.width, source->bits.height);
 
228
                printf ("   mask:             format: %-14s  size: %2d x %2d\n",
 
229
                        format_name (mask->bits.format),
 
230
                        mask->bits.width, mask->bits.height);
 
231
                printf ("   dest:             format: %-14s  size: %2d x %2d\n",
 
232
                        format_name (dest->bits.format),
 
233
                        dest->bits.width, dest->bits.height);
 
234
                printf ("   -- Failed pixel: (%d, %d) --\n", i, j);
 
235
                printf ("   source ARGB:      %f  %f  %f  %f   (pixel: %x)\n",
 
236
                        src_color.a, src_color.r, src_color.g, src_color.b,
 
237
                        src_pixel);
 
238
                printf ("   mask ARGB:        %f  %f  %f  %f   (pixel: %x)\n",
 
239
                        mask_color.a, mask_color.r, mask_color.g, mask_color.b,
 
240
                        mask_pixel);
 
241
                printf ("   dest ARGB:        %f  %f  %f  %f   (pixel: %x)\n",
 
242
                        orig_dest_color.a, orig_dest_color.r, orig_dest_color.g, orig_dest_color.b,
 
243
                        orig_dest_pixel);
 
244
                printf ("   expected ARGB:    %f  %f  %f  %f\n",
 
245
                        result.a, result.r, result.g, result.b);
 
246
 
 
247
                pixel_checker_get_min (&dest_checker, &result, &a, &r, &g, &b);
 
248
                printf ("   min acceptable:   %8d  %8d  %8d  %8d\n", a, r, g, b);
 
249
 
 
250
                pixel_checker_split_pixel (&dest_checker, dest_pixel, &a, &r, &g, &b);
 
251
                printf ("   got:              %8d  %8d  %8d  %8d   (pixel: %x)\n", a, r, g, b, dest_pixel);
 
252
                
 
253
                pixel_checker_get_max (&dest_checker, &result, &a, &r, &g, &b);
 
254
                printf ("   max acceptable:   %8d  %8d  %8d  %8d\n", a, r, g, b);
 
255
                printf ("\n");
 
256
                printf ("    { %s,\n", operator_name (op));
 
257
                printf ("      PIXMAN_%s,\t0x%x,\n", format_name (source->bits.format), src_pixel);
 
258
                printf ("      PIXMAN_%s,\t0x%x,\n", format_name (mask->bits.format), mask_pixel);
 
259
                printf ("      PIXMAN_%s,\t0x%x\n", format_name (dest->bits.format), orig_dest_pixel);
 
260
                printf ("    },\n");
 
261
                return FALSE;
 
262
            }
 
263
        }
 
264
    }
 
265
 
 
266
    return TRUE;
 
267
}
 
268
 
 
269
static pixman_bool_t
 
270
do_check (int i)
 
271
{
 
272
    pixman_image_t *source, *dest, *mask;
 
273
    pixman_op_t op;
 
274
    int x, y, width, height;
 
275
    pixman_image_t *dest_copy;
 
276
    pixman_bool_t result = TRUE;
 
277
    pixman_bool_t component_alpha;
 
278
 
 
279
    prng_srand (i);
 
280
    op = RANDOM_ELT (operators);
 
281
    x = prng_rand_n (MAX_WIDTH);
 
282
    y = prng_rand_n (MAX_HEIGHT);
 
283
    width = prng_rand_n (MAX_WIDTH) + 4;
 
284
    height = prng_rand_n (MAX_HEIGHT) + 4;
 
285
 
 
286
    source = create_image (NULL);
 
287
    mask = create_image (NULL);
 
288
    dest = create_image (&dest_copy);
 
289
 
 
290
    if (x >= dest->bits.width)
 
291
        x = dest->bits.width / 2;
 
292
    if (y >= dest->bits.height)
 
293
        y = dest->bits.height / 2;
 
294
    if (x + width > dest->bits.width)
 
295
        width = dest->bits.width - x;
 
296
    if (y + height > dest->bits.height)
 
297
        height = dest->bits.height - y;
 
298
 
 
299
    component_alpha = prng_rand_n (2);
 
300
 
 
301
    pixman_image_set_component_alpha (mask, component_alpha);
 
302
    
 
303
    pixman_image_composite32 (op, source, mask, dest,
 
304
                              0, 0, 0, 0,
 
305
                              x, y, width, height);
 
306
 
 
307
    if (!verify (i, op, source, mask, dest, dest_copy,
 
308
                 x, y, width, height, component_alpha))
 
309
    {
 
310
        result = FALSE;
 
311
    }
 
312
    
 
313
    pixman_image_unref (source);
 
314
    pixman_image_unref (mask);
 
315
    pixman_image_unref (dest);
 
316
    pixman_image_unref (dest_copy);
 
317
 
 
318
    return result;
 
319
}
 
320
 
 
321
#define N_TESTS    10000000
 
322
 
 
323
int
 
324
main (int argc, const char *argv[])
 
325
{
 
326
    int i;
 
327
    int result = 0;
 
328
 
 
329
    if (argc == 2)
 
330
    {
 
331
        if (strcmp (argv[1], "--forever") == 0)
 
332
        {
 
333
            uint32_t n;
 
334
 
 
335
            prng_srand (time (0));
 
336
 
 
337
            n = prng_rand();
 
338
 
 
339
            for (;;)
 
340
                do_check (n++);
 
341
        }
 
342
        else
 
343
        {
 
344
            do_check (strtol (argv[1], NULL, 0));
 
345
        }
 
346
    }
 
347
    else
 
348
    {
 
349
#ifdef USE_OPENMP
 
350
#       pragma omp parallel for default(none) reduction(|:result)
 
351
#endif
 
352
        for (i = 0; i < N_TESTS; ++i)
 
353
        {
 
354
            if (!do_check (i))
 
355
                result |= 1;
 
356
        }
 
357
    }
 
358
    
 
359
    return result;
 
360
}