1/* Based loosely on scaling-test */ 2 3#include <stdlib.h> 4#include <stdio.h> 5#include "utils.h" 6 7#define MAX_SRC_WIDTH 48 8#define MAX_SRC_HEIGHT 48 9#define MAX_DST_WIDTH 48 10#define MAX_DST_HEIGHT 48 11#define MAX_STRIDE 4 12 13static pixman_format_code_t formats[] = 14{ 15 PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_r5g6b5, PIXMAN_a1, PIXMAN_a4 16}; 17 18static pixman_format_code_t mask_formats[] = 19{ 20 PIXMAN_a1, PIXMAN_a4, PIXMAN_a8, 21}; 22 23static pixman_op_t operators[] = 24{ 25 PIXMAN_OP_OVER, PIXMAN_OP_ADD, PIXMAN_OP_SRC, PIXMAN_OP_IN 26}; 27 28#define RANDOM_ELT(array) \ 29 ((array)[prng_rand_n(ARRAY_LENGTH((array)))]) 30 31static void 32destroy_bits (pixman_image_t *image, void *data) 33{ 34 fence_free (data); 35} 36 37static pixman_fixed_t 38random_fixed (int n) 39{ 40 return prng_rand_n (n << 16); 41} 42 43/* 44 * Composite operation with pseudorandom images 45 */ 46uint32_t 47test_composite (int testnum, 48 int verbose) 49{ 50 int i; 51 pixman_image_t * src_img; 52 pixman_image_t * dst_img; 53 pixman_region16_t clip; 54 int dst_width, dst_height; 55 int dst_stride; 56 int dst_x, dst_y; 57 int dst_bpp; 58 pixman_op_t op; 59 uint32_t * dst_bits; 60 uint32_t crc32; 61 pixman_format_code_t mask_format, dst_format; 62 pixman_trapezoid_t *traps; 63 int src_x, src_y; 64 int n_traps; 65 66 static pixman_color_t colors[] = 67 { 68 { 0xffff, 0xffff, 0xffff, 0xffff }, 69 { 0x0000, 0x0000, 0x0000, 0x0000 }, 70 { 0xabcd, 0xabcd, 0x0000, 0xabcd }, 71 { 0x0000, 0x0000, 0x0000, 0xffff }, 72 { 0x0101, 0x0101, 0x0101, 0x0101 }, 73 { 0x7777, 0x6666, 0x5555, 0x9999 }, 74 }; 75 76 FLOAT_REGS_CORRUPTION_DETECTOR_START (); 77 78 prng_srand (testnum); 79 80 op = RANDOM_ELT (operators); 81 mask_format = RANDOM_ELT (mask_formats); 82 83 /* Create source image */ 84 85 if (prng_rand_n (4) == 0) 86 { 87 src_img = pixman_image_create_solid_fill ( 88 &(colors[prng_rand_n (ARRAY_LENGTH (colors))])); 89 90 src_x = 10; 91 src_y = 234; 92 } 93 else 94 { 95 pixman_format_code_t src_format = RANDOM_ELT(formats); 96 int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8; 97 int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1; 98 int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1; 99 int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp; 100 uint32_t *bits; 101 102 src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2); 103 src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2); 104 105 src_stride = (src_stride + 3) & ~3; 106 107 bits = (uint32_t *)make_random_bytes (src_stride * src_height); 108 109 src_img = pixman_image_create_bits ( 110 src_format, src_width, src_height, bits, src_stride); 111 112 pixman_image_set_destroy_function (src_img, destroy_bits, bits); 113 114 if (prng_rand_n (8) == 0) 115 { 116 pixman_box16_t clip_boxes[2]; 117 int n = prng_rand_n (2) + 1; 118 119 for (i = 0; i < n; i++) 120 { 121 clip_boxes[i].x1 = prng_rand_n (src_width); 122 clip_boxes[i].y1 = prng_rand_n (src_height); 123 clip_boxes[i].x2 = 124 clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1); 125 clip_boxes[i].y2 = 126 clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1); 127 128 if (verbose) 129 { 130 printf ("source clip box: [%d,%d-%d,%d]\n", 131 clip_boxes[i].x1, clip_boxes[i].y1, 132 clip_boxes[i].x2, clip_boxes[i].y2); 133 } 134 } 135 136 pixman_region_init_rects (&clip, clip_boxes, n); 137 pixman_image_set_clip_region (src_img, &clip); 138 pixman_image_set_source_clipping (src_img, 1); 139 pixman_region_fini (&clip); 140 } 141 142 image_endian_swap (src_img); 143 } 144 145 /* Create destination image */ 146 { 147 dst_format = RANDOM_ELT(formats); 148 dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8; 149 dst_width = prng_rand_n (MAX_DST_WIDTH) + 1; 150 dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1; 151 dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp; 152 dst_stride = (dst_stride + 3) & ~3; 153 154 dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height); 155 156 dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2); 157 dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2); 158 159 dst_img = pixman_image_create_bits ( 160 dst_format, dst_width, dst_height, dst_bits, dst_stride); 161 162 image_endian_swap (dst_img); 163 } 164 165 /* Create traps */ 166 { 167 int i; 168 169 n_traps = prng_rand_n (25); 170 traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t)); 171 172 for (i = 0; i < n_traps; ++i) 173 { 174 pixman_trapezoid_t *t = &(traps[i]); 175 176 t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2; 177 t->bottom = t->top + random_fixed (MAX_DST_HEIGHT); 178 t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2; 179 t->left.p1.y = t->top - random_fixed (50); 180 t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2; 181 t->left.p2.y = t->bottom + random_fixed (50); 182 t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH); 183 t->right.p1.y = t->top - random_fixed (50); 184 t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH); 185 t->right.p2.y = t->bottom - random_fixed (50); 186 } 187 } 188 189 if (prng_rand_n (8) == 0) 190 { 191 pixman_box16_t clip_boxes[2]; 192 int n = prng_rand_n (2) + 1; 193 for (i = 0; i < n; i++) 194 { 195 clip_boxes[i].x1 = prng_rand_n (dst_width); 196 clip_boxes[i].y1 = prng_rand_n (dst_height); 197 clip_boxes[i].x2 = 198 clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1); 199 clip_boxes[i].y2 = 200 clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1); 201 202 if (verbose) 203 { 204 printf ("destination clip box: [%d,%d-%d,%d]\n", 205 clip_boxes[i].x1, clip_boxes[i].y1, 206 clip_boxes[i].x2, clip_boxes[i].y2); 207 } 208 } 209 pixman_region_init_rects (&clip, clip_boxes, n); 210 pixman_image_set_clip_region (dst_img, &clip); 211 pixman_region_fini (&clip); 212 } 213 214 pixman_composite_trapezoids (op, src_img, dst_img, mask_format, 215 src_x, src_y, dst_x, dst_y, n_traps, traps); 216 217 if (dst_format == PIXMAN_x8r8g8b8) 218 { 219 /* ignore unused part */ 220 for (i = 0; i < dst_stride * dst_height / 4; i++) 221 dst_bits[i] &= 0xFFFFFF; 222 } 223 224 image_endian_swap (dst_img); 225 226 if (verbose) 227 { 228 int j; 229 230 for (i = 0; i < dst_height; i++) 231 { 232 for (j = 0; j < dst_stride; j++) 233 printf ("%02X ", *((uint8_t *)dst_bits + i * dst_stride + j)); 234 235 printf ("\n"); 236 } 237 } 238 239 crc32 = compute_crc32 (0, dst_bits, dst_stride * dst_height); 240 241 fence_free (dst_bits); 242 243 pixman_image_unref (src_img); 244 pixman_image_unref (dst_img); 245 fence_free (traps); 246 247 FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); 248 return crc32; 249} 250 251int 252main (int argc, const char *argv[]) 253{ 254 return fuzzer_test_main("composite traps", 40000, 0x749BCC57, 255 test_composite, argc, argv); 256} 257