~ubuntu-branches/ubuntu/saucy/pixman/saucy-security

« back to all changes in this revision

Viewing changes to test/blitters-test.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-09-28 18:12:47 UTC
  • mfrom: (1.1.8 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090928181247-3iehog63i50htejf
Tags: 0.16.2-1
* New upstream release (closes: #546849).
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Test program, which stresses the use of different color formats and
 
3
 * compositing operations.
 
4
 *
 
5
 * Just run it without any command line arguments, and it will report either
 
6
 *   "blitters test passed" - everything is ok
 
7
 *   "blitters test failed!" - there is some problem
 
8
 *
 
9
 * In the case of failure, finding the problem involves the following steps:
 
10
 * 1. Get the reference 'blitters-test' binary. It makes sense to disable all
 
11
 *    the cpu specific optimizations in pixman and also configure it with
 
12
 *    '--disable-shared' option. Those who are paranoid can also tweak the
 
13
 *    sources to disable all fastpath functions. The resulting binary
 
14
 *    can be renamed to something like 'blitters-test.ref'.
 
15
 * 2. Compile the buggy binary (also with the '--disable-shared' option).
 
16
 * 3. Run 'ruby blitters-test-bisect.rb ./blitters-test.ref ./blitters-test'
 
17
 * 4. Look at the information about failed case (destination buffer content
 
18
 *    will be shown) and try to figure out what is wrong. Loading
 
19
 *    test program in gdb, specifying failed test number in the command
 
20
 *    line with '-' character prepended and setting breakpoint on
 
21
 *    'pixman_image_composite' function can provide detailed information
 
22
 *    about function arguments
 
23
 */
 
24
#include <assert.h>
 
25
#include <stdlib.h>
 
26
#include <stdio.h>
 
27
#include <config.h>
 
28
#include "pixman.h"
 
29
 
 
30
/* A primitive pseudorandom number generator, taken from POSIX.1-2001 example */
 
31
 
 
32
static uint32_t lcg_seed;
 
33
 
 
34
static inline uint32_t
 
35
lcg_rand (void)
 
36
{
 
37
    lcg_seed = lcg_seed * 1103515245 + 12345;
 
38
    return ((uint32_t)(lcg_seed / 65536) % 32768);
 
39
}
 
40
 
 
41
static inline void
 
42
lcg_srand (uint32_t seed)
 
43
{
 
44
    lcg_seed = seed;
 
45
}
 
46
 
 
47
static inline uint32_t
 
48
lcg_rand_n (int max)
 
49
{
 
50
    return lcg_rand () % max;
 
51
}
 
52
 
 
53
static void *
 
54
aligned_malloc (size_t align, size_t size)
 
55
{
 
56
    void *result;
 
57
 
 
58
#ifdef HAVE_POSIX_MEMALIGN
 
59
    posix_memalign (&result, align, size);
 
60
#else
 
61
    result = malloc (size);
 
62
#endif
 
63
 
 
64
    return result;
 
65
}
 
66
 
 
67
/*----------------------------------------------------------------------------*\
 
68
 *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
 
69
 *
 
70
 *  This program generates the CRC-32 values for the files named in the
 
71
 *  command-line arguments.  These are the same CRC-32 values used by GZIP,
 
72
 *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf () can also be detached and
 
73
 *  used independently.
 
74
 *
 
75
 *  THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
 
76
 *
 
77
 *  Based on the byte-oriented implementation "File Verification Using CRC"
 
78
 *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
 
79
 *
 
80
 *  v1.0.0: original release.
 
81
 *  v1.0.1: fixed printf formats.
 
82
 *  v1.0.2: fixed something else.
 
83
 *  v1.0.3: replaced CRC constant table by generator function.
 
84
 *  v1.0.4: reformatted code, made ANSI C.  1994-12-05.
 
85
 *  v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
 
86
\*----------------------------------------------------------------------------*/
 
87
 
 
88
/*----------------------------------------------------------------------------*\
 
89
 *  NAME:
 
90
 *     Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
 
91
 *  DESCRIPTION:
 
92
 *     Computes or accumulates the CRC-32 value for a memory buffer.
 
93
 *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
 
94
 *     a CRC to be generated for multiple sequential buffer-fuls of data.
 
95
 *     The 'inCrc32' for the first buffer must be zero.
 
96
 *  ARGUMENTS:
 
97
 *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
 
98
 *     buf     - buffer to compute CRC-32 value for
 
99
 *     bufLen  - number of bytes in buffer
 
100
 *  RETURNS:
 
101
 *     crc32 - computed CRC-32 value
 
102
 *  ERRORS:
 
103
 *     (no errors are possible)
 
104
\*----------------------------------------------------------------------------*/
 
105
 
 
106
static uint32_t
 
107
compute_crc32 (uint32_t    in_crc32,
 
108
               const void *buf,
 
109
               size_t      buf_len)
 
110
{
 
111
    static const uint32_t crc_table[256] = {
 
112
        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
 
113
        0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
 
114
        0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
 
115
        0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
 
116
        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
 
117
        0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
 
118
        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
 
119
        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
 
120
        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
 
121
        0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
 
122
        0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
 
123
        0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
 
124
        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
 
125
        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
 
126
        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
 
127
        0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
 
128
        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
 
129
        0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
 
130
        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
 
131
        0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
 
132
        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
 
133
        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
 
134
        0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
 
135
        0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
 
136
        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
 
137
        0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
 
138
        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
 
139
        0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
 
140
        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
 
141
        0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
 
142
        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
 
143
        0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
 
144
        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
 
145
        0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
 
146
        0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
 
147
        0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
 
148
        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
 
149
        0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
 
150
        0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
 
151
        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
 
152
        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
 
153
        0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
 
154
        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
 
155
    };
 
156
 
 
157
    uint32_t              crc32;
 
158
    unsigned char *       byte_buf;
 
159
    size_t                i;
 
160
 
 
161
    /* accumulate crc32 for buffer */
 
162
    crc32 = in_crc32 ^ 0xFFFFFFFF;
 
163
    byte_buf = (unsigned char*) buf;
 
164
 
 
165
    for (i = 0; i < buf_len; i++)
 
166
        crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
 
167
 
 
168
    return (crc32 ^ 0xFFFFFFFF);
 
169
}
 
170
 
 
171
/* perform endian conversion of pixel data */
 
172
static void
 
173
image_endian_swap (pixman_image_t *img, int bpp)
 
174
{
 
175
    int stride = pixman_image_get_stride (img);
 
176
    uint32_t *data = pixman_image_get_data (img);
 
177
    int height = pixman_image_get_height (img);;
 
178
    int i, j;
 
179
 
 
180
    /* swap bytes only on big endian systems */
 
181
    volatile uint16_t endian_check_var = 0x1234;
 
182
    if (*(volatile uint8_t *)&endian_check_var != 0x12)
 
183
        return;
 
184
 
 
185
    for (i = 0; i < height; i++)
 
186
    {
 
187
        uint8_t *line_data = (uint8_t *)data + stride * i;
 
188
        /* swap bytes only for 16, 24 and 32 bpp for now */
 
189
        switch (bpp)
 
190
        {
 
191
        case 1:
 
192
            for (j = 0; j < stride; j++)
 
193
            {
 
194
                line_data[j] =
 
195
                    ((line_data[j] & 0x80) >> 7) |
 
196
                    ((line_data[j] & 0x40) >> 5) |
 
197
                    ((line_data[j] & 0x20) >> 3) |
 
198
                    ((line_data[j] & 0x10) >> 1) |
 
199
                    ((line_data[j] & 0x08) << 1) |
 
200
                    ((line_data[j] & 0x04) << 3) |
 
201
                    ((line_data[j] & 0x02) << 5) |
 
202
                    ((line_data[j] & 0x01) << 7);
 
203
            }
 
204
            break;
 
205
        case 4:
 
206
            for (j = 0; j < stride; j++)
 
207
            {
 
208
                line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
 
209
            }
 
210
            break;
 
211
        case 16:
 
212
            for (j = 0; j + 2 <= stride; j += 2)
 
213
            {
 
214
                char t1 = line_data[j + 0];
 
215
                char t2 = line_data[j + 1];
 
216
 
 
217
                line_data[j + 1] = t1;
 
218
                line_data[j + 0] = t2;
 
219
            }
 
220
            break;
 
221
        case 24:
 
222
            for (j = 0; j + 3 <= stride; j += 3)
 
223
            {
 
224
                char t1 = line_data[j + 0];
 
225
                char t2 = line_data[j + 1];
 
226
                char t3 = line_data[j + 2];
 
227
 
 
228
                line_data[j + 2] = t1;
 
229
                line_data[j + 1] = t2;
 
230
                line_data[j + 0] = t3;
 
231
            }
 
232
            break;
 
233
        case 32:
 
234
            for (j = 0; j + 4 <= stride; j += 4)
 
235
            {
 
236
                char t1 = line_data[j + 0];
 
237
                char t2 = line_data[j + 1];
 
238
                char t3 = line_data[j + 2];
 
239
                char t4 = line_data[j + 3];
 
240
 
 
241
                line_data[j + 3] = t1;
 
242
                line_data[j + 2] = t2;
 
243
                line_data[j + 1] = t3;
 
244
                line_data[j + 0] = t4;
 
245
            }
 
246
            break;
 
247
        default:
 
248
            break;
 
249
        }
 
250
    }
 
251
}
 
252
 
 
253
/* Create random image for testing purposes */
 
254
static pixman_image_t *
 
255
create_random_image (pixman_format_code_t *allowed_formats,
 
256
                     int                   max_width,
 
257
                     int                   max_height,
 
258
                     int                   max_extra_stride,
 
259
                     pixman_format_code_t *used_fmt)
 
260
{
 
261
    int n = 0, i, width, height, stride;
 
262
    pixman_format_code_t fmt;
 
263
    uint32_t *buf;
 
264
    pixman_image_t *img;
 
265
 
 
266
    while (allowed_formats[n] != -1)
 
267
        n++;
 
268
    fmt = allowed_formats[lcg_rand_n (n)];
 
269
    width = lcg_rand_n (max_width) + 1;
 
270
    height = lcg_rand_n (max_height) + 1;
 
271
    stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
 
272
        lcg_rand_n (max_extra_stride + 1);
 
273
    stride = (stride + 3) & ~3;
 
274
 
 
275
    /* do the allocation */
 
276
    buf = aligned_malloc (64, stride * height);
 
277
 
 
278
    /* initialize image with random data */
 
279
    for (i = 0; i < stride * height; i++)
 
280
    {
 
281
        /* generation is biased to having more 0 or 255 bytes as
 
282
         * they are more likely to be special-cased in code
 
283
         */
 
284
        *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
 
285
            (lcg_rand_n (2) ? 0 : 255);
 
286
    }
 
287
 
 
288
    img = pixman_image_create_bits (fmt, width, height, buf, stride);
 
289
 
 
290
    image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
 
291
 
 
292
    if (used_fmt) *used_fmt = fmt;
 
293
    return img;
 
294
}
 
295
 
 
296
/* Free random image, and optionally update crc32 based on its data */
 
297
static uint32_t
 
298
free_random_image (uint32_t initcrc,
 
299
                   pixman_image_t *img,
 
300
                   pixman_format_code_t fmt)
 
301
{
 
302
    uint32_t crc32 = 0;
 
303
    int stride = pixman_image_get_stride (img);
 
304
    uint32_t *data = pixman_image_get_data (img);
 
305
    int height = pixman_image_get_height (img);;
 
306
 
 
307
    if (fmt != -1)
 
308
    {
 
309
        /* mask unused 'x' part */
 
310
        if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
 
311
            PIXMAN_FORMAT_DEPTH (fmt) != 0)
 
312
        {
 
313
            int i;
 
314
            uint32_t *data = pixman_image_get_data (img);
 
315
            uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
 
316
 
 
317
            if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA)
 
318
                mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
 
319
 
 
320
            for (i = 0; i < 32; i++)
 
321
                mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
 
322
 
 
323
            for (i = 0; i < stride * height / 4; i++)
 
324
                data[i] &= mask;
 
325
        }
 
326
 
 
327
        /* swap endiannes in order to provide identical results on both big
 
328
         * and litte endian systems
 
329
         */
 
330
        image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
 
331
        crc32 = compute_crc32 (initcrc, data, stride * height);
 
332
    }
 
333
 
 
334
    pixman_image_unref (img);
 
335
    free (data);
 
336
 
 
337
    return crc32;
 
338
}
 
339
 
 
340
static pixman_op_t op_list[] = {
 
341
    PIXMAN_OP_SRC,
 
342
    PIXMAN_OP_OVER,
 
343
    PIXMAN_OP_ADD,
 
344
    PIXMAN_OP_CLEAR,
 
345
    PIXMAN_OP_SRC,
 
346
    PIXMAN_OP_DST,
 
347
    PIXMAN_OP_OVER,
 
348
    PIXMAN_OP_OVER_REVERSE,
 
349
    PIXMAN_OP_IN,
 
350
    PIXMAN_OP_IN_REVERSE,
 
351
    PIXMAN_OP_OUT,
 
352
    PIXMAN_OP_OUT_REVERSE,
 
353
    PIXMAN_OP_ATOP,
 
354
    PIXMAN_OP_ATOP_REVERSE,
 
355
    PIXMAN_OP_XOR,
 
356
    PIXMAN_OP_ADD,
 
357
    PIXMAN_OP_SATURATE,
 
358
    PIXMAN_OP_DISJOINT_CLEAR,
 
359
    PIXMAN_OP_DISJOINT_SRC,
 
360
    PIXMAN_OP_DISJOINT_DST,
 
361
    PIXMAN_OP_DISJOINT_OVER,
 
362
    PIXMAN_OP_DISJOINT_OVER_REVERSE,
 
363
    PIXMAN_OP_DISJOINT_IN,
 
364
    PIXMAN_OP_DISJOINT_IN_REVERSE,
 
365
    PIXMAN_OP_DISJOINT_OUT,
 
366
    PIXMAN_OP_DISJOINT_OUT_REVERSE,
 
367
    PIXMAN_OP_DISJOINT_ATOP,
 
368
    PIXMAN_OP_DISJOINT_ATOP_REVERSE,
 
369
    PIXMAN_OP_DISJOINT_XOR,
 
370
    PIXMAN_OP_CONJOINT_CLEAR,
 
371
    PIXMAN_OP_CONJOINT_SRC,
 
372
    PIXMAN_OP_CONJOINT_DST,
 
373
    PIXMAN_OP_CONJOINT_OVER,
 
374
    PIXMAN_OP_CONJOINT_OVER_REVERSE,
 
375
    PIXMAN_OP_CONJOINT_IN,
 
376
    PIXMAN_OP_CONJOINT_IN_REVERSE,
 
377
    PIXMAN_OP_CONJOINT_OUT,
 
378
    PIXMAN_OP_CONJOINT_OUT_REVERSE,
 
379
    PIXMAN_OP_CONJOINT_ATOP,
 
380
    PIXMAN_OP_CONJOINT_ATOP_REVERSE,
 
381
    PIXMAN_OP_CONJOINT_XOR,
 
382
    PIXMAN_OP_MULTIPLY,
 
383
    PIXMAN_OP_SCREEN,
 
384
    PIXMAN_OP_OVERLAY,
 
385
    PIXMAN_OP_DARKEN,
 
386
    PIXMAN_OP_LIGHTEN,
 
387
    PIXMAN_OP_COLOR_DODGE,
 
388
    PIXMAN_OP_COLOR_BURN,
 
389
    PIXMAN_OP_HARD_LIGHT,
 
390
    PIXMAN_OP_DIFFERENCE,
 
391
    PIXMAN_OP_EXCLUSION,
 
392
#if 0 /* these use floating point math and are not always bitexact on different platforms */
 
393
    PIXMAN_OP_SOFT_LIGHT,
 
394
    PIXMAN_OP_HSL_HUE,
 
395
    PIXMAN_OP_HSL_SATURATION,
 
396
    PIXMAN_OP_HSL_COLOR,
 
397
    PIXMAN_OP_HSL_LUMINOSITY,
 
398
#endif
 
399
};
 
400
 
 
401
static pixman_format_code_t img_fmt_list[] = {
 
402
    PIXMAN_a8r8g8b8,
 
403
    PIXMAN_x8r8g8b8,
 
404
    PIXMAN_r5g6b5,
 
405
    PIXMAN_r3g3b2,
 
406
    PIXMAN_a8,
 
407
    PIXMAN_a8b8g8r8,
 
408
    PIXMAN_x8b8g8r8,
 
409
    PIXMAN_b8g8r8a8,
 
410
    PIXMAN_b8g8r8x8,
 
411
    PIXMAN_r8g8b8,
 
412
    PIXMAN_b8g8r8,
 
413
    PIXMAN_r5g6b5,
 
414
    PIXMAN_b5g6r5,
 
415
    PIXMAN_x2r10g10b10,
 
416
    PIXMAN_a2r10g10b10,
 
417
    PIXMAN_x2b10g10r10,
 
418
    PIXMAN_a2b10g10r10,
 
419
    PIXMAN_a1r5g5b5,
 
420
    PIXMAN_x1r5g5b5,
 
421
    PIXMAN_a1b5g5r5,
 
422
    PIXMAN_x1b5g5r5,
 
423
    PIXMAN_a4r4g4b4,
 
424
    PIXMAN_x4r4g4b4,
 
425
    PIXMAN_a4b4g4r4,
 
426
    PIXMAN_x4b4g4r4,
 
427
    PIXMAN_a8,
 
428
    PIXMAN_r3g3b2,
 
429
    PIXMAN_b2g3r3,
 
430
    PIXMAN_a2r2g2b2,
 
431
    PIXMAN_a2b2g2r2,
 
432
#if 0 /* using these crashes the test */
 
433
    PIXMAN_c8,
 
434
    PIXMAN_g8,
 
435
    PIXMAN_x4c4,
 
436
    PIXMAN_x4g4,
 
437
    PIXMAN_c4,
 
438
    PIXMAN_g4,
 
439
    PIXMAN_g1,
 
440
#endif
 
441
    PIXMAN_x4a4,
 
442
    PIXMAN_a4,
 
443
    PIXMAN_r1g2b1,
 
444
    PIXMAN_b1g2r1,
 
445
    PIXMAN_a1r1g1b1,
 
446
    PIXMAN_a1b1g1r1,
 
447
    PIXMAN_a1,
 
448
    -1
 
449
};
 
450
 
 
451
static pixman_format_code_t mask_fmt_list[] = {
 
452
    PIXMAN_a8r8g8b8,
 
453
    PIXMAN_a8,
 
454
    PIXMAN_a4,
 
455
    PIXMAN_a1,
 
456
    -1
 
457
};
 
458
 
 
459
 
 
460
/*
 
461
 * Composite operation with pseudorandom images
 
462
 */
 
463
uint32_t
 
464
test_composite (uint32_t initcrc, int testnum, int verbose)
 
465
{
 
466
    int i;
 
467
    pixman_image_t *src_img = NULL;
 
468
    pixman_image_t *dst_img = NULL;
 
469
    pixman_image_t *mask_img = NULL;
 
470
    int src_width, src_height;
 
471
    int dst_width, dst_height;
 
472
    int src_stride, dst_stride;
 
473
    int src_x, src_y;
 
474
    int dst_x, dst_y;
 
475
    int w, h;
 
476
    int op;
 
477
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
 
478
    uint32_t *dstbuf;
 
479
    uint32_t crc32;
 
480
    int max_width, max_height, max_extra_stride;
 
481
 
 
482
    max_width = max_height = 24 + testnum / 10000;
 
483
    max_extra_stride = 4 + testnum / 1000000;
 
484
 
 
485
    if (max_width > 256)
 
486
        max_width = 256;
 
487
 
 
488
    if (max_height > 16)
 
489
        max_height = 16;
 
490
 
 
491
    if (max_extra_stride > 8)
 
492
        max_extra_stride = 8;
 
493
 
 
494
    lcg_srand (testnum);
 
495
 
 
496
    op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];
 
497
 
 
498
    if (lcg_rand_n (8))
 
499
    {
 
500
        /* normal image */
 
501
        src_img = create_random_image (img_fmt_list, max_width, max_height,
 
502
                                       max_extra_stride, &src_fmt);
 
503
    }
 
504
    else
 
505
    {
 
506
        /* solid case */
 
507
        src_img = create_random_image (img_fmt_list, 1, 1,
 
508
                                       max_extra_stride, &src_fmt);
 
509
 
 
510
        pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
 
511
    }
 
512
 
 
513
    dst_img = create_random_image (img_fmt_list, max_width, max_height,
 
514
                                   max_extra_stride, &dst_fmt);
 
515
 
 
516
    mask_img = NULL;
 
517
    mask_fmt = -1;
 
518
 
 
519
    if (lcg_rand_n (2))
 
520
    {
 
521
        if (lcg_rand_n (2))
 
522
        {
 
523
            mask_img = create_random_image (mask_fmt_list, max_width, max_height,
 
524
                                           max_extra_stride, &mask_fmt);
 
525
        }
 
526
        else
 
527
        {
 
528
            /* solid case */
 
529
            mask_img = create_random_image (mask_fmt_list, 1, 1,
 
530
                                           max_extra_stride, &mask_fmt);
 
531
            pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
 
532
        }
 
533
 
 
534
        if (lcg_rand_n (2))
 
535
            pixman_image_set_component_alpha (mask_img, 1);
 
536
    }
 
537
 
 
538
    src_width = pixman_image_get_width (src_img);
 
539
    src_height = pixman_image_get_height (src_img);
 
540
    src_stride = pixman_image_get_stride (src_img);
 
541
 
 
542
    dst_width = pixman_image_get_width (dst_img);
 
543
    dst_height = pixman_image_get_height (dst_img);
 
544
    dst_stride = pixman_image_get_stride (dst_img);
 
545
 
 
546
    dstbuf = pixman_image_get_data (dst_img);
 
547
 
 
548
    src_x = lcg_rand_n (src_width);
 
549
    src_y = lcg_rand_n (src_height);
 
550
    dst_x = lcg_rand_n (dst_width);
 
551
    dst_y = lcg_rand_n (dst_height);
 
552
 
 
553
    w = lcg_rand_n (dst_width - dst_x + 1);
 
554
    h = lcg_rand_n (dst_height - dst_y + 1);
 
555
 
 
556
    if (verbose)
 
557
    {
 
558
        printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
 
559
            op, src_fmt, dst_fmt, mask_fmt);
 
560
        printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
 
561
            src_width, src_height, dst_width, dst_height);
 
562
        printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
 
563
            src_x, src_y, dst_x, dst_y);
 
564
        printf ("src_stride=%d, dst_stride=%d\n",
 
565
            src_stride, dst_stride);
 
566
        printf ("w=%d, h=%d\n", w, h);
 
567
    }
 
568
 
 
569
    pixman_image_composite (op, src_img, mask_img, dst_img,
 
570
                            src_x, src_y, src_x, src_y, dst_x, dst_y, w, h);
 
571
 
 
572
    if (verbose)
 
573
    {
 
574
        int j;
 
575
 
 
576
        printf ("---\n");
 
577
        for (i = 0; i < dst_height; i++)
 
578
        {
 
579
            for (j = 0; j < dst_stride; j++)
 
580
            {
 
581
                if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
 
582
                    printf ("| ");
 
583
 
 
584
                printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
 
585
            }
 
586
            printf ("\n");
 
587
        }
 
588
        printf ("---\n");
 
589
    }
 
590
 
 
591
    free_random_image (initcrc, src_img, -1);
 
592
    crc32 = free_random_image (initcrc, dst_img, dst_fmt);
 
593
 
 
594
    if (mask_img)
 
595
        free_random_image (initcrc, mask_img, -1);
 
596
 
 
597
    return crc32;
 
598
}
 
599
 
 
600
int
 
601
main (int argc, char *argv[])
 
602
{
 
603
    int i, n1 = 1, n2 = 0;
 
604
    uint32_t crc = 0;
 
605
    int verbose = getenv ("VERBOSE") != NULL;
 
606
 
 
607
    if (argc >= 3)
 
608
    {
 
609
        n1 = atoi (argv[1]);
 
610
        n2 = atoi (argv[2]);
 
611
    }
 
612
    else if (argc >= 2)
 
613
    {
 
614
        n2 = atoi (argv[1]);
 
615
    }
 
616
    else
 
617
    {
 
618
        n1 = 1;
 
619
        n2 = 2000000;
 
620
    }
 
621
 
 
622
    if (n2 < 0)
 
623
    {
 
624
        crc = test_composite (0, abs (n2), 1);
 
625
        printf ("crc32=%08X\n", crc);
 
626
    }
 
627
    else
 
628
    {
 
629
        for (i = n1; i <= n2; i++)
 
630
        {
 
631
            crc = test_composite (crc, i, 0);
 
632
 
 
633
            if (verbose)
 
634
                printf ("%d: %08X\n", i, crc);
 
635
        }
 
636
        printf ("crc32=%08X\n", crc);
 
637
 
 
638
        if (n2 == 2000000)
 
639
        {
 
640
            /* Predefined value for running with all the fastpath functions
 
641
               disabled. It needs to be updated every time when changes are
 
642
               introduced to this program or behavior of pixman changes! */
 
643
            if (crc == 0x06D8EDB6)
 
644
            {
 
645
                printf ("blitters test passed\n");
 
646
            }
 
647
            else
 
648
            {
 
649
                printf ("blitters test failed!\n");
 
650
                return 1;
 
651
            }
 
652
        }
 
653
    }
 
654
    return 0;
 
655
}