/src/wuffs/fuzz/c/std/pixel_swizzler_fuzzer.c
Line | Count | Source |
1 | | // Copyright 2021 The Wuffs Authors. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
4 | | // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
5 | | // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
6 | | // option. This file may not be copied, modified, or distributed |
7 | | // except according to those terms. |
8 | | // |
9 | | // SPDX-License-Identifier: Apache-2.0 OR MIT |
10 | | |
11 | | // ---------------- |
12 | | |
13 | | // Silence the nested slash-star warning for the next comment's command line. |
14 | | #pragma clang diagnostic push |
15 | | #pragma clang diagnostic ignored "-Wcomment" |
16 | | |
17 | | /* |
18 | | This fuzzer (the fuzz function) is typically run indirectly, by a framework |
19 | | such as https://github.com/google/oss-fuzz calling LLVMFuzzerTestOneInput. |
20 | | |
21 | | When working on the fuzz implementation, or as a coherence check, defining |
22 | | WUFFS_CONFIG__FUZZLIB_MAIN will let you manually run fuzz over a set of files: |
23 | | |
24 | | gcc -DWUFFS_CONFIG__FUZZLIB_MAIN pixel_swizzler_fuzzer.c |
25 | | ./a.out ../../../test/data |
26 | | rm -f ./a.out |
27 | | |
28 | | It should print "PASS", amongst other information, and exit(0). |
29 | | */ |
30 | | |
31 | | #pragma clang diagnostic pop |
32 | | |
33 | | // Wuffs ships as a "single file C library" or "header file library" as per |
34 | | // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt |
35 | | // |
36 | | // To use that single file as a "foo.c"-like implementation, instead of a |
37 | | // "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or |
38 | | // compiling it. |
39 | | #define WUFFS_IMPLEMENTATION |
40 | | |
41 | | #if defined(WUFFS_CONFIG__FUZZLIB_MAIN) |
42 | | // Defining the WUFFS_CONFIG__STATIC_FUNCTIONS macro is optional, but when |
43 | | // combined with WUFFS_IMPLEMENTATION, it demonstrates making all of Wuffs' |
44 | | // functions have static storage. |
45 | | // |
46 | | // This can help the compiler ignore or discard unused code, which can produce |
47 | | // faster compiles and smaller binaries. Other motivations are discussed in the |
48 | | // "ALLOW STATIC IMPLEMENTATION" section of |
49 | | // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt |
50 | | #define WUFFS_CONFIG__STATIC_FUNCTIONS |
51 | | #endif // defined(WUFFS_CONFIG__FUZZLIB_MAIN) |
52 | | |
53 | | // Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of |
54 | | // release/c/etc.c choose which parts of Wuffs to build. That file contains the |
55 | | // entire Wuffs standard library, implementing a variety of codecs and file |
56 | | // formats. Without this macro definition, an optimizing compiler or linker may |
57 | | // very well discard Wuffs code for unused codecs, but listing the Wuffs |
58 | | // modules we use makes that process explicit. Preprocessing means that such |
59 | | // code simply isn't compiled. |
60 | | #define WUFFS_CONFIG__MODULES |
61 | | #define WUFFS_CONFIG__MODULE__BASE |
62 | | |
63 | | #include <sys/mman.h> |
64 | | #include <unistd.h> |
65 | | |
66 | | // If building this program in an environment that doesn't easily accommodate |
67 | | // relative includes, you can use the script/inline-c-relative-includes.go |
68 | | // program to generate a stand-alone C file. |
69 | | #include "../../../release/c/wuffs-unsupported-snapshot.c" |
70 | | #include "../fuzzlib/fuzzlib.c" |
71 | | |
72 | | const uint32_t pixfmts[] = { |
73 | | WUFFS_BASE__PIXEL_FORMAT__Y, |
74 | | WUFFS_BASE__PIXEL_FORMAT__Y_16BE, |
75 | | WUFFS_BASE__PIXEL_FORMAT__Y_16LE, |
76 | | WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL, |
77 | | WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL, |
78 | | WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY, |
79 | | WUFFS_BASE__PIXEL_FORMAT__BGR_565, |
80 | | WUFFS_BASE__PIXEL_FORMAT__BGR, |
81 | | WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL, |
82 | | WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE, |
83 | | WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL, |
84 | | WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE, |
85 | | WUFFS_BASE__PIXEL_FORMAT__BGRX, |
86 | | WUFFS_BASE__PIXEL_FORMAT__RGB, |
87 | | WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL, |
88 | | WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL, |
89 | | }; |
90 | | |
91 | | const wuffs_base__pixel_blend blends[] = { |
92 | | WUFFS_BASE__PIXEL_BLEND__SRC, |
93 | | WUFFS_BASE__PIXEL_BLEND__SRC_OVER, |
94 | | }; |
95 | | |
96 | | size_t // |
97 | 3 | round_up_to_pagesize(size_t n) { |
98 | 3 | size_t ps = getpagesize(); |
99 | 3 | if (ps <= 0) { |
100 | 0 | return n; |
101 | 0 | } |
102 | 3 | return ((n + (ps - 1)) / ps) * ps; |
103 | 3 | } |
104 | | |
105 | | // allocate_guarded_pages allocates (2 * len) bytes of memory. The first half |
106 | | // has read|write permissions. The second half has no permissions, so that |
107 | | // attempting to read or write to it will cause a segmentation fault. |
108 | | const char* // |
109 | 7 | allocate_guarded_pages(uint8_t** ptr_out, size_t len) { |
110 | 7 | void* ptr = |
111 | 7 | mmap(NULL, 2 * len, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
112 | 7 | if (ptr == MAP_FAILED) { |
113 | 0 | return "fuzz: internal error: mmap failed"; |
114 | 0 | } |
115 | 7 | if (mprotect(ptr, len, PROT_READ | PROT_WRITE)) { |
116 | 0 | return "fuzz: internal error: mprotect failed"; |
117 | 0 | } |
118 | 7 | *ptr_out = ptr; |
119 | 7 | return NULL; |
120 | 7 | } |
121 | | |
122 | | // fuzz_swizzle_interleaved_from_slice tests that, regardless of the randomized |
123 | | // inputs, calling wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice |
124 | | // will not crash the fuzzer (e.g. due to reads or write past buffer bounds). |
125 | | const char* // |
126 | 3.04k | fuzz_swizzle_interleaved_from_slice(wuffs_base__io_buffer* src, uint64_t hash) { |
127 | 3.04k | uint8_t dst_palette_array[1024]; |
128 | 3.04k | uint8_t src_palette_array[1024]; |
129 | 3.04k | if ((src->meta.wi - src->meta.ri) >= 2048) { |
130 | 182 | memcpy(dst_palette_array, src->data.ptr + src->meta.ri, 1024); |
131 | 182 | src->meta.ri += 1024; |
132 | 182 | memcpy(src_palette_array, src->data.ptr + src->meta.ri, 1024); |
133 | 182 | src->meta.ri += 1024; |
134 | 2.86k | } else { |
135 | 2.93M | for (uint32_t i = 0; i < 1024; i++) { |
136 | 2.93M | dst_palette_array[i] = (uint8_t)i; |
137 | 2.93M | src_palette_array[i] = (uint8_t)i; |
138 | 2.93M | } |
139 | 2.86k | } |
140 | 3.04k | wuffs_base__slice_u8 dst_palette = |
141 | 3.04k | wuffs_base__make_slice_u8(&dst_palette_array[0], 1024); |
142 | 3.04k | wuffs_base__slice_u8 src_palette = |
143 | 3.04k | wuffs_base__make_slice_u8(&src_palette_array[0], 1024); |
144 | | |
145 | 3.04k | size_t num_pixfmts = sizeof(pixfmts) / sizeof(pixfmts[0]); |
146 | 3.04k | wuffs_base__pixel_format dst_pixfmt = wuffs_base__make_pixel_format( |
147 | 3.04k | pixfmts[(0xFF & (hash >> 0)) % num_pixfmts]); |
148 | 3.04k | wuffs_base__pixel_format src_pixfmt = wuffs_base__make_pixel_format( |
149 | 3.04k | pixfmts[(0xFF & (hash >> 8)) % num_pixfmts]); |
150 | | |
151 | 3.04k | size_t num_blends = sizeof(blends) / sizeof(blends[0]); |
152 | 3.04k | wuffs_base__pixel_blend blend = blends[(0xFF & (hash >> 16)) % num_blends]; |
153 | | |
154 | 3.04k | size_t dst_len = 0xFF & (hash >> 24); |
155 | 3.04k | size_t src_len = 0xFF & (hash >> 32); |
156 | | |
157 | 3.04k | wuffs_base__pixel_swizzler swizzler; |
158 | 3.04k | wuffs_base__status status = wuffs_base__pixel_swizzler__prepare( |
159 | 3.04k | &swizzler, dst_pixfmt, dst_palette, src_pixfmt, src_palette, blend); |
160 | 3.04k | if (status.repr) { |
161 | 232 | return wuffs_base__status__message(&status); |
162 | 232 | } |
163 | | |
164 | 2.81k | static size_t alloc_size = 0; |
165 | 2.81k | if (alloc_size == 0) { |
166 | 1 | alloc_size = round_up_to_pagesize(0x100); |
167 | 1 | } |
168 | | |
169 | 2.81k | static uint8_t* dst_alloc = NULL; |
170 | 2.81k | if (!dst_alloc) { |
171 | 1 | const char* z = allocate_guarded_pages(&dst_alloc, alloc_size); |
172 | 1 | if (z != NULL) { |
173 | 0 | return z; |
174 | 0 | } |
175 | 1 | } |
176 | | |
177 | 2.81k | static uint8_t* src_alloc = NULL; |
178 | 2.81k | if (!src_alloc) { |
179 | 1 | const char* z = allocate_guarded_pages(&src_alloc, alloc_size); |
180 | 1 | if (z != NULL) { |
181 | 0 | return z; |
182 | 0 | } |
183 | 1 | } |
184 | | |
185 | | // Position dst_slice and src_slice so that reading or writing one byte past |
186 | | // their end will cause a segmentation fault. |
187 | 2.81k | wuffs_base__slice_u8 dst_slice = |
188 | 2.81k | wuffs_base__make_slice_u8(dst_alloc + alloc_size - dst_len, dst_len); |
189 | 2.81k | wuffs_base__slice_u8 src_slice = |
190 | 2.81k | wuffs_base__make_slice_u8(src_alloc + alloc_size - src_len, src_len); |
191 | | |
192 | | // Fill in dst_slice and src_slice. |
193 | 2.81k | if ((src->meta.wi - src->meta.ri) >= (dst_len + src_len)) { |
194 | 560 | memcpy(dst_slice.ptr, src->data.ptr + src->meta.ri, dst_len); |
195 | 560 | src->meta.ri += dst_len; |
196 | 560 | memcpy(src_slice.ptr, src->data.ptr + src->meta.ri, src_len); |
197 | 560 | src->meta.ri += src_len; |
198 | 2.25k | } else { |
199 | 282k | for (size_t i = 0; i < dst_len; i++) { |
200 | 279k | dst_slice.ptr[i] = (uint8_t)i; |
201 | 279k | } |
202 | 195k | for (size_t i = 0; i < src_len; i++) { |
203 | 193k | src_slice.ptr[i] = (uint8_t)i; |
204 | 193k | } |
205 | 2.25k | } |
206 | | |
207 | | // When manually testing this program, enabling this code should lead to a |
208 | | // segmentation fault. |
209 | | #if 0 |
210 | | src_slice.ptr[src_slice.len]++; |
211 | | #endif |
212 | | |
213 | | // Calling etc__swizzle_interleaved_from_slice should not crash, whether for |
214 | | // reading/writing out of bounds or for other reasons. |
215 | 2.81k | wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice( |
216 | 2.81k | &swizzler, dst_slice, dst_palette, src_slice); |
217 | | |
218 | 2.81k | return NULL; |
219 | 2.81k | } |
220 | | |
221 | | const char* // |
222 | 3.04k | fuzz_swizzle_ycck(wuffs_base__io_buffer* src, uint64_t hash) { |
223 | 3.04k | uint8_t dst_palette_array[1024] = {0}; |
224 | 3.04k | wuffs_base__slice_u8 dst_palette = |
225 | 3.04k | wuffs_base__make_slice_u8(&dst_palette_array[0], 1024); |
226 | | |
227 | 3.04k | size_t num_pixfmts = sizeof(pixfmts) / sizeof(pixfmts[0]); |
228 | 3.04k | wuffs_base__pixel_format dst_pixfmt = wuffs_base__make_pixel_format( |
229 | 3.04k | pixfmts[(0xFF & (hash >> 0)) % num_pixfmts]); |
230 | | |
231 | 3.04k | uint32_t x_min_incl = (63 & (hash >> 8)) + 1; |
232 | 3.04k | uint32_t x_max_excl = (63 & (hash >> 14)) + 1; |
233 | 3.04k | uint32_t y_min_incl = (63 & (hash >> 20)) + 1; |
234 | 3.04k | uint32_t y_max_excl = (63 & (hash >> 26)) + 1; |
235 | | |
236 | 3.04k | uint32_t width_in_mcus = (3 & (hash >> 32)) + 1; |
237 | 3.04k | uint32_t height_in_mcus = (3 & (hash >> 34)) + 1; |
238 | | |
239 | 3.04k | uint32_t allow_hv3 = 1 & (hash >> 36); |
240 | 3.04k | bool is_rgb_or_cmyk = 1 & (hash >> 37); |
241 | 3.04k | bool triangle_filter_for_2to1 = 1 & (hash >> 38); |
242 | 3.04k | bool use_4th_component = 1 & (hash >> 39); |
243 | | |
244 | 3.04k | if (triangle_filter_for_2to1) { |
245 | 1.13k | x_min_incl = 0; |
246 | 1.13k | y_min_incl = 0; |
247 | 1.90k | } else { |
248 | 1.90k | if (x_min_incl > x_max_excl) { |
249 | 934 | uint32_t a = x_min_incl; |
250 | 934 | x_min_incl = x_max_excl; |
251 | 934 | x_max_excl = a; |
252 | 934 | } |
253 | 1.90k | if (y_min_incl > y_max_excl) { |
254 | 1.16k | uint32_t a = y_min_incl; |
255 | 1.16k | y_min_incl = y_max_excl; |
256 | 1.16k | y_max_excl = a; |
257 | 1.16k | } |
258 | 1.90k | } |
259 | | |
260 | 3.04k | uint32_t possible_hv_values[2][4] = { |
261 | 3.04k | {1, 1, 2, 4}, |
262 | 3.04k | {1, 1, 3, 3}, |
263 | 3.04k | }; |
264 | 3.04k | uint32_t h0 = possible_hv_values[allow_hv3][3 & (hash >> 28)]; |
265 | 3.04k | uint32_t h1 = possible_hv_values[allow_hv3][3 & (hash >> 30)]; |
266 | 3.04k | uint32_t h2 = possible_hv_values[allow_hv3][3 & (hash >> 32)]; |
267 | 3.04k | uint32_t h3 = |
268 | 3.04k | use_4th_component ? possible_hv_values[allow_hv3][3 & (hash >> 34)] : 0; |
269 | 3.04k | uint32_t v0 = possible_hv_values[allow_hv3][3 & (hash >> 36)]; |
270 | 3.04k | uint32_t v1 = possible_hv_values[allow_hv3][3 & (hash >> 38)]; |
271 | 3.04k | uint32_t v2 = possible_hv_values[allow_hv3][3 & (hash >> 40)]; |
272 | 3.04k | uint32_t v3 = |
273 | 3.04k | use_4th_component ? possible_hv_values[allow_hv3][3 & (hash >> 42)] : 0; |
274 | | |
275 | 3.04k | uint32_t width0 = 8 * width_in_mcus * h0; |
276 | 3.04k | uint32_t width1 = 8 * width_in_mcus * h1; |
277 | 3.04k | uint32_t width2 = 8 * width_in_mcus * h2; |
278 | 3.04k | uint32_t width3 = 8 * width_in_mcus * h3; |
279 | 3.04k | uint32_t height0 = 8 * height_in_mcus * v0; |
280 | 3.04k | uint32_t height1 = 8 * height_in_mcus * v1; |
281 | 3.04k | uint32_t height2 = 8 * height_in_mcus * v2; |
282 | 3.04k | uint32_t height3 = 8 * height_in_mcus * v3; |
283 | | |
284 | 3.04k | uint32_t hmax = wuffs_base__u32__max( |
285 | 3.04k | h0, wuffs_base__u32__max(h1, wuffs_base__u32__max(h2, h3))); |
286 | 3.04k | uint32_t vmax = wuffs_base__u32__max( |
287 | 3.04k | v0, wuffs_base__u32__max(v1, wuffs_base__u32__max(v2, v3))); |
288 | 3.04k | x_max_excl = x_min_incl + wuffs_base__u32__min(x_max_excl - x_min_incl, |
289 | 3.04k | 8 * width_in_mcus * hmax); |
290 | 3.04k | y_max_excl = y_min_incl + wuffs_base__u32__min(y_max_excl - y_min_incl, |
291 | 3.04k | 8 * height_in_mcus * vmax); |
292 | | |
293 | 3.04k | static size_t dst_alloc_size = 0; |
294 | 3.04k | if (dst_alloc_size == 0) { |
295 | 1 | dst_alloc_size = round_up_to_pagesize(8 * 64 * 64); |
296 | 1 | } |
297 | | |
298 | 3.04k | static uint8_t* dst_alloc = NULL; |
299 | 3.04k | if (!dst_alloc) { |
300 | 1 | const char* z = allocate_guarded_pages(&dst_alloc, dst_alloc_size); |
301 | 1 | if (z != NULL) { |
302 | 0 | return z; |
303 | 0 | } |
304 | 1 | } |
305 | | |
306 | 3.04k | wuffs_base__pixel_buffer dst_pixbuf; |
307 | 3.04k | wuffs_base__pixel_config dst_pixcfg; |
308 | 3.04k | wuffs_base__pixel_config__set(&dst_pixcfg, dst_pixfmt.repr, 0, x_max_excl, |
309 | 3.04k | y_max_excl); |
310 | 3.04k | uint64_t dst_pixbuf_len = wuffs_base__pixel_config__pixbuf_len(&dst_pixcfg); |
311 | 3.04k | if (dst_pixbuf_len > dst_alloc_size) { |
312 | 0 | return "fuzz: internal error: dst_alloc_size is too small"; |
313 | 3.04k | } else { |
314 | 3.04k | wuffs_base__status status = wuffs_base__pixel_buffer__set_from_slice( |
315 | 3.04k | &dst_pixbuf, &dst_pixcfg, |
316 | 3.04k | wuffs_base__make_slice_u8(dst_alloc + dst_alloc_size - dst_pixbuf_len, |
317 | 3.04k | dst_pixbuf_len)); |
318 | 3.04k | if (status.repr) { |
319 | 0 | return "fuzz: internal error: wuffs_base__pixel_buffer__set_from_slice " |
320 | 0 | "failed"; |
321 | 0 | } |
322 | 3.04k | } |
323 | | |
324 | 3.04k | static size_t src_alloc_size = 0; |
325 | 3.04k | if (src_alloc_size == 0) { |
326 | 1 | src_alloc_size = round_up_to_pagesize(8 * 4 * 4 * 8 * 4 * 4); |
327 | 1 | } |
328 | | |
329 | 3.04k | static uint8_t* src_alloc0 = NULL; |
330 | 3.04k | static uint8_t* src_alloc1 = NULL; |
331 | 3.04k | static uint8_t* src_alloc2 = NULL; |
332 | 3.04k | static uint8_t* src_alloc3 = NULL; |
333 | 3.04k | if (!src_alloc0) { |
334 | 1 | const char* z = allocate_guarded_pages(&src_alloc0, src_alloc_size); |
335 | 1 | if (z != NULL) { |
336 | 0 | return z; |
337 | 0 | } |
338 | 1 | } |
339 | 3.04k | if (!src_alloc1) { |
340 | 1 | const char* z = allocate_guarded_pages(&src_alloc1, src_alloc_size); |
341 | 1 | if (z != NULL) { |
342 | 0 | return z; |
343 | 0 | } |
344 | 1 | } |
345 | 3.04k | if (!src_alloc2) { |
346 | 1 | const char* z = allocate_guarded_pages(&src_alloc2, src_alloc_size); |
347 | 1 | if (z != NULL) { |
348 | 0 | return z; |
349 | 0 | } |
350 | 1 | } |
351 | 3.04k | if (!src_alloc3) { |
352 | 1 | const char* z = allocate_guarded_pages(&src_alloc3, src_alloc_size); |
353 | 1 | if (z != NULL) { |
354 | 0 | return z; |
355 | 0 | } |
356 | 1 | } |
357 | | |
358 | 3.04k | uint32_t src_len0 = width0 * height0; |
359 | 3.04k | uint32_t src_len1 = width1 * height1; |
360 | 3.04k | uint32_t src_len2 = width2 * height2; |
361 | 3.04k | uint32_t src_len3 = width3 * height3; |
362 | 3.04k | if ((src_len0 > src_alloc_size) || // |
363 | 3.04k | (src_len1 > src_alloc_size) || // |
364 | 3.04k | (src_len2 > src_alloc_size) || // |
365 | 3.04k | (src_len3 > src_alloc_size)) { |
366 | 0 | return "fuzz: internal error: src_alloc_size is too small"; |
367 | 0 | } |
368 | | |
369 | 3.04k | uint8_t s0 = 0x90; |
370 | 3.04k | if (src->meta.ri < src->meta.wi) { |
371 | 2.75k | s0 = src->data.ptr[src->meta.ri++]; |
372 | 2.75k | } |
373 | 3.04k | uint8_t s1 = 0x91; |
374 | 3.04k | if (src->meta.ri < src->meta.wi) { |
375 | 2.46k | s1 = src->data.ptr[src->meta.ri++]; |
376 | 2.46k | } |
377 | 3.04k | uint8_t s2 = 0x92; |
378 | 3.04k | if (src->meta.ri < src->meta.wi) { |
379 | 1.46k | s2 = src->data.ptr[src->meta.ri++]; |
380 | 1.46k | } |
381 | 3.04k | uint8_t s3 = 0x93; |
382 | 3.04k | if (src->meta.ri < src->meta.wi) { |
383 | 297 | s3 = src->data.ptr[src->meta.ri++]; |
384 | 297 | } |
385 | | |
386 | 3.04k | wuffs_base__slice_u8 src0 = wuffs_base__make_slice_u8( |
387 | 3.04k | src_alloc0 + src_alloc_size - src_len0, src_len0); |
388 | 3.04k | memset(src0.ptr, s0, src0.len); |
389 | 3.04k | wuffs_base__slice_u8 src1 = wuffs_base__make_slice_u8( |
390 | 3.04k | src_alloc1 + src_alloc_size - src_len1, src_len1); |
391 | 3.04k | memset(src1.ptr, s1, src1.len); |
392 | 3.04k | wuffs_base__slice_u8 src2 = wuffs_base__make_slice_u8( |
393 | 3.04k | src_alloc2 + src_alloc_size - src_len2, src_len2); |
394 | 3.04k | memset(src2.ptr, s2, src2.len); |
395 | 3.04k | wuffs_base__slice_u8 src3 = wuffs_base__empty_slice_u8(); |
396 | 3.04k | if (use_4th_component) { |
397 | 664 | wuffs_base__slice_u8 src3 = wuffs_base__make_slice_u8( |
398 | 664 | src_alloc3 + src_alloc_size - src_len3, src_len3); |
399 | 664 | memset(src3.ptr, s3, src3.len); |
400 | 664 | } |
401 | | |
402 | 3.04k | wuffs_base__pixel_swizzler swizzler = {0}; |
403 | 3.04k | uint8_t scratch_buffer[2048]; |
404 | 3.04k | wuffs_base__status status = wuffs_base__pixel_swizzler__swizzle_ycck( |
405 | 3.04k | &swizzler, &dst_pixbuf, dst_palette, // |
406 | 3.04k | x_min_incl, x_max_excl, // |
407 | 3.04k | y_min_incl, y_max_excl, // |
408 | 3.04k | src0, src1, src2, src3, // |
409 | 3.04k | width0, width1, width2, width3, // |
410 | 3.04k | height0, height1, height2, height3, // |
411 | 3.04k | width0, width1, width2, width3, // |
412 | 3.04k | h0, h1, h2, h3, // |
413 | 3.04k | v0, v1, v2, v3, // |
414 | 3.04k | is_rgb_or_cmyk, // |
415 | 3.04k | triangle_filter_for_2to1, // |
416 | 3.04k | wuffs_base__make_slice_u8(scratch_buffer, sizeof(scratch_buffer))); |
417 | 3.04k | if (status.repr) { |
418 | 1.58k | return wuffs_base__status__message(&status); |
419 | 1.58k | } |
420 | 1.46k | return NULL; |
421 | 3.04k | } |
422 | | |
423 | | const char* // |
424 | 3.04k | fuzz(wuffs_base__io_buffer* src, uint64_t hash) { |
425 | 3.04k | const char* s0 = fuzz_swizzle_interleaved_from_slice(src, hash); |
426 | 3.04k | const char* s1 = fuzz_swizzle_ycck(src, hash); |
427 | 3.04k | if (s0 && strstr(s0, "internal error:")) { |
428 | 0 | return s0; |
429 | 0 | } |
430 | 3.04k | if (s1 && strstr(s1, "internal error:")) { |
431 | 0 | return s1; |
432 | 0 | } |
433 | 3.04k | return s0 ? s0 : s1; |
434 | 3.04k | } |