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 56static const uint32_t kSeed = (uint32_t)(time(nullptr)); 57static SkRandom gRand(kSeed); 58static bool return_large = false; 59static bool return_undef = false; 60 61static const int kBitmapSize = 24; 62 63static 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 74static 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 84static 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 107static SkScalar make_scalar(bool positiveOnly = false) { 108 return make_number(positiveOnly); 109} 110 111static 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 120static 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 137static bool make_bool() { 138 return R(2) == 1; 139} 140 141static SkRect make_rect() { 142 return SkRect::MakeWH(SkIntToScalar(R(static_cast<float>(kBitmapSize))), 143 SkIntToScalar(R(static_cast<float>(kBitmapSize)))); 144} 145 146static 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 154static 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 162static SkXfermode::Mode make_xfermode() { 163 return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1)); 164} 165 166static SkPaint::Align make_paint_align() { 167 return static_cast<SkPaint::Align>(R(SkPaint::kRight_Align+1)); 168} 169 170static SkPaint::Hinting make_paint_hinting() { 171 return static_cast<SkPaint::Hinting>(R(SkPaint::kFull_Hinting+1)); 172} 173 174static SkPaint::Style make_paint_style() { 175 return static_cast<SkPaint::Style>(R(SkPaint::kStrokeAndFill_Style+1)); 176} 177 178static SkPaint::Cap make_paint_cap() { 179 return static_cast<SkPaint::Cap>(R(SkPaint::kDefault_Cap+1)); 180} 181 182static SkPaint::Join make_paint_join() { 183 return static_cast<SkPaint::Join>(R(SkPaint::kDefault_Join+1)); 184} 185 186static SkPaint::TextEncoding make_paint_text_encoding() { 187 return static_cast<SkPaint::TextEncoding>(R(SkPaint::kGlyphID_TextEncoding+1)); 188} 189 190static SkBlurStyle make_blur_style() { 191 return static_cast<SkBlurStyle>(R(kLastEnum_SkBlurStyle+1)); 192} 193 194static SkBlurMaskFilter::BlurFlags make_blur_mask_filter_flag() { 195 return static_cast<SkBlurMaskFilter::BlurFlags>(R(SkBlurMaskFilter::kAll_BlurFlag+1)); 196} 197 198static SkFilterQuality make_filter_quality() { 199 return static_cast<SkFilterQuality>(R(kHigh_SkFilterQuality+1)); 200} 201 202static SkTypeface::Style make_typeface_style() { 203 return static_cast<SkTypeface::Style>(R(SkTypeface::kBoldItalic+1)); 204} 205 206static SkPath1DPathEffect::Style make_path_1d_path_effect_style() { 207 return static_cast<SkPath1DPathEffect::Style>(R((int)SkPath1DPathEffect::kLastEnum_Style + 1)); 208} 209 210static SkColor make_color() { 211 return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090; 212} 213 214static SkDropShadowImageFilter::ShadowMode make_shadow_mode() { 215 return (R(2) == 1) ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode : 216 SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode; 217} 218 219static SkPoint3 make_point() { 220 return SkPoint3::Make(make_scalar(), make_scalar(), make_scalar(true)); 221} 222 223static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() { 224 return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1); 225} 226 227static 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 241static SkColorType rand_colortype() { 242 return (SkColorType)R(kLastEnum_SkColorType + 1); 243} 244 245static 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 253static 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 267static 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 291static 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 302static 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 331static 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 348static void rand_color_table(uint8_t* table) { 349 for (int i = 0; i < 256; ++i) { 350 table[i] = R(256); 351 } 352} 353 354static 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 394static 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 426static 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 476static 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 502static SkImageFilter* make_image_filter(bool canBeNull = true); 503 504static 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 559static 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 734static 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 766static 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 774static 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 798class ImageFilterFuzzView : public SampleView { 799public: 800 ImageFilterFuzzView() { 801 this->setBGColor(0xFFDDDDDD); 802 } 803 804protected: 805 // overrides from SkEventSink 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 814 void drawBG(SkCanvas* canvas) { 815 canvas->drawColor(0xFFDDDDDD); 816 } 817 818 virtual void onDrawContent(SkCanvas* canvas) { 819 do_fuzz(canvas); 820 this->inval(0); 821 } 822 823private: 824 typedef SkView INHERITED; 825}; 826 827////////////////////////////////////////////////////////////////////////////// 828 829static SkView* MyFactory() { return new ImageFilterFuzzView; } 830static SkViewRegister reg(MyFactory); 831