mmx: add x8f8g8b8 fetcher
[profile/ivi/pixman.git] / test / scaling-crash-test.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "utils.h"
6
7 /*
8  * We have a source image filled with solid color, set NORMAL or PAD repeat,
9  * and some transform which results in nearest neighbour scaling.
10  *
11  * The expected result is either that the destination image filled with this solid
12  * color or, if the transformation is such that we can't composite anything at
13  * all, that nothing has changed in the destination.
14  *
15  * The surrounding memory of the source image is a different solid color so that
16  * we are sure to get failures if we access it.
17  */
18 static int
19 run_test (int32_t               dst_width,
20           int32_t               dst_height,
21           int32_t               src_width,
22           int32_t               src_height,
23           int32_t               src_x,
24           int32_t               src_y,
25           int32_t               scale_x,
26           int32_t               scale_y,
27           pixman_filter_t       filter,
28           pixman_repeat_t       repeat)
29 {
30     pixman_image_t *   src_img;
31     pixman_image_t *   dst_img;
32     pixman_transform_t transform;
33     uint32_t *         srcbuf;
34     uint32_t *         dstbuf;
35     pixman_box32_t     box = { 0, 0, src_width, src_height };
36     pixman_color_t     color_cc = { 0xcccc, 0xcccc, 0xcccc, 0xcccc };
37     int result;
38     int i;
39
40     static const pixman_fixed_t kernel[] =
41     {
42 #define D(f)    (pixman_double_to_fixed (f) + 0x0001)
43
44         pixman_int_to_fixed (5),
45         pixman_int_to_fixed (5),
46         D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
47         D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
48         D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
49         D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
50         D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0)
51     };
52
53     result = 0;
54
55     srcbuf = (uint32_t *)malloc ((src_width + 10) * (src_height + 10) * 4);
56     dstbuf = (uint32_t *)malloc (dst_width * dst_height * 4);
57
58     memset (srcbuf, 0x88, src_width * src_height * 4);
59     memset (dstbuf, 0x33, dst_width * dst_height * 4);
60
61     src_img = pixman_image_create_bits (
62         PIXMAN_a8r8g8b8, src_width, src_height,
63         srcbuf + (src_width + 10) * 5 + 5, (src_width + 10) * 4);
64
65     pixman_image_fill_boxes (PIXMAN_OP_SRC, src_img, &color_cc, 1, &box);
66
67     dst_img = pixman_image_create_bits (
68         PIXMAN_a8r8g8b8, dst_width, dst_height, dstbuf, dst_width * 4);
69
70     pixman_transform_init_scale (&transform, scale_x, scale_y);
71     pixman_image_set_transform (src_img, &transform);
72     pixman_image_set_repeat (src_img, repeat);
73     if (filter == PIXMAN_FILTER_CONVOLUTION)
74         pixman_image_set_filter (src_img, filter, kernel, 27);
75     else
76         pixman_image_set_filter (src_img, filter, NULL, 0);
77
78     pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
79                             src_x, src_y, 0, 0, 0, 0, dst_width, dst_height);
80
81     pixman_image_unref (src_img);
82     pixman_image_unref (dst_img);
83
84     for (i = 0; i < dst_width * dst_height; i++)
85     {
86         if (dstbuf[i] != 0xCCCCCCCC && dstbuf[i] != 0x33333333)
87         {
88             result = 1;
89             break;
90         }
91     }
92
93     free (srcbuf);
94     free (dstbuf);
95     return result;
96 }
97
98 typedef struct filter_info_t filter_info_t;
99 struct filter_info_t
100 {
101     pixman_filter_t value;
102     char name[28];
103 };
104
105 static const filter_info_t filters[] =
106 {
107     { PIXMAN_FILTER_NEAREST, "NEAREST" },
108     { PIXMAN_FILTER_BILINEAR, "BILINEAR" },
109     { PIXMAN_FILTER_CONVOLUTION, "CONVOLUTION" },
110 };
111
112 typedef struct repeat_info_t repeat_info_t;
113 struct repeat_info_t
114 {
115     pixman_repeat_t value;
116     char name[28];
117 };
118
119
120 static const repeat_info_t repeats[] =
121 {
122     { PIXMAN_REPEAT_PAD, "PAD" },
123     { PIXMAN_REPEAT_REFLECT, "REFLECT" },
124     { PIXMAN_REPEAT_NORMAL, "NORMAL" }
125 };
126
127 static int
128 do_test (int32_t                dst_size,
129          int32_t                src_size,
130          int32_t                src_offs,
131          int32_t                scale_factor)
132 {
133     int i, j;
134
135     for (i = 0; i < ARRAY_LENGTH (filters); ++i)
136     {
137         for (j = 0; j < ARRAY_LENGTH (repeats); ++j)
138         {
139             /* horizontal test */
140             if (run_test (dst_size, 1,
141                           src_size, 1,
142                           src_offs, 0,
143                           scale_factor, 65536,
144                           filters[i].value,
145                           repeats[j].value) != 0)
146             {
147                 printf ("Vertical test failed with %s filter and repeat mode %s\n",
148                         filters[i].name, repeats[j].name);
149
150                 return 1;
151             }
152
153             /* vertical test */
154             if (run_test (1, dst_size,
155                           1, src_size,
156                           0, src_offs,
157                           65536, scale_factor,
158                           filters[i].value,
159                           repeats[j].value) != 0)
160             {
161                 printf ("Vertical test failed with %s filter and repeat mode %s\n",
162                         filters[i].name, repeats[j].name);
163
164                 return 1;
165             }
166         }
167     }
168
169     return 0;
170 }
171
172 int
173 main (int argc, char *argv[])
174 {
175     int i;
176
177     pixman_disable_out_of_bounds_workaround ();
178
179     /* can potentially crash */
180     assert (do_test (
181                 48000, 32767, 1, 65536 * 128) == 0);
182
183     /* can potentially get into a deadloop */
184     assert (do_test (
185                 16384, 65536, 32, 32768) == 0);
186
187     /* can potentially access memory outside source image buffer */
188     assert (do_test (
189                 10, 10, 0, 1) == 0);
190     assert (do_test (
191                 10, 10, 0, 0) == 0);
192
193     for (i = 0; i < 100; ++i)
194     {
195         pixman_fixed_t one_seventh =
196             (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (7 << 16);
197
198         assert (do_test (
199                     1, 7, 3, one_seventh + i - 50) == 0);
200     }
201
202     for (i = 0; i < 100; ++i)
203     {
204         pixman_fixed_t scale =
205             (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (32767 << 16);
206
207         assert (do_test (
208                     1, 32767, 16383, scale + i - 50) == 0);
209     }
210
211     /* can potentially provide invalid results (out of range matrix stuff) */
212     assert (do_test (
213         48000, 32767, 16384, 65536 * 128) == 0);
214
215     return 0;
216 }