1 /*
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 "SampleCode.h"
8 #include "Sk1DPathEffect.h"
9 #include "Sk2DPathEffect.h"
10 #include "SkAlphaThresholdFilter.h"
11 #include "SkArcToPathEffect.h"
12 #include "SkAnnotation.h"
13 #include "SkBlurImageFilter.h"
14 #include "SkBlurMaskFilter.h"
15 #include "SkCanvas.h"
16 #include "SkColorCubeFilter.h"
17 #include "SkColorFilter.h"
18 #include "SkColorFilterImageFilter.h"
19 #include "SkColorMatrixFilter.h"
20 #include "SkComposeImageFilter.h"
21 #include "SkCornerPathEffect.h"
22 #include "SkDashPathEffect.h"
23 #include "SkData.h"
24 #include "SkDiscretePathEffect.h"
25 #include "SkDisplacementMapEffect.h"
26 #include "SkDropShadowImageFilter.h"
27 #include "SkEmbossMaskFilter.h"
28 #include "SkFlattenableSerialization.h"
29 #include "SkImageSource.h"
30 #include "SkLayerRasterizer.h"
31 #include "SkLightingImageFilter.h"
32 #include "SkLumaColorFilter.h"
33 #include "SkMagnifierImageFilter.h"
34 #include "SkMatrixConvolutionImageFilter.h"
35 #include "SkMergeImageFilter.h"
36 #include "SkMorphologyImageFilter.h"
37 #include "SkOffsetImageFilter.h"
38 #include "SkPaintImageFilter.h"
39 #include "SkPerlinNoiseShader.h"
40 #include "SkPictureImageFilter.h"
41 #include "SkPictureRecorder.h"
42 #include "SkPoint3.h"
43 #include "SkRandom.h"
44 #include "SkTableColorFilter.h"
45 #include "SkTestImageFilters.h"
46 #include "SkTileImageFilter.h"
47 #include "SkTypeface.h"
48 #include "SkView.h"
49 #include "SkXfermodeImageFilter.h"
50 #include <stdio.h>
51 #include <time.h>
52 
53 //#define SK_ADD_RANDOM_BIT_FLIPS
54 //#define SK_FUZZER_IS_VERBOSE
55 
56 static const uint32_t kSeed = (uint32_t)(time(nullptr));
57 static SkRandom gRand(kSeed);
58 static bool return_large = false;
59 static bool return_undef = false;
60 
61 static const int kBitmapSize = 24;
62 
R(float x)63 static int R(float x) {
64     return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x);
65 }
66 
67 #if defined _WIN32
68 #pragma warning ( push )
69 // we are intentionally causing an overflow here
70 //      (warning C4756: overflow in constant arithmetic)
71 #pragma warning ( disable : 4756 )
72 #endif
73 
huge()74 static float huge() {
75     double d = 1e100;
76     float f = (float)d;
77     return f;
78 }
79 
80 #if defined _WIN32
81 #pragma warning ( pop )
82 #endif
83 
make_number(bool positiveOnly)84 static float make_number(bool positiveOnly) {
85     float f = positiveOnly ? 1.0f : 0.0f;
86     float v = f;
87     int sel;
88 
89     if (return_large) sel = R(6); else sel = R(4);
90     if (!return_undef && sel == 0) sel = 1;
91 
92     if (R(2) == 1) v = (float)(R(100)+f); else
93 
94     switch (sel) {
95         case 0: break;
96         case 1: v = f; break;
97         case 2: v = 0.000001f; break;
98         case 3: v = 10000.0f; break;
99         case 4: v = 2000000000.0f; break;
100         case 5: v = huge(); break;
101     }
102 
103     if (!positiveOnly && (R(4) == 1)) v = -v;
104     return v;
105 }
106 
make_scalar(bool positiveOnly=false)107 static SkScalar make_scalar(bool positiveOnly = false) {
108     return make_number(positiveOnly);
109 }
110 
make_string()111 static SkString make_string() {
112     int length = R(1000);
113     SkString str(length);
114     for (int i = 0; i < length; ++i) {
115         str[i] = static_cast<char>(R(256));
116     }
117     return str;
118 }
119 
make_font_name()120 static SkString make_font_name() {
121     int sel = R(8);
122 
123     switch(sel) {
124         case 0: return SkString("Courier New");
125         case 1: return SkString("Helvetica");
126         case 2: return SkString("monospace");
127         case 3: return SkString("sans-serif");
128         case 4: return SkString("serif");
129         case 5: return SkString("Times");
130         case 6: return SkString("Times New Roman");
131         case 7:
132         default:
133             return make_string();
134     }
135 }
136 
make_bool()137 static bool make_bool() {
138     return R(2) == 1;
139 }
140 
make_rect()141 static SkRect make_rect() {
142     return SkRect::MakeWH(SkIntToScalar(R(static_cast<float>(kBitmapSize))),
143                           SkIntToScalar(R(static_cast<float>(kBitmapSize))));
144 }
145 
make_region()146 static SkRegion make_region() {
147     SkIRect iRegion = SkIRect::MakeXYWH(R(static_cast<float>(kBitmapSize)),
148                                         R(static_cast<float>(kBitmapSize)),
149                                         R(static_cast<float>(kBitmapSize)),
150                                         R(static_cast<float>(kBitmapSize)));
151     return SkRegion(iRegion);
152 }
153 
make_matrix()154 static SkMatrix make_matrix() {
155     SkMatrix m;
156     for (int i = 0; i < 9; ++i) {
157         m[i] = make_scalar();
158     }
159     return m;
160 }
161 
make_xfermode()162 static SkXfermode::Mode make_xfermode() {
163     return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1));
164 }
165 
make_paint_align()166 static SkPaint::Align make_paint_align() {
167     return static_cast<SkPaint::Align>(R(SkPaint::kRight_Align+1));
168 }
169 
make_paint_hinting()170 static SkPaint::Hinting make_paint_hinting() {
171     return static_cast<SkPaint::Hinting>(R(SkPaint::kFull_Hinting+1));
172 }
173 
make_paint_style()174 static SkPaint::Style make_paint_style() {
175     return static_cast<SkPaint::Style>(R(SkPaint::kStrokeAndFill_Style+1));
176 }
177 
make_paint_cap()178 static SkPaint::Cap make_paint_cap() {
179     return static_cast<SkPaint::Cap>(R(SkPaint::kDefault_Cap+1));
180 }
181 
make_paint_join()182 static SkPaint::Join make_paint_join() {
183     return static_cast<SkPaint::Join>(R(SkPaint::kDefault_Join+1));
184 }
185 
make_paint_text_encoding()186 static SkPaint::TextEncoding make_paint_text_encoding() {
187     return static_cast<SkPaint::TextEncoding>(R(SkPaint::kGlyphID_TextEncoding+1));
188 }
189 
make_blur_style()190 static SkBlurStyle make_blur_style() {
191     return static_cast<SkBlurStyle>(R(kLastEnum_SkBlurStyle+1));
192 }
193 
make_blur_mask_filter_flag()194 static SkBlurMaskFilter::BlurFlags make_blur_mask_filter_flag() {
195     return static_cast<SkBlurMaskFilter::BlurFlags>(R(SkBlurMaskFilter::kAll_BlurFlag+1));
196 }
197 
make_filter_quality()198 static SkFilterQuality make_filter_quality() {
199     return static_cast<SkFilterQuality>(R(kHigh_SkFilterQuality+1));
200 }
201 
make_typeface_style()202 static SkTypeface::Style make_typeface_style() {
203     return static_cast<SkTypeface::Style>(R(SkTypeface::kBoldItalic+1));
204 }
205 
make_path_1d_path_effect_style()206 static SkPath1DPathEffect::Style make_path_1d_path_effect_style() {
207     return static_cast<SkPath1DPathEffect::Style>(R((int)SkPath1DPathEffect::kLastEnum_Style + 1));
208 }
209 
make_color()210 static SkColor make_color() {
211     return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090;
212 }
213 
make_shadow_mode()214 static SkDropShadowImageFilter::ShadowMode make_shadow_mode() {
215     return (R(2) == 1) ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode :
216                          SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode;
217 }
218 
make_point()219 static SkPoint3 make_point() {
220     return SkPoint3::Make(make_scalar(), make_scalar(), make_scalar(true));
221 }
222 
make_channel_selector_type()223 static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() {
224     return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1);
225 }
226 
valid_for_raster_canvas(const SkImageInfo & info)227 static bool valid_for_raster_canvas(const SkImageInfo& info) {
228     switch (info.colorType()) {
229         case kAlpha_8_SkColorType:
230         case kRGB_565_SkColorType:
231             return true;
232         case kN32_SkColorType:
233             return kPremul_SkAlphaType == info.alphaType() ||
234                    kOpaque_SkAlphaType == info.alphaType();
235         default:
236             break;
237     }
238     return false;
239 }
240 
rand_colortype()241 static SkColorType rand_colortype() {
242     return (SkColorType)R(kLastEnum_SkColorType + 1);
243 }
244 
rand_bitmap_for_canvas(SkBitmap * bitmap)245 static void rand_bitmap_for_canvas(SkBitmap* bitmap) {
246     SkImageInfo info;
247     do {
248         info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(),
249                                  kPremul_SkAlphaType);
250     } while (!valid_for_raster_canvas(info) || !bitmap->tryAllocPixels(info));
251 }
252 
make_g_bitmap(SkBitmap & bitmap)253 static void make_g_bitmap(SkBitmap& bitmap) {
254     rand_bitmap_for_canvas(&bitmap);
255 
256     SkCanvas canvas(bitmap);
257     canvas.clear(0x00000000);
258     SkPaint paint;
259     paint.setAntiAlias(true);
260     paint.setColor(0xFF884422);
261     paint.setTextSize(SkIntToScalar(kBitmapSize/2));
262     const char* str = "g";
263     canvas.drawText(str, strlen(str), SkIntToScalar(kBitmapSize/8),
264                     SkIntToScalar(kBitmapSize/4), paint);
265 }
266 
make_checkerboard_bitmap(SkBitmap & bitmap)267 static void make_checkerboard_bitmap(SkBitmap& bitmap) {
268     rand_bitmap_for_canvas(&bitmap);
269 
270     SkCanvas canvas(bitmap);
271     canvas.clear(0x00000000);
272     SkPaint darkPaint;
273     darkPaint.setColor(0xFF804020);
274     SkPaint lightPaint;
275     lightPaint.setColor(0xFF244484);
276     const int i = kBitmapSize / 8;
277     const SkScalar f = SkIntToScalar(i);
278     for (int y = 0; y < kBitmapSize; y += i) {
279         for (int x = 0; x < kBitmapSize; x += i) {
280             canvas.save();
281             canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
282             canvas.drawRect(SkRect::MakeXYWH(0, 0, f, f), darkPaint);
283             canvas.drawRect(SkRect::MakeXYWH(f, 0, f, f), lightPaint);
284             canvas.drawRect(SkRect::MakeXYWH(0, f, f, f), lightPaint);
285             canvas.drawRect(SkRect::MakeXYWH(f, f, f, f), darkPaint);
286             canvas.restore();
287         }
288     }
289 }
290 
make_bitmap()291 static const SkBitmap& make_bitmap() {
292     static SkBitmap bitmap[2];
293     static bool initialized = false;
294     if (!initialized) {
295         make_g_bitmap(bitmap[0]);
296         make_checkerboard_bitmap(bitmap[1]);
297         initialized = true;
298     }
299     return bitmap[R(2)];
300 }
301 
make_3Dlut(int * cubeDimension,bool invR,bool invG,bool invB)302 static SkData* make_3Dlut(int* cubeDimension, bool invR, bool invG, bool invB) {
303     int size = 4 << R(5);
304     SkData* data = SkData::NewUninitialized(sizeof(SkColor) * size * size * size);
305     SkColor* pixels = (SkColor*)(data->writable_data());
306     SkAutoTMalloc<uint8_t> lutMemory(size);
307     SkAutoTMalloc<uint8_t> invLutMemory(size);
308     uint8_t* lut = lutMemory.get();
309     uint8_t* invLut = invLutMemory.get();
310     const int maxIndex = size - 1;
311     for (int i = 0; i < size; i++) {
312         lut[i] = (i * 255) / maxIndex;
313         invLut[i] = ((maxIndex - i) * 255) / maxIndex;
314     }
315     for (int r = 0; r < size; ++r) {
316         for (int g = 0; g < size; ++g) {
317             for (int b = 0; b < size; ++b) {
318                 pixels[(size * ((size * b) + g)) + r] = SkColorSetARGB(0xFF,
319                         invR ? invLut[r] : lut[r],
320                         invG ? invLut[g] : lut[g],
321                         invB ? invLut[b] : lut[b]);
322             }
323         }
324     }
325     if (cubeDimension) {
326         *cubeDimension = size;
327     }
328     return data;
329 }
330 
drawSomething(SkCanvas * canvas)331 static void drawSomething(SkCanvas* canvas) {
332     SkPaint paint;
333 
334     canvas->save();
335     canvas->scale(0.5f, 0.5f);
336     canvas->drawBitmap(make_bitmap(), 0, 0, nullptr);
337     canvas->restore();
338 
339     paint.setAntiAlias(true);
340 
341     paint.setColor(SK_ColorRED);
342     canvas->drawCircle(SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/3), paint);
343     paint.setColor(SK_ColorBLACK);
344     paint.setTextSize(SkIntToScalar(kBitmapSize/3));
345     canvas->drawText("Picture", 7, SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/4), paint);
346 }
347 
rand_color_table(uint8_t * table)348 static void rand_color_table(uint8_t* table) {
349     for (int i = 0; i < 256; ++i) {
350         table[i] = R(256);
351     }
352 }
353 
make_color_filter()354 static SkColorFilter* make_color_filter() {
355     SkColorFilter* colorFilter;
356     switch (R(6)) {
357         case 0: {
358             SkScalar array[20];
359             for (int i = 0; i < 20; ++i) {
360                 array[i] = make_scalar();
361             }
362             colorFilter = SkColorMatrixFilter::Create(array);
363             break;
364         }
365         case 1:
366             colorFilter = SkLumaColorFilter::Create();
367             break;
368         case 2: {
369             uint8_t tableA[256];
370             uint8_t tableR[256];
371             uint8_t tableG[256];
372             uint8_t tableB[256];
373             rand_color_table(tableA);
374             rand_color_table(tableR);
375             rand_color_table(tableG);
376             rand_color_table(tableB);
377             colorFilter = SkTableColorFilter::CreateARGB(tableA, tableR, tableG, tableB);
378             break;
379         }
380         case 3:
381             colorFilter = SkColorFilter::CreateModeFilter(make_color(), make_xfermode());
382             break;
383         case 4:
384             colorFilter = SkColorMatrixFilter::CreateLightingFilter(make_color(), make_color());
385             break;
386         case 5:
387         default:
388             colorFilter = nullptr;
389             break;
390     }
391     return colorFilter;
392 }
393 
make_path()394 static SkPath make_path() {
395     SkPath path;
396     int numOps = R(30);
397     for (int i = 0; i < numOps; ++i) {
398         switch (R(6)) {
399             case 0:
400                 path.moveTo(make_scalar(), make_scalar());
401                 break;
402             case 1:
403                 path.lineTo(make_scalar(), make_scalar());
404                 break;
405             case 2:
406                 path.quadTo(make_scalar(), make_scalar(), make_scalar(), make_scalar());
407                 break;
408             case 3:
409                 path.conicTo(make_scalar(), make_scalar(), make_scalar(), make_scalar(), make_scalar());
410                 break;
411             case 4:
412                 path.cubicTo(make_scalar(), make_scalar(), make_scalar(),
413                              make_scalar(), make_scalar(), make_scalar());
414                 break;
415             case 5:
416             default:
417                 path.arcTo(make_scalar(), make_scalar(), make_scalar(), make_scalar(), make_scalar());
418                 break;
419 
420         }
421     }
422     path.close();
423     return path;
424 }
425 
make_path_effect(bool canBeNull=true)426 static SkPathEffect* make_path_effect(bool canBeNull = true) {
427     SkPathEffect* pathEffect = nullptr;
428     if (canBeNull && (R(3) == 1)) { return pathEffect; }
429 
430     switch (R(9)) {
431         case 0:
432             pathEffect = SkArcToPathEffect::Create(make_scalar(true));
433             break;
434         case 1: {
435             SkAutoTUnref<SkPathEffect> outer(make_path_effect(false));
436             SkAutoTUnref<SkPathEffect> inner(make_path_effect(false));
437             pathEffect = SkComposePathEffect::Create(outer, inner);
438             break;
439         }
440         case 2:
441             pathEffect = SkCornerPathEffect::Create(make_scalar());
442             break;
443         case 3: {
444             int count = R(10);
445             SkScalar intervals[10];
446             for (int i = 0; i < count; ++i) {
447                 intervals[i] = make_scalar();
448             }
449             pathEffect = SkDashPathEffect::Create(intervals, count, make_scalar());
450             break;
451         }
452         case 4:
453             pathEffect = SkDiscretePathEffect::Create(make_scalar(), make_scalar());
454             break;
455         case 5:
456             pathEffect = SkPath1DPathEffect::Create(make_path(),
457                                                     make_scalar(),
458                                                     make_scalar(),
459                                                     make_path_1d_path_effect_style());
460             break;
461         case 6:
462             pathEffect = SkLine2DPathEffect::Create(make_scalar(), make_matrix());
463             break;
464         case 7:
465             pathEffect = SkPath2DPathEffect::Create(make_matrix(), make_path());
466             break;
467         case 8:
468         default:
469             pathEffect = SkSumPathEffect::Create(make_path_effect(false),
470                                                  make_path_effect(false));
471             break;
472     }
473     return pathEffect;
474 }
475 
make_mask_filter()476 static SkMaskFilter* make_mask_filter() {
477     SkMaskFilter* maskFilter;
478     switch (R(3)) {
479         case 0:
480             maskFilter = SkBlurMaskFilter::Create(make_blur_style(),
481                                                   make_scalar(),
482                                                   make_blur_mask_filter_flag());
483         case 1: {
484             SkEmbossMaskFilter::Light light;
485             for (int i = 0; i < 3; ++i) {
486                 light.fDirection[i] = make_scalar();
487             }
488             light.fPad = R(65536);
489             light.fAmbient = R(256);
490             light.fSpecular = R(256);
491             maskFilter = SkEmbossMaskFilter::Create(make_scalar(),
492                                                     light);
493         }
494         case 2:
495         default:
496             maskFilter = nullptr;
497             break;
498     }
499     return maskFilter;
500 }
501 
502 static SkImageFilter* make_image_filter(bool canBeNull = true);
503 
make_paint()504 static SkPaint make_paint() {
505     SkPaint paint;
506     paint.setHinting(make_paint_hinting());
507     paint.setAntiAlias(make_bool());
508     paint.setDither(make_bool());
509     paint.setLinearText(make_bool());
510     paint.setSubpixelText(make_bool());
511     paint.setLCDRenderText(make_bool());
512     paint.setEmbeddedBitmapText(make_bool());
513     paint.setAutohinted(make_bool());
514     paint.setVerticalText(make_bool());
515     paint.setUnderlineText(make_bool());
516     paint.setStrikeThruText(make_bool());
517     paint.setFakeBoldText(make_bool());
518     paint.setDevKernText(make_bool());
519     paint.setFilterQuality(make_filter_quality());
520     paint.setStyle(make_paint_style());
521     paint.setColor(make_color());
522     paint.setStrokeWidth(make_scalar());
523     paint.setStrokeMiter(make_scalar());
524     paint.setStrokeCap(make_paint_cap());
525     paint.setStrokeJoin(make_paint_join());
526     paint.setColorFilter(make_color_filter());
527     paint.setXfermodeMode(make_xfermode());
528     paint.setPathEffect(make_path_effect());
529     paint.setMaskFilter(make_mask_filter());
530 
531     if (false) {
532         // our validating buffer does not support typefaces yet, so skip this for now
533         SkAutoTUnref<SkTypeface> typeface(
534                       SkTypeface::CreateFromName(make_font_name().c_str(), make_typeface_style()));
535         paint.setTypeface(typeface);
536     }
537 
538     SkLayerRasterizer::Builder rasterizerBuilder;
539     SkPaint paintForRasterizer;
540     if (R(2) == 1) {
541         paintForRasterizer = make_paint();
542     }
543     rasterizerBuilder.addLayer(paintForRasterizer);
544     SkAutoTUnref<SkRasterizer> rasterizer(rasterizerBuilder.detachRasterizer());
545     paint.setRasterizer(rasterizer);
546     paint.setImageFilter(make_image_filter());
547     SkAutoDataUnref data(make_3Dlut(nullptr, make_bool(), make_bool(), make_bool()));
548     SkAutoTUnref<SkAnnotation> annotation(
549         SkAnnotation::Create(make_string().c_str(), data));
550     paint.setAnnotation(annotation);
551     paint.setTextAlign(make_paint_align());
552     paint.setTextSize(make_scalar());
553     paint.setTextScaleX(make_scalar());
554     paint.setTextSkewX(make_scalar());
555     paint.setTextEncoding(make_paint_text_encoding());
556     return paint;
557 }
558 
make_image_filter(bool canBeNull)559 static SkImageFilter* make_image_filter(bool canBeNull) {
560     SkImageFilter* filter = 0;
561 
562     // Add a 1 in 3 chance to get a nullptr input
563     if (canBeNull && (R(3) == 1)) { return filter; }
564 
565     enum { ALPHA_THRESHOLD, MERGE, COLOR, LUT3D, BLUR, MAGNIFIER,
566            DOWN_SAMPLE, XFERMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
567            DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW,
568            MORPHOLOGY, BITMAP, DISPLACE, TILE, PICTURE, PAINT, NUM_FILTERS };
569 
570     switch (R(NUM_FILTERS)) {
571     case ALPHA_THRESHOLD:
572         filter = SkAlphaThresholdFilter::Create(make_region(), make_scalar(), make_scalar());
573         break;
574     case MERGE:
575         filter = SkMergeImageFilter::Create(make_image_filter(), make_image_filter(), make_xfermode());
576         break;
577     case COLOR:
578     {
579         SkAutoTUnref<SkColorFilter> cf(make_color_filter());
580         filter = cf.get() ? SkColorFilterImageFilter::Create(cf, make_image_filter()) : 0;
581     }
582         break;
583     case LUT3D:
584     {
585         int cubeDimension;
586         SkAutoDataUnref lut3D(make_3Dlut(&cubeDimension, (R(2) == 1), (R(2) == 1), (R(2) == 1)));
587         SkAutoTUnref<SkColorFilter> cf(SkColorCubeFilter::Create(lut3D, cubeDimension));
588         filter = cf.get() ? SkColorFilterImageFilter::Create(cf, make_image_filter()) : 0;
589     }
590         break;
591     case BLUR:
592         filter = SkBlurImageFilter::Create(make_scalar(true), make_scalar(true), make_image_filter());
593         break;
594     case MAGNIFIER:
595         filter = SkMagnifierImageFilter::Create(make_rect(), make_scalar(true));
596         break;
597     case DOWN_SAMPLE:
598         filter = SkDownSampleImageFilter::Create(make_scalar());
599         break;
600     case XFERMODE:
601     {
602         SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(make_xfermode()));
603         filter = SkXfermodeImageFilter::Create(mode, make_image_filter(), make_image_filter());
604     }
605         break;
606     case OFFSET:
607         filter = SkOffsetImageFilter::Create(make_scalar(), make_scalar(), make_image_filter());
608         break;
609     case MATRIX:
610         filter = SkImageFilter::CreateMatrixFilter(make_matrix(),
611                                                    (SkFilterQuality)R(4),
612                                                    make_image_filter());
613         break;
614     case MATRIX_CONVOLUTION:
615     {
616         SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
617                                                      SkIntToScalar(kBitmapSize)));
618         SkISize size = SkISize::Make(R(10)+1, R(10)+1);
619         int arraySize = size.width() * size.height();
620         SkTArray<SkScalar> kernel(arraySize);
621         for (int i = 0; i < arraySize; ++i) {
622             kernel.push_back() = make_scalar();
623         }
624         SkIPoint kernelOffset = SkIPoint::Make(R(SkIntToScalar(size.width())),
625                                                R(SkIntToScalar(size.height())));
626         filter = SkMatrixConvolutionImageFilter::Create(size,
627                                                         kernel.begin(),
628                                                         make_scalar(),
629                                                         make_scalar(),
630                                                         kernelOffset,
631                                                         (SkMatrixConvolutionImageFilter::TileMode)R(3),
632                                                         R(2) == 1,
633                                                         make_image_filter(),
634                                                         &cropR);
635     }
636         break;
637     case COMPOSE:
638         filter = SkComposeImageFilter::Create(make_image_filter(), make_image_filter());
639         break;
640     case DISTANT_LIGHT:
641         filter = (R(2) == 1) ?
642                  SkLightingImageFilter::CreateDistantLitDiffuse(make_point(),
643                  make_color(), make_scalar(), make_scalar(), make_image_filter()) :
644                  SkLightingImageFilter::CreateDistantLitSpecular(make_point(),
645                  make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)),
646                  make_image_filter());
647         break;
648     case POINT_LIGHT:
649         filter = (R(2) == 1) ?
650                  SkLightingImageFilter::CreatePointLitDiffuse(make_point(),
651                  make_color(), make_scalar(), make_scalar(), make_image_filter()) :
652                  SkLightingImageFilter::CreatePointLitSpecular(make_point(),
653                  make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)),
654                  make_image_filter());
655         break;
656     case SPOT_LIGHT:
657         filter = (R(2) == 1) ?
658                  SkLightingImageFilter::CreateSpotLitDiffuse(SkPoint3::Make(0, 0, 0),
659                  make_point(), make_scalar(), make_scalar(), make_color(),
660                  make_scalar(), make_scalar(), make_image_filter()) :
661                  SkLightingImageFilter::CreateSpotLitSpecular(SkPoint3::Make(0, 0, 0),
662                  make_point(), make_scalar(), make_scalar(), make_color(),
663                  make_scalar(), make_scalar(), SkIntToScalar(R(10)), make_image_filter());
664         break;
665     case NOISE:
666     {
667         SkAutoTUnref<SkShader> shader((R(2) == 1) ?
668             SkPerlinNoiseShader::CreateFractalNoise(
669                 make_scalar(true), make_scalar(true), R(10.0f), make_scalar()) :
670             SkPerlinNoiseShader::CreateTurbulence(
671                 make_scalar(true), make_scalar(true), R(10.0f), make_scalar()));
672         SkPaint paint;
673         paint.setShader(shader);
674         SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
675                                                      SkIntToScalar(kBitmapSize)));
676         filter = SkPaintImageFilter::Create(paint, &cropR);
677     }
678         break;
679     case DROP_SHADOW:
680         filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(), make_scalar(true),
681                     make_scalar(true), make_color(), make_shadow_mode(), make_image_filter(),
682                     nullptr);
683         break;
684     case MORPHOLOGY:
685         if (R(2) == 1) {
686             filter = SkDilateImageFilter::Create(R(static_cast<float>(kBitmapSize)),
687                 R(static_cast<float>(kBitmapSize)), make_image_filter());
688         } else {
689             filter = SkErodeImageFilter::Create(R(static_cast<float>(kBitmapSize)),
690                 R(static_cast<float>(kBitmapSize)), make_image_filter());
691         }
692         break;
693     case BITMAP:
694     {
695         SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(make_bitmap()));
696         if (R(2) == 1) {
697             filter = SkImageSource::Create(image, make_rect(), make_rect(), kHigh_SkFilterQuality);
698         } else {
699             filter = SkImageSource::Create(image);
700         }
701     }
702         break;
703     case DISPLACE:
704         filter = SkDisplacementMapEffect::Create(make_channel_selector_type(),
705                                                  make_channel_selector_type(), make_scalar(),
706                                                  make_image_filter(false), make_image_filter());
707         break;
708     case TILE:
709         filter = SkTileImageFilter::Create(make_rect(), make_rect(), make_image_filter(false));
710         break;
711     case PICTURE:
712     {
713         SkRTreeFactory factory;
714         SkPictureRecorder recorder;
715         SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(kBitmapSize),
716                                                             SkIntToScalar(kBitmapSize),
717                                                             &factory, 0);
718         drawSomething(recordingCanvas);
719         SkAutoTUnref<SkPicture> pict(recorder.endRecording());
720         filter = SkPictureImageFilter::Create(pict.get(), make_rect());
721     }
722         break;
723     case PAINT:
724     {
725         SkImageFilter::CropRect cropR(make_rect());
726         filter = SkPaintImageFilter::Create(make_paint(), &cropR);
727     }
728     default:
729         break;
730     }
731     return (filter || canBeNull) ? filter : make_image_filter(canBeNull);
732 }
733 
make_serialized_image_filter()734 static SkImageFilter* make_serialized_image_filter() {
735     SkAutoTUnref<SkImageFilter> filter(make_image_filter(false));
736     SkAutoTUnref<SkData> data(SkValidatingSerializeFlattenable(filter));
737     const unsigned char* ptr = static_cast<const unsigned char*>(data->data());
738     size_t len = data->size();
739 #ifdef SK_ADD_RANDOM_BIT_FLIPS
740     unsigned char* p = const_cast<unsigned char*>(ptr);
741     for (size_t i = 0; i < len; ++i, ++p) {
742         if (R(250) == 1) { // 0.4% of the time, flip a bit or byte
743             if (R(10) == 1) { // Then 10% of the time, change a whole byte
744                 switch(R(3)) {
745                 case 0:
746                     *p ^= 0xFF; // Flip entire byte
747                     break;
748                 case 1:
749                     *p = 0xFF; // Set all bits to 1
750                     break;
751                 case 2:
752                     *p = 0x00; // Set all bits to 0
753                     break;
754                 }
755             } else {
756                 *p ^= (1 << R(8));
757             }
758         }
759     }
760 #endif // SK_ADD_RANDOM_BIT_FLIPS
761     SkFlattenable* flattenable = SkValidatingDeserializeFlattenable(ptr, len,
762                                     SkImageFilter::GetFlattenableType());
763     return static_cast<SkImageFilter*>(flattenable);
764 }
765 
drawClippedBitmap(SkCanvas * canvas,int x,int y,const SkPaint & paint)766 static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
767     canvas->save();
768     canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
769         SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize)));
770     canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint);
771     canvas->restore();
772 }
773 
do_fuzz(SkCanvas * canvas)774 static void do_fuzz(SkCanvas* canvas) {
775     SkImageFilter* filter = make_serialized_image_filter();
776 
777 #ifdef SK_FUZZER_IS_VERBOSE
778     static uint32_t numFilters = 0;
779     static uint32_t numValidFilters = 0;
780     if (0 == numFilters) {
781         printf("Fuzzing with %u\n", kSeed);
782     }
783     numFilters++;
784     if (filter) {
785         numValidFilters++;
786     }
787     printf("Filter no : %u. Valid filters so far : %u\r", numFilters, numValidFilters);
788     fflush(stdout);
789 #endif
790 
791     SkPaint paint;
792     SkSafeUnref(paint.setImageFilter(filter));
793     drawClippedBitmap(canvas, 0, 0, paint);
794 }
795 
796 //////////////////////////////////////////////////////////////////////////////
797 
798 class ImageFilterFuzzView : public SampleView {
799 public:
ImageFilterFuzzView()800     ImageFilterFuzzView() {
801         this->setBGColor(0xFFDDDDDD);
802     }
803 
804 protected:
805     // overrides from SkEventSink
onQuery(SkEvent * evt)806     virtual bool onQuery(SkEvent* evt) {
807         if (SampleCode::TitleQ(*evt)) {
808             SampleCode::TitleR(evt, "ImageFilterFuzzer");
809             return true;
810         }
811         return this->INHERITED::onQuery(evt);
812     }
813 
drawBG(SkCanvas * canvas)814     void drawBG(SkCanvas* canvas) {
815         canvas->drawColor(0xFFDDDDDD);
816     }
817 
onDrawContent(SkCanvas * canvas)818     virtual void onDrawContent(SkCanvas* canvas) {
819         do_fuzz(canvas);
820         this->inval(0);
821     }
822 
823 private:
824     typedef SkView INHERITED;
825 };
826 
827 //////////////////////////////////////////////////////////////////////////////
828 
MyFactory()829 static SkView* MyFactory() { return new ImageFilterFuzzView; }
830 static SkViewRegister reg(MyFactory);
831