blob: e3d30b5af78c779b568b353e6e97d83c9ce7fbdd [file] [log] [blame]
kjlubick43195932016-04-05 12:48:47 -07001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "Fuzz.h"
8#include "Sk1DPathEffect.h"
9#include "Sk2DPathEffect.h"
10#include "SkAlphaThresholdFilter.h"
11#include "SkArcToPathEffect.h"
12#include "SkBlurImageFilter.h"
13#include "SkBlurMaskFilter.h"
14#include "SkCanvas.h"
kjlubick43195932016-04-05 12:48:47 -070015#include "SkColorFilter.h"
16#include "SkColorFilterImageFilter.h"
17#include "SkColorMatrixFilter.h"
18#include "SkComposeImageFilter.h"
19#include "SkCornerPathEffect.h"
20#include "SkDashPathEffect.h"
21#include "SkData.h"
22#include "SkDiscretePathEffect.h"
23#include "SkDisplacementMapEffect.h"
24#include "SkDropShadowImageFilter.h"
25#include "SkEmbossMaskFilter.h"
26#include "SkFlattenableSerialization.h"
27#include "SkImageSource.h"
28#include "SkLayerRasterizer.h"
29#include "SkLightingImageFilter.h"
30#include "SkLumaColorFilter.h"
31#include "SkMagnifierImageFilter.h"
32#include "SkMatrixConvolutionImageFilter.h"
33#include "SkMergeImageFilter.h"
34#include "SkMorphologyImageFilter.h"
35#include "SkOffsetImageFilter.h"
36#include "SkPaintImageFilter.h"
37#include "SkPerlinNoiseShader.h"
38#include "SkPictureImageFilter.h"
39#include "SkPictureRecorder.h"
40#include "SkPoint3.h"
41#include "SkRandom.h"
42#include "SkTableColorFilter.h"
kjlubick43195932016-04-05 12:48:47 -070043#include "SkTileImageFilter.h"
44#include "SkTypeface.h"
45#include "SkXfermodeImageFilter.h"
Kevin Lubick2f535ce2016-11-01 15:01:12 -040046#include <cmath>
kjlubick43195932016-04-05 12:48:47 -070047#include <stdio.h>
48#include <time.h>
49
50#define SK_ADD_RANDOM_BIT_FLIPS
51
52static Fuzz* fuzz;
53static const int kBitmapSize = 24;
54
kjlubick43195932016-04-05 12:48:47 -070055
Kevin Lubick416b2482016-11-10 16:17:49 -050056// There should be no more than one make_* used as a function argument.
57static bool make_bool() {
58 bool b; fuzz->next(&b);
59 return b;
kjlubick43195932016-04-05 12:48:47 -070060}
61
Kevin Lubick416b2482016-11-10 16:17:49 -050062static float make_number(bool positiveOnly) {
63 float f;
64 fuzz->next(&f);
65 if (positiveOnly) {
66 return std::abs(f);
67 }
kjlubick43195932016-04-05 12:48:47 -070068 return f;
69}
70
kjlubick43195932016-04-05 12:48:47 -070071static SkString make_string() {
Kevin Lubick416b2482016-11-10 16:17:49 -050072 int length;
73 fuzz->nextRange(&length, 0, 1000);
kjlubick43195932016-04-05 12:48:47 -070074 SkString str(length);
75 for (int i = 0; i < length; ++i) {
Kevin Lubick416b2482016-11-10 16:17:49 -050076 char c;
77 fuzz->nextRange(&c, 0, 255);
78 str[i] = c;
kjlubick43195932016-04-05 12:48:47 -070079 }
80 return str;
81}
82
83static SkString make_font_name() {
Kevin Lubick416b2482016-11-10 16:17:49 -050084 int sel;
85 fuzz->nextRange(&sel, 0, 7);
kjlubick43195932016-04-05 12:48:47 -070086
87 switch(sel) {
88 case 0: return SkString("Courier New");
89 case 1: return SkString("Helvetica");
90 case 2: return SkString("monospace");
91 case 3: return SkString("sans-serif");
92 case 4: return SkString("serif");
93 case 5: return SkString("Times");
94 case 6: return SkString("Times New Roman");
95 case 7:
96 default:
97 return make_string();
98 }
99}
100
kjlubick43195932016-04-05 12:48:47 -0700101static SkRect make_rect() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500102 SkScalar w, h;
103 fuzz->nextRange(&w, 0.0f, (float) kBitmapSize-1);
104 fuzz->nextRange(&h, 0.0f, (float) kBitmapSize-1);
105 return SkRect::MakeWH(w, h);
kjlubick43195932016-04-05 12:48:47 -0700106}
107
108static SkRegion make_region() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500109 int32_t x, y, w, h;
110 fuzz->nextRange(&x, 0, kBitmapSize-1);
111 fuzz->nextRange(&y, 0, kBitmapSize-1);
112 fuzz->nextRange(&w, 0, kBitmapSize-1);
113 fuzz->nextRange(&h, 0, kBitmapSize-1);
114 SkIRect iRegion = SkIRect::MakeXYWH(x,y,w,h);
kjlubick43195932016-04-05 12:48:47 -0700115 return SkRegion(iRegion);
116}
117
Kevin Lubick416b2482016-11-10 16:17:49 -0500118static void init_matrix(SkMatrix* m) {
119 SkScalar mat[9];
120 fuzz->nextN(mat, 9);
121 m->set9(mat);
kjlubick43195932016-04-05 12:48:47 -0700122}
123
reed374772b2016-10-05 17:33:02 -0700124static SkBlendMode make_blendmode() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500125 uint8_t i;
126 fuzz->nextRange(&i, 0, (uint8_t)SkBlendMode::kLastMode);
127 return static_cast<SkBlendMode>(i);
kjlubick43195932016-04-05 12:48:47 -0700128}
129
130static SkPaint::Align make_paint_align() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500131 uint8_t i;
132 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kRight_Align);
133 return static_cast<SkPaint::Align>(i);
kjlubick43195932016-04-05 12:48:47 -0700134}
135
136static SkPaint::Hinting make_paint_hinting() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500137 uint8_t i;
138 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kFull_Hinting);
139 return static_cast<SkPaint::Hinting>(i);
kjlubick43195932016-04-05 12:48:47 -0700140}
141
142static SkPaint::Style make_paint_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500143 uint8_t i;
144 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kStrokeAndFill_Style);
145 return static_cast<SkPaint::Style>(i);
kjlubick43195932016-04-05 12:48:47 -0700146}
147
148static SkPaint::Cap make_paint_cap() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500149 uint8_t i;
150 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kDefault_Cap);
151 return static_cast<SkPaint::Cap>(i);
kjlubick43195932016-04-05 12:48:47 -0700152}
153
154static SkPaint::Join make_paint_join() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500155 uint8_t i;
156 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kDefault_Join);
157 return static_cast<SkPaint::Join>(i);
kjlubick43195932016-04-05 12:48:47 -0700158}
159
160static SkPaint::TextEncoding make_paint_text_encoding() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500161 uint8_t i;
162 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kGlyphID_TextEncoding);
163 return static_cast<SkPaint::TextEncoding>(i);
kjlubick43195932016-04-05 12:48:47 -0700164}
165
166static SkBlurStyle make_blur_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500167 uint8_t i;
168 fuzz->nextRange(&i, 0, (uint8_t)kLastEnum_SkBlurStyle);
169 return static_cast<SkBlurStyle>(i);
kjlubick43195932016-04-05 12:48:47 -0700170}
171
172static SkBlurMaskFilter::BlurFlags make_blur_mask_filter_flag() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500173 uint8_t i;
174 fuzz->nextRange(&i, 0, (uint8_t)SkBlurMaskFilter::kAll_BlurFlag);
175 return static_cast<SkBlurMaskFilter::BlurFlags>(i);
kjlubick43195932016-04-05 12:48:47 -0700176}
177
178static SkFilterQuality make_filter_quality() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500179 uint8_t i;
180 fuzz->nextRange(&i, 0, (uint8_t)kHigh_SkFilterQuality);
181 return static_cast<SkFilterQuality>(i);
kjlubick43195932016-04-05 12:48:47 -0700182}
183
mbocee6a9912016-05-31 11:42:36 -0700184static SkFontStyle make_typeface_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500185 uint8_t i;
186 fuzz->nextRange(&i, 0, (uint8_t)SkTypeface::kBoldItalic);
187 return SkFontStyle::FromOldStyle(i);
kjlubick43195932016-04-05 12:48:47 -0700188}
189
190static SkPath1DPathEffect::Style make_path_1d_path_effect_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500191 uint8_t i;
192 fuzz->nextRange(&i, 0, (uint8_t)SkPath1DPathEffect::kLastEnum_Style);
193 return static_cast<SkPath1DPathEffect::Style>(i);
kjlubick43195932016-04-05 12:48:47 -0700194}
195
196static SkColor make_color() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500197 return make_bool() ? 0xFFC0F0A0 : 0xFF000090;
kjlubick43195932016-04-05 12:48:47 -0700198}
199
200static SkDropShadowImageFilter::ShadowMode make_shadow_mode() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500201 return make_bool() ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode :
202 SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode;
kjlubick43195932016-04-05 12:48:47 -0700203}
204
205static SkPoint3 make_point() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500206 SkScalar a, b, c;
207 fuzz->next(&a, &b, &c);
208 c = std::abs(c);
209 return SkPoint3::Make(a, b, c);
kjlubick43195932016-04-05 12:48:47 -0700210}
211
212static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500213 uint8_t i;
214 fuzz->nextRange(&i, 1, (uint8_t)SkDisplacementMapEffect::kA_ChannelSelectorType);
215 return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(i);
kjlubick43195932016-04-05 12:48:47 -0700216}
217
kjlubick43195932016-04-05 12:48:47 -0700218static SkColorType rand_colortype() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500219 uint8_t i;
220 fuzz->nextRange(&i, 0, kLastEnum_SkColorType);
221 return (SkColorType) i;
kjlubick43195932016-04-05 12:48:47 -0700222}
223
224static void rand_bitmap_for_canvas(SkBitmap* bitmap) {
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400225 SkImageInfo info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(),
kjlubick43195932016-04-05 12:48:47 -0700226 kPremul_SkAlphaType);
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400227 if (!bitmap->tryAllocPixels(info)){
228 SkDebugf("Bitmap not allocated\n");
229 }
kjlubick43195932016-04-05 12:48:47 -0700230}
231
232static void make_g_bitmap(SkBitmap& bitmap) {
233 rand_bitmap_for_canvas(&bitmap);
234
235 SkCanvas canvas(bitmap);
236 canvas.clear(0x00000000);
237 SkPaint paint;
238 paint.setAntiAlias(true);
239 paint.setColor(0xFF884422);
240 paint.setTextSize(SkIntToScalar(kBitmapSize/2));
241 const char* str = "g";
242 canvas.drawText(str, strlen(str), SkIntToScalar(kBitmapSize/8),
243 SkIntToScalar(kBitmapSize/4), paint);
244}
245
246static void make_checkerboard_bitmap(SkBitmap& bitmap) {
247 rand_bitmap_for_canvas(&bitmap);
248
249 SkCanvas canvas(bitmap);
250 canvas.clear(0x00000000);
251 SkPaint darkPaint;
252 darkPaint.setColor(0xFF804020);
253 SkPaint lightPaint;
254 lightPaint.setColor(0xFF244484);
255 const int i = kBitmapSize / 8;
256 const SkScalar f = SkIntToScalar(i);
257 for (int y = 0; y < kBitmapSize; y += i) {
258 for (int x = 0; x < kBitmapSize; x += i) {
259 canvas.save();
260 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
261 canvas.drawRect(SkRect::MakeXYWH(0, 0, f, f), darkPaint);
262 canvas.drawRect(SkRect::MakeXYWH(f, 0, f, f), lightPaint);
263 canvas.drawRect(SkRect::MakeXYWH(0, f, f, f), lightPaint);
264 canvas.drawRect(SkRect::MakeXYWH(f, f, f, f), darkPaint);
265 canvas.restore();
266 }
267 }
268}
269
270static const SkBitmap& make_bitmap() {
271 static SkBitmap bitmap[2];
272 static bool initialized = false;
273 if (!initialized) {
274 make_g_bitmap(bitmap[0]);
275 make_checkerboard_bitmap(bitmap[1]);
276 initialized = true;
277 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500278 uint8_t i;
279 fuzz->nextRange(&i, 0, 1);
280 return bitmap[i];
kjlubick43195932016-04-05 12:48:47 -0700281}
282
283static sk_sp<SkData> make_3Dlut(int* cubeDimension, bool invR, bool invG, bool invB) {
Kevin Lubick416b2482016-11-10 16:17:49 -0500284 uint8_t shift;
285 fuzz->nextRange(&shift, 0, 4);
286 int size = 4 << shift;
kjlubick43195932016-04-05 12:48:47 -0700287 auto data = SkData::MakeUninitialized(sizeof(SkColor) * size * size * size);
288 SkColor* pixels = (SkColor*)(data->writable_data());
289 SkAutoTMalloc<uint8_t> lutMemory(size);
290 SkAutoTMalloc<uint8_t> invLutMemory(size);
291 uint8_t* lut = lutMemory.get();
292 uint8_t* invLut = invLutMemory.get();
293 const int maxIndex = size - 1;
294 for (int i = 0; i < size; i++) {
295 lut[i] = (i * 255) / maxIndex;
296 invLut[i] = ((maxIndex - i) * 255) / maxIndex;
297 }
298 for (int r = 0; r < size; ++r) {
299 for (int g = 0; g < size; ++g) {
300 for (int b = 0; b < size; ++b) {
301 pixels[(size * ((size * b) + g)) + r] = SkColorSetARGB(0xFF,
302 invR ? invLut[r] : lut[r],
303 invG ? invLut[g] : lut[g],
304 invB ? invLut[b] : lut[b]);
305 }
306 }
307 }
308 if (cubeDimension) {
309 *cubeDimension = size;
310 }
311 return data;
312}
313
314static void drawSomething(SkCanvas* canvas) {
315 SkPaint paint;
316
317 canvas->save();
318 canvas->scale(0.5f, 0.5f);
319 canvas->drawBitmap(make_bitmap(), 0, 0, nullptr);
320 canvas->restore();
321
322 paint.setAntiAlias(true);
323
324 paint.setColor(SK_ColorRED);
325 canvas->drawCircle(SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/3), paint);
326 paint.setColor(SK_ColorBLACK);
327 paint.setTextSize(SkIntToScalar(kBitmapSize/3));
328 canvas->drawText("Picture", 7, SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/4), paint);
329}
330
kjlubick43195932016-04-05 12:48:47 -0700331static sk_sp<SkColorFilter> make_color_filter() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500332 uint8_t s;
333 fuzz->nextRange(&s, 0, 5);
334 switch (s) {
kjlubick43195932016-04-05 12:48:47 -0700335 case 0: {
336 SkScalar array[20];
Kevin Lubick416b2482016-11-10 16:17:49 -0500337 fuzz->nextN(array, 20);
kjlubick43195932016-04-05 12:48:47 -0700338 return SkColorFilter::MakeMatrixFilterRowMajor255(array);
339 }
340 case 1:
341 return SkLumaColorFilter::Make();
342 case 2: {
343 uint8_t tableA[256];
344 uint8_t tableR[256];
345 uint8_t tableG[256];
346 uint8_t tableB[256];
Kevin Lubick416b2482016-11-10 16:17:49 -0500347 fuzz->nextN(tableA, 256);
348 fuzz->nextN(tableR, 256);
349 fuzz->nextN(tableG, 256);
350 fuzz->nextN(tableB, 256);
kjlubick43195932016-04-05 12:48:47 -0700351 return SkTableColorFilter::MakeARGB(tableA, tableR, tableG, tableB);
352 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500353 case 3: {
354 SkColor c = make_color();
355 SkBlendMode mode = make_blendmode();
356 return SkColorFilter::MakeModeFilter(c, mode);
357 }
358 case 4: {
359 SkColor a = make_color();
360 SkColor b = make_color();
361 return SkColorMatrixFilter::MakeLightingFilter(a, b);
362 }
kjlubick43195932016-04-05 12:48:47 -0700363 case 5:
364 default:
365 break;
366 }
367 return nullptr;
368}
369
370static SkPath make_path() {
371 SkPath path;
Kevin Lubick416b2482016-11-10 16:17:49 -0500372 uint8_t numOps;
373 fuzz->nextRange(&numOps, 0, 30);
374 for (uint8_t i = 0; i < numOps; ++i) {
375 uint8_t op;
376 fuzz->nextRange(&op, 0, 5);
377 SkScalar a, b, c, d, e, f;
378 switch (op) {
kjlubick43195932016-04-05 12:48:47 -0700379 case 0:
Kevin Lubick416b2482016-11-10 16:17:49 -0500380 fuzz->next(&a, &b);
381 path.moveTo(a, b);
kjlubick43195932016-04-05 12:48:47 -0700382 break;
383 case 1:
Kevin Lubick416b2482016-11-10 16:17:49 -0500384 fuzz->next(&a, &b);
385 path.lineTo(a, b);
kjlubick43195932016-04-05 12:48:47 -0700386 break;
387 case 2:
Kevin Lubick416b2482016-11-10 16:17:49 -0500388 fuzz->next(&a, &b, &c, &d);
389 path.quadTo(a, b, c, d);
kjlubick43195932016-04-05 12:48:47 -0700390 break;
391 case 3:
Kevin Lubick416b2482016-11-10 16:17:49 -0500392 fuzz->next(&a, &b, &c, &d, &e);
393 path.conicTo(a, b, c, d, e);
kjlubick43195932016-04-05 12:48:47 -0700394 break;
395 case 4:
Kevin Lubick416b2482016-11-10 16:17:49 -0500396 fuzz->next(&a, &b, &c, &d, &e, &f);
397 path.cubicTo(a, b, c, d, e, f);
kjlubick43195932016-04-05 12:48:47 -0700398 break;
399 case 5:
400 default:
Kevin Lubick416b2482016-11-10 16:17:49 -0500401 fuzz->next(&a, &b, &c, &d, &e);
402 path.arcTo(a, b, c, d, e);
kjlubick43195932016-04-05 12:48:47 -0700403 break;
kjlubick43195932016-04-05 12:48:47 -0700404 }
405 }
406 path.close();
407 return path;
408}
409
410static sk_sp<SkPathEffect> make_path_effect(bool canBeNull = true) {
411 sk_sp<SkPathEffect> pathEffect;
Kevin Lubick416b2482016-11-10 16:17:49 -0500412 uint8_t s;
413 fuzz->nextRange(&s, 0, 2);
414 if (canBeNull && s == 0) { return pathEffect; }
kjlubick43195932016-04-05 12:48:47 -0700415
Kevin Lubick416b2482016-11-10 16:17:49 -0500416 fuzz->nextRange(&s, 0, 8);
417
418 switch (s) {
419 case 0: {
420 SkScalar a = make_number(true);
421 pathEffect = SkArcToPathEffect::Make(a);
kjlubick43195932016-04-05 12:48:47 -0700422 break;
423 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500424 case 1: {
425 sk_sp<SkPathEffect> a = make_path_effect(false);
426 sk_sp<SkPathEffect> b = make_path_effect(false);
427 pathEffect = SkComposePathEffect::Make(a, b);
kjlubick43195932016-04-05 12:48:47 -0700428 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500429 }
430 case 2: {
431 SkScalar a = make_number(false);
432 pathEffect = SkCornerPathEffect::Make(a);
kjlubick43195932016-04-05 12:48:47 -0700433 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500434 }
435 case 3: {
436 uint8_t count;
437 fuzz->nextRange(&count, 0, 9);
438 SkScalar intervals[10];
439 fuzz->nextN(intervals, 10);
440 SkScalar a = make_number(false);
441 pathEffect = SkDashPathEffect::Make(intervals, count, a);
kjlubick43195932016-04-05 12:48:47 -0700442 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500443 }
444 case 4: {
445 SkScalar a, b;
446 fuzz->next(&a, &b);
447 pathEffect = SkDiscretePathEffect::Make(a, b);
kjlubick43195932016-04-05 12:48:47 -0700448 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500449 }
450 case 5: {
451 SkPath path = make_path();
452 SkScalar a, b;
453 fuzz->next(&a, &b);
454 SkPath1DPathEffect::Style style = make_path_1d_path_effect_style();
455 pathEffect = SkPath1DPathEffect::Make(path, a, b, style);
456 break;
457 }
458 case 6: {
459 SkScalar a = make_number(false);
460 SkMatrix m;
461 init_matrix(&m);
462 pathEffect = SkLine2DPathEffect::Make(a, m);
463 break;
464 }
465 case 7: {
466 SkPath path = make_path();
467 SkMatrix m;
468 init_matrix(&m);
469 pathEffect = SkPath2DPathEffect::Make(m, path);
470 break;
471 }
kjlubick43195932016-04-05 12:48:47 -0700472 case 8:
Kevin Lubick416b2482016-11-10 16:17:49 -0500473 default: {
474 sk_sp<SkPathEffect> a = make_path_effect(false);
475 sk_sp<SkPathEffect> b = make_path_effect(false);
476 pathEffect = SkSumPathEffect::Make(a, b);
kjlubick43195932016-04-05 12:48:47 -0700477 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500478 }
kjlubick43195932016-04-05 12:48:47 -0700479 }
480 return pathEffect;
481}
482
483static sk_sp<SkMaskFilter> make_mask_filter() {
484 sk_sp<SkMaskFilter> maskFilter;
Kevin Lubick416b2482016-11-10 16:17:49 -0500485 uint8_t s;
486 fuzz->nextRange(&s, 0, 2);
487 switch (s) {
488 case 0: {
489 SkBlurStyle blur = make_blur_style();
490 SkScalar a = make_number(false);
491 SkBlurMaskFilter::BlurFlags flags = make_blur_mask_filter_flag();
492 maskFilter = SkBlurMaskFilter::Make(blur, a, flags);
493 break;
494 }
kjlubick43195932016-04-05 12:48:47 -0700495 case 1: {
Kevin Lubick416b2482016-11-10 16:17:49 -0500496 SkScalar a = make_number(false);
kjlubick43195932016-04-05 12:48:47 -0700497 SkEmbossMaskFilter::Light light;
Kevin Lubick416b2482016-11-10 16:17:49 -0500498 fuzz->nextN(light.fDirection, 3);
499 fuzz->nextRange(&light.fPad, 0, 65535);
500 fuzz->nextRange(&light.fAmbient, 0, 255);
501 fuzz->nextRange(&light.fSpecular, 0, 255);
502 maskFilter = SkEmbossMaskFilter::Make(a, light);
503 break;
kjlubick43195932016-04-05 12:48:47 -0700504 }
505 case 2:
506 default:
507 break;
508 }
509 return maskFilter;
510}
511
512static sk_sp<SkImageFilter> make_image_filter(bool canBeNull = true);
513
514static SkPaint make_paint() {
515 SkPaint paint;
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400516 if (fuzz->exhausted()) {
517 return paint;
518 }
kjlubick43195932016-04-05 12:48:47 -0700519 paint.setHinting(make_paint_hinting());
520 paint.setAntiAlias(make_bool());
521 paint.setDither(make_bool());
522 paint.setLinearText(make_bool());
523 paint.setSubpixelText(make_bool());
524 paint.setLCDRenderText(make_bool());
525 paint.setEmbeddedBitmapText(make_bool());
526 paint.setAutohinted(make_bool());
527 paint.setVerticalText(make_bool());
528 paint.setUnderlineText(make_bool());
529 paint.setStrikeThruText(make_bool());
530 paint.setFakeBoldText(make_bool());
531 paint.setDevKernText(make_bool());
532 paint.setFilterQuality(make_filter_quality());
533 paint.setStyle(make_paint_style());
534 paint.setColor(make_color());
Kevin Lubick416b2482016-11-10 16:17:49 -0500535 paint.setStrokeWidth(make_number(false));
536 paint.setStrokeMiter(make_number(false));
kjlubick43195932016-04-05 12:48:47 -0700537 paint.setStrokeCap(make_paint_cap());
538 paint.setStrokeJoin(make_paint_join());
539 paint.setColorFilter(make_color_filter());
reed374772b2016-10-05 17:33:02 -0700540 paint.setBlendMode(make_blendmode());
kjlubick43195932016-04-05 12:48:47 -0700541 paint.setPathEffect(make_path_effect());
542 paint.setMaskFilter(make_mask_filter());
543
544 if (false) {
545 // our validating buffer does not support typefaces yet, so skip this for now
bungeman13b9c952016-05-12 10:09:30 -0700546 paint.setTypeface(SkTypeface::MakeFromName(make_font_name().c_str(),make_typeface_style()));
kjlubick43195932016-04-05 12:48:47 -0700547 }
548
549 SkLayerRasterizer::Builder rasterizerBuilder;
550 SkPaint paintForRasterizer;
Kevin Lubick416b2482016-11-10 16:17:49 -0500551 if (make_bool()) {
kjlubick43195932016-04-05 12:48:47 -0700552 paintForRasterizer = make_paint();
553 }
554 rasterizerBuilder.addLayer(paintForRasterizer);
555 paint.setRasterizer(rasterizerBuilder.detach());
556 paint.setImageFilter(make_image_filter());
Kevin Lubick416b2482016-11-10 16:17:49 -0500557 bool a, b, c;
558 fuzz->next(&a, &b, &c);
559 sk_sp<SkData> data(make_3Dlut(nullptr, a, b, c));
kjlubick43195932016-04-05 12:48:47 -0700560 paint.setTextAlign(make_paint_align());
Kevin Lubick416b2482016-11-10 16:17:49 -0500561 SkScalar d, e, f;
562 fuzz->next(&d, &e, &f);
563 paint.setTextSize(d);
564 paint.setTextScaleX(e);
565 paint.setTextSkewX(f);
kjlubick43195932016-04-05 12:48:47 -0700566 paint.setTextEncoding(make_paint_text_encoding());
567 return paint;
568}
569
570static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
571 sk_sp<SkImageFilter> filter;
572
573 // Add a 1 in 3 chance to get a nullptr input
Kevin Lubick416b2482016-11-10 16:17:49 -0500574 uint8_t i;
575 fuzz->nextRange(&i, 0, 2);
576 if (fuzz->exhausted() || (canBeNull && i == 1)) {
kjlubick43195932016-04-05 12:48:47 -0700577 return filter;
578 }
579
Mike Kleinefaad3c2017-01-20 17:25:34 -0500580 enum { ALPHA_THRESHOLD, MERGE, COLOR, BLUR, MAGNIFIER,
reed374772b2016-10-05 17:33:02 -0700581 BLENDMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
kjlubick43195932016-04-05 12:48:47 -0700582 DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW,
583 MORPHOLOGY, BITMAP, DISPLACE, TILE, PICTURE, PAINT, NUM_FILTERS };
584
Kevin Lubick416b2482016-11-10 16:17:49 -0500585 uint8_t s;
586 fuzz->nextRange(&s, 0, NUM_FILTERS - 1);
587 switch (s) {
588 case ALPHA_THRESHOLD: {
589 SkRegion reg = make_region();
590 SkScalar innerMin, outerMax;
591 fuzz->next(&innerMin, &outerMax);
592 sk_sp<SkImageFilter> fil = make_image_filter();
593 filter = SkAlphaThresholdFilter::Make(reg, innerMin, outerMax, fil);
kjlubick43195932016-04-05 12:48:47 -0700594 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500595 }
596 case MERGE: {
597 sk_sp<SkImageFilter> filA = make_image_filter();
598 sk_sp<SkImageFilter> filB = make_image_filter();
599 SkBlendMode blend = make_blendmode();
600 filter = SkMergeImageFilter::Make(filA, filB, blend);
kjlubick43195932016-04-05 12:48:47 -0700601 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500602 }
kjlubick43195932016-04-05 12:48:47 -0700603 case COLOR: {
604 sk_sp<SkColorFilter> cf(make_color_filter());
605 filter = cf ? SkColorFilterImageFilter::Make(std::move(cf), make_image_filter())
606 : nullptr;
607 break;
608 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500609 case BLUR: {
610 SkScalar sX = make_number(true);
611 SkScalar sY = make_number(true);
612 sk_sp<SkImageFilter> fil = make_image_filter();
613
614 filter = SkBlurImageFilter::Make(sX, sY, fil);
kjlubick43195932016-04-05 12:48:47 -0700615 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500616 }
617 case MAGNIFIER: {
618 SkRect rect = make_rect();
619 SkScalar inset = make_number(true);
620 sk_sp<SkImageFilter> fil = make_image_filter();
621 filter = SkMagnifierImageFilter::Make(rect, inset, fil);
kjlubick43195932016-04-05 12:48:47 -0700622 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500623 }
624 case BLENDMODE: {
625 SkBlendMode mode = make_blendmode();
626 sk_sp<SkImageFilter> filA = make_image_filter();
627 sk_sp<SkImageFilter> filB = make_image_filter();
628 filter = SkXfermodeImageFilter::Make(mode, filA, filB, nullptr);
kjlubick43195932016-04-05 12:48:47 -0700629 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500630 }
631 case OFFSET: {
632 SkScalar dx, dy;
633 fuzz->next(&dx, &dy);
634 sk_sp<SkImageFilter> fil = make_image_filter();
635 filter = SkOffsetImageFilter::Make(dx, dy, fil);
kjlubick43195932016-04-05 12:48:47 -0700636 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500637 }
638 case MATRIX: {
639 SkMatrix m;
640 init_matrix(&m);
641 int qual;
642 fuzz->nextRange(&qual, 0, SkFilterQuality::kLast_SkFilterQuality - 1);
643 sk_sp<SkImageFilter> fil = make_image_filter();
644 filter = SkImageFilter::MakeMatrixFilter(m, (SkFilterQuality)qual, fil);
kjlubick43195932016-04-05 12:48:47 -0700645 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500646 }
kjlubick43195932016-04-05 12:48:47 -0700647 case MATRIX_CONVOLUTION: {
648 SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
649 SkIntToScalar(kBitmapSize)));
Kevin Lubick416b2482016-11-10 16:17:49 -0500650 int w, h;
651 fuzz->nextRange(&w, 1, 10);
652 fuzz->nextRange(&h, 1, 10);
653 SkISize size = SkISize::Make(w, h);
kjlubick43195932016-04-05 12:48:47 -0700654 int arraySize = size.width() * size.height();
655 SkTArray<SkScalar> kernel(arraySize);
656 for (int i = 0; i < arraySize; ++i) {
Kevin Lubick416b2482016-11-10 16:17:49 -0500657 kernel.push_back() = make_number(false);
kjlubick43195932016-04-05 12:48:47 -0700658 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500659 fuzz->nextRange(&w, 0, size.width() - 1);
660 fuzz->nextRange(&h, 0, size.height() - 1);
661 SkIPoint kernelOffset = SkIPoint::Make(w, h);
662 int mode;
663 fuzz->nextRange(&mode, 0, SkMatrixConvolutionImageFilter::kMax_TileMode - 1);
664 bool convolveAlpha = make_bool();
665 SkScalar gain, bias;
666 fuzz->next(&gain, &bias);
667 sk_sp<SkImageFilter> fil = make_image_filter();
robertphillipsef6a47b2016-04-08 08:01:20 -0700668 filter = SkMatrixConvolutionImageFilter::Make(size,
669 kernel.begin(),
Kevin Lubick416b2482016-11-10 16:17:49 -0500670 gain,
671 bias,
robertphillipsef6a47b2016-04-08 08:01:20 -0700672 kernelOffset,
Kevin Lubick416b2482016-11-10 16:17:49 -0500673 (SkMatrixConvolutionImageFilter::TileMode)mode,
674 convolveAlpha,
675 fil,
robertphillipsef6a47b2016-04-08 08:01:20 -0700676 &cropR);
kjlubick43195932016-04-05 12:48:47 -0700677 break;
678 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500679 case COMPOSE: {
680 sk_sp<SkImageFilter> filA = make_image_filter();
681 sk_sp<SkImageFilter> filB = make_image_filter();
682 filter = SkComposeImageFilter::Make(filA, filB);
kjlubick43195932016-04-05 12:48:47 -0700683 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500684 }
685 case DISTANT_LIGHT: {
686 SkPoint3 p = make_point();
687 SkColor c = make_color();
688 SkScalar ss, kd;
689 fuzz->next(&ss, &kd);
690 int shininess;
691 fuzz->nextRange(&shininess, 0, 9);
692 sk_sp<SkImageFilter> fil = make_image_filter();
693 filter = make_bool()
694 ? SkLightingImageFilter::MakeDistantLitDiffuse(p, c, ss, kd, fil)
695 : SkLightingImageFilter::MakeDistantLitSpecular(p, c, ss, kd, shininess, fil);
kjlubick43195932016-04-05 12:48:47 -0700696 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500697 }
698 case POINT_LIGHT: {
699 SkPoint3 p = make_point();
700 SkColor c = make_color();
701 SkScalar ss, kd;
702 fuzz->next(&ss, &kd);
703 int shininess;
704 fuzz->nextRange(&shininess, 0, 9);
705 sk_sp<SkImageFilter> fil = make_image_filter();
706 filter = make_bool()
707 ? SkLightingImageFilter::MakePointLitDiffuse(p, c, ss, kd, fil)
708 : SkLightingImageFilter::MakePointLitSpecular(p, c, ss, kd, shininess, fil);
kjlubick43195932016-04-05 12:48:47 -0700709 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500710 }
711 case SPOT_LIGHT: {
712 SkPoint3 p = make_point();
713 SkColor c = make_color();
714 SkScalar se, ca, ss, kd;
715 fuzz->next(&se, &ca, &ss, &kd);
716 int shininess;
717 fuzz->nextRange(&shininess, 0, 9);
718 sk_sp<SkImageFilter> fil = make_image_filter();
719 filter = make_bool()
robertphillips12fa47d2016-04-08 16:28:09 -0700720 ? SkLightingImageFilter::MakeSpotLitDiffuse(SkPoint3::Make(0, 0, 0),
Kevin Lubick416b2482016-11-10 16:17:49 -0500721 p, se, ca, c, ss, kd, fil)
robertphillips12fa47d2016-04-08 16:28:09 -0700722 : SkLightingImageFilter::MakeSpotLitSpecular(SkPoint3::Make(0, 0, 0),
Kevin Lubick416b2482016-11-10 16:17:49 -0500723 p, se, ca, c, ss, kd,
724 shininess, fil);
kjlubick43195932016-04-05 12:48:47 -0700725 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500726 }
kjlubick43195932016-04-05 12:48:47 -0700727 case NOISE: {
Kevin Lubick416b2482016-11-10 16:17:49 -0500728 SkScalar bfx = make_number(true);
729 SkScalar bfy = make_number(true);
730 SkScalar seed = make_number(false);
731 int octaves;
732 fuzz->nextRange(&octaves, 0, 9);
733 sk_sp<SkShader> shader(make_bool()
734 ? SkPerlinNoiseShader::MakeFractalNoise(bfx, bfy, octaves, seed)
735 : SkPerlinNoiseShader::MakeTurbulence(bfx, bfy, octaves, seed));
kjlubick43195932016-04-05 12:48:47 -0700736 SkPaint paint;
737 paint.setShader(shader);
738 SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
739 SkIntToScalar(kBitmapSize)));
740 filter = SkPaintImageFilter::Make(paint, &cropR);
741 break;
742 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500743 case DROP_SHADOW: {
744 SkScalar dx, dy, sx, sy;
745 fuzz->next(&dx, &dy);
746 sx = make_number(true);
747 sy = make_number(true);
748 SkColor c = make_color();
749 SkDropShadowImageFilter::ShadowMode mode = make_shadow_mode();
750 sk_sp<SkImageFilter> fil = make_image_filter();
751 filter = SkDropShadowImageFilter::Make(dx, dy, sx, sy, c, mode, fil, nullptr);
kjlubick43195932016-04-05 12:48:47 -0700752 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500753 }
754 case MORPHOLOGY: {
755 int rx, ry;
756 fuzz->nextRange(&rx, 0, kBitmapSize);
757 fuzz->nextRange(&ry, 0, kBitmapSize);
758 sk_sp<SkImageFilter> fil = make_image_filter();
759 if (make_bool()) {
760 filter = SkDilateImageFilter::Make(rx, ry, fil);
kjlubick43195932016-04-05 12:48:47 -0700761 } else {
Kevin Lubick416b2482016-11-10 16:17:49 -0500762 filter = SkErodeImageFilter::Make(rx, ry, fil);
kjlubick43195932016-04-05 12:48:47 -0700763 }
764 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500765 }
kjlubick43195932016-04-05 12:48:47 -0700766 case BITMAP: {
767 sk_sp<SkImage> image(SkImage::MakeFromBitmap(make_bitmap()));
Kevin Lubick416b2482016-11-10 16:17:49 -0500768 if (make_bool()) {
kjlubick43195932016-04-05 12:48:47 -0700769 filter = SkImageSource::Make(std::move(image),
770 make_rect(),
771 make_rect(),
772 kHigh_SkFilterQuality);
773 } else {
774 filter = SkImageSource::Make(std::move(image));
775 }
776 break;
777 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500778 case DISPLACE: {
779 SkDisplacementMapEffect::ChannelSelectorType x = make_channel_selector_type();
780 SkDisplacementMapEffect::ChannelSelectorType y = make_channel_selector_type();
781 SkScalar scale = make_number(false);
782 sk_sp<SkImageFilter> filA = make_image_filter(false);
783 sk_sp<SkImageFilter> filB = make_image_filter();
784
785 filter = SkDisplacementMapEffect::Make(x, y, scale, filA, filB);
kjlubick43195932016-04-05 12:48:47 -0700786 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500787 }
788 case TILE: {
789 SkRect src = make_rect();
790 SkRect dest = make_rect();
791 sk_sp<SkImageFilter> fil = make_image_filter(false);
792 filter = SkTileImageFilter::Make(src, dest, fil);
kjlubick43195932016-04-05 12:48:47 -0700793 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500794 }
kjlubick43195932016-04-05 12:48:47 -0700795 case PICTURE: {
796 SkRTreeFactory factory;
797 SkPictureRecorder recorder;
798 SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(kBitmapSize),
799 SkIntToScalar(kBitmapSize),
800 &factory, 0);
801 drawSomething(recordingCanvas);
802 sk_sp<SkPicture> pict(recorder.finishRecordingAsPicture());
803 filter = SkPictureImageFilter::Make(pict, make_rect());
804 break;
805 }
806 case PAINT: {
807 SkImageFilter::CropRect cropR(make_rect());
808 filter = SkPaintImageFilter::Make(make_paint(), &cropR);
809 break;
810 }
811 default:
812 break;
813 }
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400814 return filter;
kjlubick43195932016-04-05 12:48:47 -0700815}
816
Mike Reed5e257172016-11-01 11:22:05 -0400817static sk_sp<SkImageFilter> make_serialized_image_filter() {
kjlubick43195932016-04-05 12:48:47 -0700818 sk_sp<SkImageFilter> filter(make_image_filter(false));
bungemanffae30d2016-08-03 13:32:32 -0700819 sk_sp<SkData> data(SkValidatingSerializeFlattenable(filter.get()));
kjlubick43195932016-04-05 12:48:47 -0700820 const unsigned char* ptr = static_cast<const unsigned char*>(data->data());
821 size_t len = data->size();
822#ifdef SK_ADD_RANDOM_BIT_FLIPS
823 unsigned char* p = const_cast<unsigned char*>(ptr);
824 for (size_t i = 0; i < len; ++i, ++p) {
Kevin Lubick416b2482016-11-10 16:17:49 -0500825 uint8_t j;
826 fuzz->nextRange(&j, 1, 250);
827 if (j == 1) { // 0.4% of the time, flip a bit or byte
828 uint8_t k;
829 fuzz->nextRange(&k, 1, 10);
830 if (k == 1) { // Then 10% of the time, change a whole byte
831 uint8_t s;
832 fuzz->nextRange(&s, 0, 2);
833 switch(s) {
kjlubick43195932016-04-05 12:48:47 -0700834 case 0:
835 *p ^= 0xFF; // Flip entire byte
836 break;
837 case 1:
838 *p = 0xFF; // Set all bits to 1
839 break;
840 case 2:
841 *p = 0x00; // Set all bits to 0
842 break;
843 }
844 } else {
Kevin Lubick416b2482016-11-10 16:17:49 -0500845 uint8_t s;
846 fuzz->nextRange(&s, 0, 7);
847 *p ^= (1 << 7);
kjlubick43195932016-04-05 12:48:47 -0700848 }
849 }
850 }
851#endif // SK_ADD_RANDOM_BIT_FLIPS
Mike Reed5e257172016-11-01 11:22:05 -0400852 return SkValidatingDeserializeImageFilter(ptr, len);
kjlubick43195932016-04-05 12:48:47 -0700853}
854
855static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
856 canvas->save();
857 canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
858 SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize)));
859 canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint);
860 canvas->restore();
861}
862
863DEF_FUZZ(SerializedImageFilter, f) {
864 fuzz = f;
kjlubick43195932016-04-05 12:48:47 -0700865
866 SkPaint paint;
Mike Reed5e257172016-11-01 11:22:05 -0400867 paint.setImageFilter(make_serialized_image_filter());
kjlubick43195932016-04-05 12:48:47 -0700868 SkBitmap bitmap;
869 SkCanvas canvas(bitmap);
870 drawClippedBitmap(&canvas, 0, 0, paint);
871}