blob: 1953668d0545aa7d4115ace57be63802fba91ec6 [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"
15#include "SkColorCubeFilter.h"
16#include "SkColorFilter.h"
17#include "SkColorFilterImageFilter.h"
18#include "SkColorMatrixFilter.h"
19#include "SkComposeImageFilter.h"
20#include "SkCornerPathEffect.h"
21#include "SkDashPathEffect.h"
22#include "SkData.h"
23#include "SkDiscretePathEffect.h"
24#include "SkDisplacementMapEffect.h"
25#include "SkDropShadowImageFilter.h"
26#include "SkEmbossMaskFilter.h"
27#include "SkFlattenableSerialization.h"
28#include "SkImageSource.h"
29#include "SkLayerRasterizer.h"
30#include "SkLightingImageFilter.h"
31#include "SkLumaColorFilter.h"
32#include "SkMagnifierImageFilter.h"
33#include "SkMatrixConvolutionImageFilter.h"
34#include "SkMergeImageFilter.h"
35#include "SkMorphologyImageFilter.h"
36#include "SkOffsetImageFilter.h"
37#include "SkPaintImageFilter.h"
38#include "SkPerlinNoiseShader.h"
39#include "SkPictureImageFilter.h"
40#include "SkPictureRecorder.h"
41#include "SkPoint3.h"
42#include "SkRandom.h"
43#include "SkTableColorFilter.h"
kjlubick43195932016-04-05 12:48:47 -070044#include "SkTileImageFilter.h"
45#include "SkTypeface.h"
46#include "SkXfermodeImageFilter.h"
Kevin Lubick2f535ce2016-11-01 15:01:12 -040047#include <cmath>
kjlubick43195932016-04-05 12:48:47 -070048#include <stdio.h>
49#include <time.h>
50
51#define SK_ADD_RANDOM_BIT_FLIPS
52
53static Fuzz* fuzz;
54static const int kBitmapSize = 24;
55
kjlubick43195932016-04-05 12:48:47 -070056
Kevin Lubick416b2482016-11-10 16:17:49 -050057// There should be no more than one make_* used as a function argument.
58static bool make_bool() {
59 bool b; fuzz->next(&b);
60 return b;
kjlubick43195932016-04-05 12:48:47 -070061}
62
Kevin Lubick416b2482016-11-10 16:17:49 -050063static float make_number(bool positiveOnly) {
64 float f;
65 fuzz->next(&f);
66 if (positiveOnly) {
67 return std::abs(f);
68 }
kjlubick43195932016-04-05 12:48:47 -070069 return f;
70}
71
kjlubick43195932016-04-05 12:48:47 -070072static SkString make_string() {
Kevin Lubick416b2482016-11-10 16:17:49 -050073 int length;
74 fuzz->nextRange(&length, 0, 1000);
kjlubick43195932016-04-05 12:48:47 -070075 SkString str(length);
76 for (int i = 0; i < length; ++i) {
Kevin Lubick416b2482016-11-10 16:17:49 -050077 char c;
78 fuzz->nextRange(&c, 0, 255);
79 str[i] = c;
kjlubick43195932016-04-05 12:48:47 -070080 }
81 return str;
82}
83
84static SkString make_font_name() {
Kevin Lubick416b2482016-11-10 16:17:49 -050085 int sel;
86 fuzz->nextRange(&sel, 0, 7);
kjlubick43195932016-04-05 12:48:47 -070087
88 switch(sel) {
89 case 0: return SkString("Courier New");
90 case 1: return SkString("Helvetica");
91 case 2: return SkString("monospace");
92 case 3: return SkString("sans-serif");
93 case 4: return SkString("serif");
94 case 5: return SkString("Times");
95 case 6: return SkString("Times New Roman");
96 case 7:
97 default:
98 return make_string();
99 }
100}
101
kjlubick43195932016-04-05 12:48:47 -0700102static SkRect make_rect() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500103 SkScalar w, h;
104 fuzz->nextRange(&w, 0.0f, (float) kBitmapSize-1);
105 fuzz->nextRange(&h, 0.0f, (float) kBitmapSize-1);
106 return SkRect::MakeWH(w, h);
kjlubick43195932016-04-05 12:48:47 -0700107}
108
109static SkRegion make_region() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500110 int32_t x, y, w, h;
111 fuzz->nextRange(&x, 0, kBitmapSize-1);
112 fuzz->nextRange(&y, 0, kBitmapSize-1);
113 fuzz->nextRange(&w, 0, kBitmapSize-1);
114 fuzz->nextRange(&h, 0, kBitmapSize-1);
115 SkIRect iRegion = SkIRect::MakeXYWH(x,y,w,h);
kjlubick43195932016-04-05 12:48:47 -0700116 return SkRegion(iRegion);
117}
118
Kevin Lubick416b2482016-11-10 16:17:49 -0500119static void init_matrix(SkMatrix* m) {
120 SkScalar mat[9];
121 fuzz->nextN(mat, 9);
122 m->set9(mat);
kjlubick43195932016-04-05 12:48:47 -0700123}
124
reed374772b2016-10-05 17:33:02 -0700125static SkBlendMode make_blendmode() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500126 uint8_t i;
127 fuzz->nextRange(&i, 0, (uint8_t)SkBlendMode::kLastMode);
128 return static_cast<SkBlendMode>(i);
kjlubick43195932016-04-05 12:48:47 -0700129}
130
131static SkPaint::Align make_paint_align() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500132 uint8_t i;
133 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kRight_Align);
134 return static_cast<SkPaint::Align>(i);
kjlubick43195932016-04-05 12:48:47 -0700135}
136
137static SkPaint::Hinting make_paint_hinting() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500138 uint8_t i;
139 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kFull_Hinting);
140 return static_cast<SkPaint::Hinting>(i);
kjlubick43195932016-04-05 12:48:47 -0700141}
142
143static SkPaint::Style make_paint_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500144 uint8_t i;
145 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kStrokeAndFill_Style);
146 return static_cast<SkPaint::Style>(i);
kjlubick43195932016-04-05 12:48:47 -0700147}
148
149static SkPaint::Cap make_paint_cap() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500150 uint8_t i;
151 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kDefault_Cap);
152 return static_cast<SkPaint::Cap>(i);
kjlubick43195932016-04-05 12:48:47 -0700153}
154
155static SkPaint::Join make_paint_join() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500156 uint8_t i;
157 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kDefault_Join);
158 return static_cast<SkPaint::Join>(i);
kjlubick43195932016-04-05 12:48:47 -0700159}
160
161static SkPaint::TextEncoding make_paint_text_encoding() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500162 uint8_t i;
163 fuzz->nextRange(&i, 0, (uint8_t)SkPaint::kGlyphID_TextEncoding);
164 return static_cast<SkPaint::TextEncoding>(i);
kjlubick43195932016-04-05 12:48:47 -0700165}
166
167static SkBlurStyle make_blur_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500168 uint8_t i;
169 fuzz->nextRange(&i, 0, (uint8_t)kLastEnum_SkBlurStyle);
170 return static_cast<SkBlurStyle>(i);
kjlubick43195932016-04-05 12:48:47 -0700171}
172
173static SkBlurMaskFilter::BlurFlags make_blur_mask_filter_flag() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500174 uint8_t i;
175 fuzz->nextRange(&i, 0, (uint8_t)SkBlurMaskFilter::kAll_BlurFlag);
176 return static_cast<SkBlurMaskFilter::BlurFlags>(i);
kjlubick43195932016-04-05 12:48:47 -0700177}
178
179static SkFilterQuality make_filter_quality() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500180 uint8_t i;
181 fuzz->nextRange(&i, 0, (uint8_t)kHigh_SkFilterQuality);
182 return static_cast<SkFilterQuality>(i);
kjlubick43195932016-04-05 12:48:47 -0700183}
184
mbocee6a9912016-05-31 11:42:36 -0700185static SkFontStyle make_typeface_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500186 uint8_t i;
187 fuzz->nextRange(&i, 0, (uint8_t)SkTypeface::kBoldItalic);
188 return SkFontStyle::FromOldStyle(i);
kjlubick43195932016-04-05 12:48:47 -0700189}
190
191static SkPath1DPathEffect::Style make_path_1d_path_effect_style() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500192 uint8_t i;
193 fuzz->nextRange(&i, 0, (uint8_t)SkPath1DPathEffect::kLastEnum_Style);
194 return static_cast<SkPath1DPathEffect::Style>(i);
kjlubick43195932016-04-05 12:48:47 -0700195}
196
197static SkColor make_color() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500198 return make_bool() ? 0xFFC0F0A0 : 0xFF000090;
kjlubick43195932016-04-05 12:48:47 -0700199}
200
201static SkDropShadowImageFilter::ShadowMode make_shadow_mode() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500202 return make_bool() ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode :
203 SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode;
kjlubick43195932016-04-05 12:48:47 -0700204}
205
206static SkPoint3 make_point() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500207 SkScalar a, b, c;
208 fuzz->next(&a, &b, &c);
209 c = std::abs(c);
210 return SkPoint3::Make(a, b, c);
kjlubick43195932016-04-05 12:48:47 -0700211}
212
213static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500214 uint8_t i;
215 fuzz->nextRange(&i, 1, (uint8_t)SkDisplacementMapEffect::kA_ChannelSelectorType);
216 return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(i);
kjlubick43195932016-04-05 12:48:47 -0700217}
218
kjlubick43195932016-04-05 12:48:47 -0700219static SkColorType rand_colortype() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500220 uint8_t i;
221 fuzz->nextRange(&i, 0, kLastEnum_SkColorType);
222 return (SkColorType) i;
kjlubick43195932016-04-05 12:48:47 -0700223}
224
225static void rand_bitmap_for_canvas(SkBitmap* bitmap) {
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400226 SkImageInfo info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(),
kjlubick43195932016-04-05 12:48:47 -0700227 kPremul_SkAlphaType);
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400228 if (!bitmap->tryAllocPixels(info)){
229 SkDebugf("Bitmap not allocated\n");
230 }
kjlubick43195932016-04-05 12:48:47 -0700231}
232
233static void make_g_bitmap(SkBitmap& bitmap) {
234 rand_bitmap_for_canvas(&bitmap);
235
236 SkCanvas canvas(bitmap);
237 canvas.clear(0x00000000);
238 SkPaint paint;
239 paint.setAntiAlias(true);
240 paint.setColor(0xFF884422);
241 paint.setTextSize(SkIntToScalar(kBitmapSize/2));
242 const char* str = "g";
243 canvas.drawText(str, strlen(str), SkIntToScalar(kBitmapSize/8),
244 SkIntToScalar(kBitmapSize/4), paint);
245}
246
247static void make_checkerboard_bitmap(SkBitmap& bitmap) {
248 rand_bitmap_for_canvas(&bitmap);
249
250 SkCanvas canvas(bitmap);
251 canvas.clear(0x00000000);
252 SkPaint darkPaint;
253 darkPaint.setColor(0xFF804020);
254 SkPaint lightPaint;
255 lightPaint.setColor(0xFF244484);
256 const int i = kBitmapSize / 8;
257 const SkScalar f = SkIntToScalar(i);
258 for (int y = 0; y < kBitmapSize; y += i) {
259 for (int x = 0; x < kBitmapSize; x += i) {
260 canvas.save();
261 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
262 canvas.drawRect(SkRect::MakeXYWH(0, 0, f, f), darkPaint);
263 canvas.drawRect(SkRect::MakeXYWH(f, 0, f, f), lightPaint);
264 canvas.drawRect(SkRect::MakeXYWH(0, f, f, f), lightPaint);
265 canvas.drawRect(SkRect::MakeXYWH(f, f, f, f), darkPaint);
266 canvas.restore();
267 }
268 }
269}
270
271static const SkBitmap& make_bitmap() {
272 static SkBitmap bitmap[2];
273 static bool initialized = false;
274 if (!initialized) {
275 make_g_bitmap(bitmap[0]);
276 make_checkerboard_bitmap(bitmap[1]);
277 initialized = true;
278 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500279 uint8_t i;
280 fuzz->nextRange(&i, 0, 1);
281 return bitmap[i];
kjlubick43195932016-04-05 12:48:47 -0700282}
283
284static sk_sp<SkData> make_3Dlut(int* cubeDimension, bool invR, bool invG, bool invB) {
Kevin Lubick416b2482016-11-10 16:17:49 -0500285 uint8_t shift;
286 fuzz->nextRange(&shift, 0, 4);
287 int size = 4 << shift;
kjlubick43195932016-04-05 12:48:47 -0700288 auto data = SkData::MakeUninitialized(sizeof(SkColor) * size * size * size);
289 SkColor* pixels = (SkColor*)(data->writable_data());
290 SkAutoTMalloc<uint8_t> lutMemory(size);
291 SkAutoTMalloc<uint8_t> invLutMemory(size);
292 uint8_t* lut = lutMemory.get();
293 uint8_t* invLut = invLutMemory.get();
294 const int maxIndex = size - 1;
295 for (int i = 0; i < size; i++) {
296 lut[i] = (i * 255) / maxIndex;
297 invLut[i] = ((maxIndex - i) * 255) / maxIndex;
298 }
299 for (int r = 0; r < size; ++r) {
300 for (int g = 0; g < size; ++g) {
301 for (int b = 0; b < size; ++b) {
302 pixels[(size * ((size * b) + g)) + r] = SkColorSetARGB(0xFF,
303 invR ? invLut[r] : lut[r],
304 invG ? invLut[g] : lut[g],
305 invB ? invLut[b] : lut[b]);
306 }
307 }
308 }
309 if (cubeDimension) {
310 *cubeDimension = size;
311 }
312 return data;
313}
314
315static void drawSomething(SkCanvas* canvas) {
316 SkPaint paint;
317
318 canvas->save();
319 canvas->scale(0.5f, 0.5f);
320 canvas->drawBitmap(make_bitmap(), 0, 0, nullptr);
321 canvas->restore();
322
323 paint.setAntiAlias(true);
324
325 paint.setColor(SK_ColorRED);
326 canvas->drawCircle(SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/3), paint);
327 paint.setColor(SK_ColorBLACK);
328 paint.setTextSize(SkIntToScalar(kBitmapSize/3));
329 canvas->drawText("Picture", 7, SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/4), paint);
330}
331
kjlubick43195932016-04-05 12:48:47 -0700332static sk_sp<SkColorFilter> make_color_filter() {
Kevin Lubick416b2482016-11-10 16:17:49 -0500333 uint8_t s;
334 fuzz->nextRange(&s, 0, 5);
335 switch (s) {
kjlubick43195932016-04-05 12:48:47 -0700336 case 0: {
337 SkScalar array[20];
Kevin Lubick416b2482016-11-10 16:17:49 -0500338 fuzz->nextN(array, 20);
kjlubick43195932016-04-05 12:48:47 -0700339 return SkColorFilter::MakeMatrixFilterRowMajor255(array);
340 }
341 case 1:
342 return SkLumaColorFilter::Make();
343 case 2: {
344 uint8_t tableA[256];
345 uint8_t tableR[256];
346 uint8_t tableG[256];
347 uint8_t tableB[256];
Kevin Lubick416b2482016-11-10 16:17:49 -0500348 fuzz->nextN(tableA, 256);
349 fuzz->nextN(tableR, 256);
350 fuzz->nextN(tableG, 256);
351 fuzz->nextN(tableB, 256);
kjlubick43195932016-04-05 12:48:47 -0700352 return SkTableColorFilter::MakeARGB(tableA, tableR, tableG, tableB);
353 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500354 case 3: {
355 SkColor c = make_color();
356 SkBlendMode mode = make_blendmode();
357 return SkColorFilter::MakeModeFilter(c, mode);
358 }
359 case 4: {
360 SkColor a = make_color();
361 SkColor b = make_color();
362 return SkColorMatrixFilter::MakeLightingFilter(a, b);
363 }
kjlubick43195932016-04-05 12:48:47 -0700364 case 5:
365 default:
366 break;
367 }
368 return nullptr;
369}
370
371static SkPath make_path() {
372 SkPath path;
Kevin Lubick416b2482016-11-10 16:17:49 -0500373 uint8_t numOps;
374 fuzz->nextRange(&numOps, 0, 30);
375 for (uint8_t i = 0; i < numOps; ++i) {
376 uint8_t op;
377 fuzz->nextRange(&op, 0, 5);
378 SkScalar a, b, c, d, e, f;
379 switch (op) {
kjlubick43195932016-04-05 12:48:47 -0700380 case 0:
Kevin Lubick416b2482016-11-10 16:17:49 -0500381 fuzz->next(&a, &b);
382 path.moveTo(a, b);
kjlubick43195932016-04-05 12:48:47 -0700383 break;
384 case 1:
Kevin Lubick416b2482016-11-10 16:17:49 -0500385 fuzz->next(&a, &b);
386 path.lineTo(a, b);
kjlubick43195932016-04-05 12:48:47 -0700387 break;
388 case 2:
Kevin Lubick416b2482016-11-10 16:17:49 -0500389 fuzz->next(&a, &b, &c, &d);
390 path.quadTo(a, b, c, d);
kjlubick43195932016-04-05 12:48:47 -0700391 break;
392 case 3:
Kevin Lubick416b2482016-11-10 16:17:49 -0500393 fuzz->next(&a, &b, &c, &d, &e);
394 path.conicTo(a, b, c, d, e);
kjlubick43195932016-04-05 12:48:47 -0700395 break;
396 case 4:
Kevin Lubick416b2482016-11-10 16:17:49 -0500397 fuzz->next(&a, &b, &c, &d, &e, &f);
398 path.cubicTo(a, b, c, d, e, f);
kjlubick43195932016-04-05 12:48:47 -0700399 break;
400 case 5:
401 default:
Kevin Lubick416b2482016-11-10 16:17:49 -0500402 fuzz->next(&a, &b, &c, &d, &e);
403 path.arcTo(a, b, c, d, e);
kjlubick43195932016-04-05 12:48:47 -0700404 break;
kjlubick43195932016-04-05 12:48:47 -0700405 }
406 }
407 path.close();
408 return path;
409}
410
411static sk_sp<SkPathEffect> make_path_effect(bool canBeNull = true) {
412 sk_sp<SkPathEffect> pathEffect;
Kevin Lubick416b2482016-11-10 16:17:49 -0500413 uint8_t s;
414 fuzz->nextRange(&s, 0, 2);
415 if (canBeNull && s == 0) { return pathEffect; }
kjlubick43195932016-04-05 12:48:47 -0700416
Kevin Lubick416b2482016-11-10 16:17:49 -0500417 fuzz->nextRange(&s, 0, 8);
418
419 switch (s) {
420 case 0: {
421 SkScalar a = make_number(true);
422 pathEffect = SkArcToPathEffect::Make(a);
kjlubick43195932016-04-05 12:48:47 -0700423 break;
424 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500425 case 1: {
426 sk_sp<SkPathEffect> a = make_path_effect(false);
427 sk_sp<SkPathEffect> b = make_path_effect(false);
428 pathEffect = SkComposePathEffect::Make(a, b);
kjlubick43195932016-04-05 12:48:47 -0700429 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500430 }
431 case 2: {
432 SkScalar a = make_number(false);
433 pathEffect = SkCornerPathEffect::Make(a);
kjlubick43195932016-04-05 12:48:47 -0700434 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500435 }
436 case 3: {
437 uint8_t count;
438 fuzz->nextRange(&count, 0, 9);
439 SkScalar intervals[10];
440 fuzz->nextN(intervals, 10);
441 SkScalar a = make_number(false);
442 pathEffect = SkDashPathEffect::Make(intervals, count, a);
kjlubick43195932016-04-05 12:48:47 -0700443 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500444 }
445 case 4: {
446 SkScalar a, b;
447 fuzz->next(&a, &b);
448 pathEffect = SkDiscretePathEffect::Make(a, b);
kjlubick43195932016-04-05 12:48:47 -0700449 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500450 }
451 case 5: {
452 SkPath path = make_path();
453 SkScalar a, b;
454 fuzz->next(&a, &b);
455 SkPath1DPathEffect::Style style = make_path_1d_path_effect_style();
456 pathEffect = SkPath1DPathEffect::Make(path, a, b, style);
457 break;
458 }
459 case 6: {
460 SkScalar a = make_number(false);
461 SkMatrix m;
462 init_matrix(&m);
463 pathEffect = SkLine2DPathEffect::Make(a, m);
464 break;
465 }
466 case 7: {
467 SkPath path = make_path();
468 SkMatrix m;
469 init_matrix(&m);
470 pathEffect = SkPath2DPathEffect::Make(m, path);
471 break;
472 }
kjlubick43195932016-04-05 12:48:47 -0700473 case 8:
Kevin Lubick416b2482016-11-10 16:17:49 -0500474 default: {
475 sk_sp<SkPathEffect> a = make_path_effect(false);
476 sk_sp<SkPathEffect> b = make_path_effect(false);
477 pathEffect = SkSumPathEffect::Make(a, b);
kjlubick43195932016-04-05 12:48:47 -0700478 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500479 }
kjlubick43195932016-04-05 12:48:47 -0700480 }
481 return pathEffect;
482}
483
484static sk_sp<SkMaskFilter> make_mask_filter() {
485 sk_sp<SkMaskFilter> maskFilter;
Kevin Lubick416b2482016-11-10 16:17:49 -0500486 uint8_t s;
487 fuzz->nextRange(&s, 0, 2);
488 switch (s) {
489 case 0: {
490 SkBlurStyle blur = make_blur_style();
491 SkScalar a = make_number(false);
492 SkBlurMaskFilter::BlurFlags flags = make_blur_mask_filter_flag();
493 maskFilter = SkBlurMaskFilter::Make(blur, a, flags);
494 break;
495 }
kjlubick43195932016-04-05 12:48:47 -0700496 case 1: {
Kevin Lubick416b2482016-11-10 16:17:49 -0500497 SkScalar a = make_number(false);
kjlubick43195932016-04-05 12:48:47 -0700498 SkEmbossMaskFilter::Light light;
Kevin Lubick416b2482016-11-10 16:17:49 -0500499 fuzz->nextN(light.fDirection, 3);
500 fuzz->nextRange(&light.fPad, 0, 65535);
501 fuzz->nextRange(&light.fAmbient, 0, 255);
502 fuzz->nextRange(&light.fSpecular, 0, 255);
503 maskFilter = SkEmbossMaskFilter::Make(a, light);
504 break;
kjlubick43195932016-04-05 12:48:47 -0700505 }
506 case 2:
507 default:
508 break;
509 }
510 return maskFilter;
511}
512
513static sk_sp<SkImageFilter> make_image_filter(bool canBeNull = true);
514
515static SkPaint make_paint() {
516 SkPaint paint;
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400517 if (fuzz->exhausted()) {
518 return paint;
519 }
kjlubick43195932016-04-05 12:48:47 -0700520 paint.setHinting(make_paint_hinting());
521 paint.setAntiAlias(make_bool());
522 paint.setDither(make_bool());
523 paint.setLinearText(make_bool());
524 paint.setSubpixelText(make_bool());
525 paint.setLCDRenderText(make_bool());
526 paint.setEmbeddedBitmapText(make_bool());
527 paint.setAutohinted(make_bool());
528 paint.setVerticalText(make_bool());
529 paint.setUnderlineText(make_bool());
530 paint.setStrikeThruText(make_bool());
531 paint.setFakeBoldText(make_bool());
532 paint.setDevKernText(make_bool());
533 paint.setFilterQuality(make_filter_quality());
534 paint.setStyle(make_paint_style());
535 paint.setColor(make_color());
Kevin Lubick416b2482016-11-10 16:17:49 -0500536 paint.setStrokeWidth(make_number(false));
537 paint.setStrokeMiter(make_number(false));
kjlubick43195932016-04-05 12:48:47 -0700538 paint.setStrokeCap(make_paint_cap());
539 paint.setStrokeJoin(make_paint_join());
540 paint.setColorFilter(make_color_filter());
reed374772b2016-10-05 17:33:02 -0700541 paint.setBlendMode(make_blendmode());
kjlubick43195932016-04-05 12:48:47 -0700542 paint.setPathEffect(make_path_effect());
543 paint.setMaskFilter(make_mask_filter());
544
545 if (false) {
546 // our validating buffer does not support typefaces yet, so skip this for now
bungeman13b9c952016-05-12 10:09:30 -0700547 paint.setTypeface(SkTypeface::MakeFromName(make_font_name().c_str(),make_typeface_style()));
kjlubick43195932016-04-05 12:48:47 -0700548 }
549
550 SkLayerRasterizer::Builder rasterizerBuilder;
551 SkPaint paintForRasterizer;
Kevin Lubick416b2482016-11-10 16:17:49 -0500552 if (make_bool()) {
kjlubick43195932016-04-05 12:48:47 -0700553 paintForRasterizer = make_paint();
554 }
555 rasterizerBuilder.addLayer(paintForRasterizer);
556 paint.setRasterizer(rasterizerBuilder.detach());
557 paint.setImageFilter(make_image_filter());
Kevin Lubick416b2482016-11-10 16:17:49 -0500558 bool a, b, c;
559 fuzz->next(&a, &b, &c);
560 sk_sp<SkData> data(make_3Dlut(nullptr, a, b, c));
kjlubick43195932016-04-05 12:48:47 -0700561 paint.setTextAlign(make_paint_align());
Kevin Lubick416b2482016-11-10 16:17:49 -0500562 SkScalar d, e, f;
563 fuzz->next(&d, &e, &f);
564 paint.setTextSize(d);
565 paint.setTextScaleX(e);
566 paint.setTextSkewX(f);
kjlubick43195932016-04-05 12:48:47 -0700567 paint.setTextEncoding(make_paint_text_encoding());
568 return paint;
569}
570
571static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
572 sk_sp<SkImageFilter> filter;
573
574 // Add a 1 in 3 chance to get a nullptr input
Kevin Lubick416b2482016-11-10 16:17:49 -0500575 uint8_t i;
576 fuzz->nextRange(&i, 0, 2);
577 if (fuzz->exhausted() || (canBeNull && i == 1)) {
kjlubick43195932016-04-05 12:48:47 -0700578 return filter;
579 }
580
581 enum { ALPHA_THRESHOLD, MERGE, COLOR, LUT3D, BLUR, MAGNIFIER,
reed374772b2016-10-05 17:33:02 -0700582 BLENDMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
kjlubick43195932016-04-05 12:48:47 -0700583 DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW,
584 MORPHOLOGY, BITMAP, DISPLACE, TILE, PICTURE, PAINT, NUM_FILTERS };
585
Kevin Lubick416b2482016-11-10 16:17:49 -0500586 uint8_t s;
587 fuzz->nextRange(&s, 0, NUM_FILTERS - 1);
588 switch (s) {
589 case ALPHA_THRESHOLD: {
590 SkRegion reg = make_region();
591 SkScalar innerMin, outerMax;
592 fuzz->next(&innerMin, &outerMax);
593 sk_sp<SkImageFilter> fil = make_image_filter();
594 filter = SkAlphaThresholdFilter::Make(reg, innerMin, outerMax, fil);
kjlubick43195932016-04-05 12:48:47 -0700595 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500596 }
597 case MERGE: {
598 sk_sp<SkImageFilter> filA = make_image_filter();
599 sk_sp<SkImageFilter> filB = make_image_filter();
600 SkBlendMode blend = make_blendmode();
601 filter = SkMergeImageFilter::Make(filA, filB, blend);
kjlubick43195932016-04-05 12:48:47 -0700602 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500603 }
kjlubick43195932016-04-05 12:48:47 -0700604 case COLOR: {
605 sk_sp<SkColorFilter> cf(make_color_filter());
606 filter = cf ? SkColorFilterImageFilter::Make(std::move(cf), make_image_filter())
607 : nullptr;
608 break;
609 }
610 case LUT3D: {
611 int cubeDimension;
Kevin Lubick416b2482016-11-10 16:17:49 -0500612 bool a, b, c;
613 fuzz->next(&a, &b, &c);
614 sk_sp<SkData> lut3D(make_3Dlut(&cubeDimension, a, b, c));
kjlubick43195932016-04-05 12:48:47 -0700615 sk_sp<SkColorFilter> cf(SkColorCubeFilter::Make(std::move(lut3D), cubeDimension));
616 filter = cf ? SkColorFilterImageFilter::Make(std::move(cf), make_image_filter())
617 : nullptr;
618 break;
619 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500620 case BLUR: {
621 SkScalar sX = make_number(true);
622 SkScalar sY = make_number(true);
623 sk_sp<SkImageFilter> fil = make_image_filter();
624
625 filter = SkBlurImageFilter::Make(sX, sY, fil);
kjlubick43195932016-04-05 12:48:47 -0700626 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500627 }
628 case MAGNIFIER: {
629 SkRect rect = make_rect();
630 SkScalar inset = make_number(true);
631 sk_sp<SkImageFilter> fil = make_image_filter();
632 filter = SkMagnifierImageFilter::Make(rect, inset, fil);
kjlubick43195932016-04-05 12:48:47 -0700633 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500634 }
635 case BLENDMODE: {
636 SkBlendMode mode = make_blendmode();
637 sk_sp<SkImageFilter> filA = make_image_filter();
638 sk_sp<SkImageFilter> filB = make_image_filter();
639 filter = SkXfermodeImageFilter::Make(mode, filA, filB, nullptr);
kjlubick43195932016-04-05 12:48:47 -0700640 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500641 }
642 case OFFSET: {
643 SkScalar dx, dy;
644 fuzz->next(&dx, &dy);
645 sk_sp<SkImageFilter> fil = make_image_filter();
646 filter = SkOffsetImageFilter::Make(dx, dy, fil);
kjlubick43195932016-04-05 12:48:47 -0700647 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500648 }
649 case MATRIX: {
650 SkMatrix m;
651 init_matrix(&m);
652 int qual;
653 fuzz->nextRange(&qual, 0, SkFilterQuality::kLast_SkFilterQuality - 1);
654 sk_sp<SkImageFilter> fil = make_image_filter();
655 filter = SkImageFilter::MakeMatrixFilter(m, (SkFilterQuality)qual, fil);
kjlubick43195932016-04-05 12:48:47 -0700656 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500657 }
kjlubick43195932016-04-05 12:48:47 -0700658 case MATRIX_CONVOLUTION: {
659 SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
660 SkIntToScalar(kBitmapSize)));
Kevin Lubick416b2482016-11-10 16:17:49 -0500661 int w, h;
662 fuzz->nextRange(&w, 1, 10);
663 fuzz->nextRange(&h, 1, 10);
664 SkISize size = SkISize::Make(w, h);
kjlubick43195932016-04-05 12:48:47 -0700665 int arraySize = size.width() * size.height();
666 SkTArray<SkScalar> kernel(arraySize);
667 for (int i = 0; i < arraySize; ++i) {
Kevin Lubick416b2482016-11-10 16:17:49 -0500668 kernel.push_back() = make_number(false);
kjlubick43195932016-04-05 12:48:47 -0700669 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500670 fuzz->nextRange(&w, 0, size.width() - 1);
671 fuzz->nextRange(&h, 0, size.height() - 1);
672 SkIPoint kernelOffset = SkIPoint::Make(w, h);
673 int mode;
674 fuzz->nextRange(&mode, 0, SkMatrixConvolutionImageFilter::kMax_TileMode - 1);
675 bool convolveAlpha = make_bool();
676 SkScalar gain, bias;
677 fuzz->next(&gain, &bias);
678 sk_sp<SkImageFilter> fil = make_image_filter();
robertphillipsef6a47b2016-04-08 08:01:20 -0700679 filter = SkMatrixConvolutionImageFilter::Make(size,
680 kernel.begin(),
Kevin Lubick416b2482016-11-10 16:17:49 -0500681 gain,
682 bias,
robertphillipsef6a47b2016-04-08 08:01:20 -0700683 kernelOffset,
Kevin Lubick416b2482016-11-10 16:17:49 -0500684 (SkMatrixConvolutionImageFilter::TileMode)mode,
685 convolveAlpha,
686 fil,
robertphillipsef6a47b2016-04-08 08:01:20 -0700687 &cropR);
kjlubick43195932016-04-05 12:48:47 -0700688 break;
689 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500690 case COMPOSE: {
691 sk_sp<SkImageFilter> filA = make_image_filter();
692 sk_sp<SkImageFilter> filB = make_image_filter();
693 filter = SkComposeImageFilter::Make(filA, filB);
kjlubick43195932016-04-05 12:48:47 -0700694 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500695 }
696 case DISTANT_LIGHT: {
697 SkPoint3 p = make_point();
698 SkColor c = make_color();
699 SkScalar ss, kd;
700 fuzz->next(&ss, &kd);
701 int shininess;
702 fuzz->nextRange(&shininess, 0, 9);
703 sk_sp<SkImageFilter> fil = make_image_filter();
704 filter = make_bool()
705 ? SkLightingImageFilter::MakeDistantLitDiffuse(p, c, ss, kd, fil)
706 : SkLightingImageFilter::MakeDistantLitSpecular(p, c, ss, kd, shininess, fil);
kjlubick43195932016-04-05 12:48:47 -0700707 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500708 }
709 case POINT_LIGHT: {
710 SkPoint3 p = make_point();
711 SkColor c = make_color();
712 SkScalar ss, kd;
713 fuzz->next(&ss, &kd);
714 int shininess;
715 fuzz->nextRange(&shininess, 0, 9);
716 sk_sp<SkImageFilter> fil = make_image_filter();
717 filter = make_bool()
718 ? SkLightingImageFilter::MakePointLitDiffuse(p, c, ss, kd, fil)
719 : SkLightingImageFilter::MakePointLitSpecular(p, c, ss, kd, shininess, fil);
kjlubick43195932016-04-05 12:48:47 -0700720 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500721 }
722 case SPOT_LIGHT: {
723 SkPoint3 p = make_point();
724 SkColor c = make_color();
725 SkScalar se, ca, ss, kd;
726 fuzz->next(&se, &ca, &ss, &kd);
727 int shininess;
728 fuzz->nextRange(&shininess, 0, 9);
729 sk_sp<SkImageFilter> fil = make_image_filter();
730 filter = make_bool()
robertphillips12fa47d2016-04-08 16:28:09 -0700731 ? SkLightingImageFilter::MakeSpotLitDiffuse(SkPoint3::Make(0, 0, 0),
Kevin Lubick416b2482016-11-10 16:17:49 -0500732 p, se, ca, c, ss, kd, fil)
robertphillips12fa47d2016-04-08 16:28:09 -0700733 : SkLightingImageFilter::MakeSpotLitSpecular(SkPoint3::Make(0, 0, 0),
Kevin Lubick416b2482016-11-10 16:17:49 -0500734 p, se, ca, c, ss, kd,
735 shininess, fil);
kjlubick43195932016-04-05 12:48:47 -0700736 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500737 }
kjlubick43195932016-04-05 12:48:47 -0700738 case NOISE: {
Kevin Lubick416b2482016-11-10 16:17:49 -0500739 SkScalar bfx = make_number(true);
740 SkScalar bfy = make_number(true);
741 SkScalar seed = make_number(false);
742 int octaves;
743 fuzz->nextRange(&octaves, 0, 9);
744 sk_sp<SkShader> shader(make_bool()
745 ? SkPerlinNoiseShader::MakeFractalNoise(bfx, bfy, octaves, seed)
746 : SkPerlinNoiseShader::MakeTurbulence(bfx, bfy, octaves, seed));
kjlubick43195932016-04-05 12:48:47 -0700747 SkPaint paint;
748 paint.setShader(shader);
749 SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
750 SkIntToScalar(kBitmapSize)));
751 filter = SkPaintImageFilter::Make(paint, &cropR);
752 break;
753 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500754 case DROP_SHADOW: {
755 SkScalar dx, dy, sx, sy;
756 fuzz->next(&dx, &dy);
757 sx = make_number(true);
758 sy = make_number(true);
759 SkColor c = make_color();
760 SkDropShadowImageFilter::ShadowMode mode = make_shadow_mode();
761 sk_sp<SkImageFilter> fil = make_image_filter();
762 filter = SkDropShadowImageFilter::Make(dx, dy, sx, sy, c, mode, fil, nullptr);
kjlubick43195932016-04-05 12:48:47 -0700763 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500764 }
765 case MORPHOLOGY: {
766 int rx, ry;
767 fuzz->nextRange(&rx, 0, kBitmapSize);
768 fuzz->nextRange(&ry, 0, kBitmapSize);
769 sk_sp<SkImageFilter> fil = make_image_filter();
770 if (make_bool()) {
771 filter = SkDilateImageFilter::Make(rx, ry, fil);
kjlubick43195932016-04-05 12:48:47 -0700772 } else {
Kevin Lubick416b2482016-11-10 16:17:49 -0500773 filter = SkErodeImageFilter::Make(rx, ry, fil);
kjlubick43195932016-04-05 12:48:47 -0700774 }
775 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500776 }
kjlubick43195932016-04-05 12:48:47 -0700777 case BITMAP: {
778 sk_sp<SkImage> image(SkImage::MakeFromBitmap(make_bitmap()));
Kevin Lubick416b2482016-11-10 16:17:49 -0500779 if (make_bool()) {
kjlubick43195932016-04-05 12:48:47 -0700780 filter = SkImageSource::Make(std::move(image),
781 make_rect(),
782 make_rect(),
783 kHigh_SkFilterQuality);
784 } else {
785 filter = SkImageSource::Make(std::move(image));
786 }
787 break;
788 }
Kevin Lubick416b2482016-11-10 16:17:49 -0500789 case DISPLACE: {
790 SkDisplacementMapEffect::ChannelSelectorType x = make_channel_selector_type();
791 SkDisplacementMapEffect::ChannelSelectorType y = make_channel_selector_type();
792 SkScalar scale = make_number(false);
793 sk_sp<SkImageFilter> filA = make_image_filter(false);
794 sk_sp<SkImageFilter> filB = make_image_filter();
795
796 filter = SkDisplacementMapEffect::Make(x, y, scale, filA, filB);
kjlubick43195932016-04-05 12:48:47 -0700797 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500798 }
799 case TILE: {
800 SkRect src = make_rect();
801 SkRect dest = make_rect();
802 sk_sp<SkImageFilter> fil = make_image_filter(false);
803 filter = SkTileImageFilter::Make(src, dest, fil);
kjlubick43195932016-04-05 12:48:47 -0700804 break;
Kevin Lubick416b2482016-11-10 16:17:49 -0500805 }
kjlubick43195932016-04-05 12:48:47 -0700806 case PICTURE: {
807 SkRTreeFactory factory;
808 SkPictureRecorder recorder;
809 SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(kBitmapSize),
810 SkIntToScalar(kBitmapSize),
811 &factory, 0);
812 drawSomething(recordingCanvas);
813 sk_sp<SkPicture> pict(recorder.finishRecordingAsPicture());
814 filter = SkPictureImageFilter::Make(pict, make_rect());
815 break;
816 }
817 case PAINT: {
818 SkImageFilter::CropRect cropR(make_rect());
819 filter = SkPaintImageFilter::Make(make_paint(), &cropR);
820 break;
821 }
822 default:
823 break;
824 }
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400825 return filter;
kjlubick43195932016-04-05 12:48:47 -0700826}
827
Mike Reed5e257172016-11-01 11:22:05 -0400828static sk_sp<SkImageFilter> make_serialized_image_filter() {
kjlubick43195932016-04-05 12:48:47 -0700829 sk_sp<SkImageFilter> filter(make_image_filter(false));
bungemanffae30d2016-08-03 13:32:32 -0700830 sk_sp<SkData> data(SkValidatingSerializeFlattenable(filter.get()));
kjlubick43195932016-04-05 12:48:47 -0700831 const unsigned char* ptr = static_cast<const unsigned char*>(data->data());
832 size_t len = data->size();
833#ifdef SK_ADD_RANDOM_BIT_FLIPS
834 unsigned char* p = const_cast<unsigned char*>(ptr);
835 for (size_t i = 0; i < len; ++i, ++p) {
Kevin Lubick416b2482016-11-10 16:17:49 -0500836 uint8_t j;
837 fuzz->nextRange(&j, 1, 250);
838 if (j == 1) { // 0.4% of the time, flip a bit or byte
839 uint8_t k;
840 fuzz->nextRange(&k, 1, 10);
841 if (k == 1) { // Then 10% of the time, change a whole byte
842 uint8_t s;
843 fuzz->nextRange(&s, 0, 2);
844 switch(s) {
kjlubick43195932016-04-05 12:48:47 -0700845 case 0:
846 *p ^= 0xFF; // Flip entire byte
847 break;
848 case 1:
849 *p = 0xFF; // Set all bits to 1
850 break;
851 case 2:
852 *p = 0x00; // Set all bits to 0
853 break;
854 }
855 } else {
Kevin Lubick416b2482016-11-10 16:17:49 -0500856 uint8_t s;
857 fuzz->nextRange(&s, 0, 7);
858 *p ^= (1 << 7);
kjlubick43195932016-04-05 12:48:47 -0700859 }
860 }
861 }
862#endif // SK_ADD_RANDOM_BIT_FLIPS
Mike Reed5e257172016-11-01 11:22:05 -0400863 return SkValidatingDeserializeImageFilter(ptr, len);
kjlubick43195932016-04-05 12:48:47 -0700864}
865
866static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
867 canvas->save();
868 canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
869 SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize)));
870 canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint);
871 canvas->restore();
872}
873
874DEF_FUZZ(SerializedImageFilter, f) {
875 fuzz = f;
kjlubick43195932016-04-05 12:48:47 -0700876
877 SkPaint paint;
Mike Reed5e257172016-11-01 11:22:05 -0400878 paint.setImageFilter(make_serialized_image_filter());
kjlubick43195932016-04-05 12:48:47 -0700879 SkBitmap bitmap;
880 SkCanvas canvas(bitmap);
881 drawClippedBitmap(&canvas, 0, 0, paint);
882}