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