SampleFilterFuzz.cpp revision f91e3d4f54de9976b6538decadd977b19e49eadd
1 2/* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SampleCode.h" 9#include "SkBicubicImageFilter.h" 10#include "SkBitmapSource.h" 11#include "SkBlurImageFilter.h" 12#include "SkCanvas.h" 13#include "SkColorFilter.h" 14#include "SkColorFilterImageFilter.h" 15#include "SkComposeImageFilter.h" 16#include "SkBitmapDevice.h" 17#include "SkDisplacementMapEffect.h" 18#include "SkDropShadowImageFilter.h" 19#include "SkFlattenableSerialization.h" 20#include "SkLightingImageFilter.h" 21#include "SkMagnifierImageFilter.h" 22#include "SkMergeImageFilter.h" 23#include "SkMorphologyImageFilter.h" 24#include "SkOffsetImageFilter.h" 25#include "SkPerlinNoiseShader.h" 26#include "SkRandom.h" 27#include "SkRectShaderImageFilter.h" 28#include "SkView.h" 29#include "SkXfermodeImageFilter.h" 30 31static const uint32_t kSeed = 1; 32static SkRandom gRand(kSeed); 33static bool return_large = false; 34static bool return_undef = false; 35 36static const int kBitmapSize = 24; 37 38static int R(float x) { 39 return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x); 40} 41 42#if defined _WIN32 43#pragma warning ( push ) 44// we are intentionally causing an overflow here 45// (warning C4756: overflow in constant arithmetic) 46#pragma warning ( disable : 4756 ) 47#endif 48 49static float huge() { 50 double d = 1e100; 51 float f = (float)d; 52 return f; 53} 54 55#if defined _WIN32 56#pragma warning ( pop ) 57#endif 58 59static float make_number(bool positiveOnly) { 60 float f = positiveOnly ? 1.0f : 0.0f; 61 float v = f; 62 int sel; 63 64 if (return_large) sel = R(6); else sel = R(4); 65 if (!return_undef && sel == 0) sel = 1; 66 67 if (R(2) == 1) v = (float)(R(100)+f); else 68 69 switch (sel) { 70 case 0: break; 71 case 1: v = f; break; 72 case 2: v = 0.000001f; break; 73 case 3: v = 10000.0f; break; 74 case 4: v = 2000000000.0f; break; 75 case 5: v = huge(); break; 76 } 77 78 if (!positiveOnly && (R(4) == 1)) v = -v; 79 return v; 80} 81 82static SkScalar make_scalar(bool positiveOnly = false) { 83 return SkFloatToScalar(make_number(positiveOnly)); 84} 85 86static SkRect make_rect(int offset = 1) { 87 return SkRect::MakeWH(SkIntToScalar(R(static_cast<float>(kBitmapSize))+offset), 88 SkIntToScalar(R(static_cast<float>(kBitmapSize))+offset)); 89} 90 91static SkXfermode::Mode make_xfermode() { 92 return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1)); 93} 94 95static SkColor make_color() { 96 return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090; 97} 98 99static SkPoint3 make_point() { 100 return SkPoint3(make_scalar(), make_scalar(), make_scalar(true)); 101} 102 103static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() { 104 return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1); 105} 106 107static void make_g_bitmap(SkBitmap& bitmap) { 108 bitmap.setConfig(SkBitmap::kARGB_8888_Config, kBitmapSize, kBitmapSize); 109 bitmap.allocPixels(); 110 SkBitmapDevice device(bitmap); 111 SkCanvas canvas(&device); 112 canvas.clear(0x00000000); 113 SkPaint paint; 114 paint.setAntiAlias(true); 115 paint.setColor(0xFF884422); 116 paint.setTextSize(SkIntToScalar(kBitmapSize/2)); 117 const char* str = "g"; 118 canvas.drawText(str, strlen(str), SkIntToScalar(kBitmapSize/8), 119 SkIntToScalar(kBitmapSize/4), paint); 120} 121 122static void make_checkerboard_bitmap(SkBitmap& bitmap) { 123 bitmap.setConfig(SkBitmap::kARGB_8888_Config, kBitmapSize, kBitmapSize); 124 bitmap.allocPixels(); 125 SkBitmapDevice device(bitmap); 126 SkCanvas canvas(&device); 127 canvas.clear(0x00000000); 128 SkPaint darkPaint; 129 darkPaint.setColor(0xFF804020); 130 SkPaint lightPaint; 131 lightPaint.setColor(0xFF244484); 132 const int i = kBitmapSize / 8; 133 const SkScalar f = SkIntToScalar(i); 134 for (int y = 0; y < kBitmapSize; y += i) { 135 for (int x = 0; x < kBitmapSize; x += i) { 136 canvas.save(); 137 canvas.translate(SkIntToScalar(x), SkIntToScalar(y)); 138 canvas.drawRect(SkRect::MakeXYWH(0, 0, f, f), darkPaint); 139 canvas.drawRect(SkRect::MakeXYWH(f, 0, f, f), lightPaint); 140 canvas.drawRect(SkRect::MakeXYWH(0, f, f, f), lightPaint); 141 canvas.drawRect(SkRect::MakeXYWH(f, f, f, f), darkPaint); 142 canvas.restore(); 143 } 144 } 145} 146 147static const SkBitmap& make_bitmap() { 148 static SkBitmap bitmap[2]; 149 static bool initialized = false; 150 if (!initialized) { 151 make_g_bitmap(bitmap[0]); 152 make_checkerboard_bitmap(bitmap[1]); 153 initialized = true; 154 } 155 return bitmap[R(2)]; 156} 157 158static SkImageFilter* make_image_filter(bool canBeNull = true) { 159 SkImageFilter* filter = 0; 160 161 // Add a 1 in 3 chance to get a NULL input 162 if (canBeNull && (R(3) == 1)) { return filter; } 163 164 enum { BICUBIC, MERGE, COLOR, BLUR, MAGNIFIER, XFERMODE, OFFSET, COMPOSE, 165 DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW, 166 MORPHOLOGY, BITMAP, DISPLACE, NUM_FILTERS }; 167 168 switch (R(NUM_FILTERS)) { 169 case BICUBIC: 170 // Scale is set to 1 here so that it can fit in the DAG without resizing the output 171 filter = SkBicubicImageFilter::CreateMitchell(SkSize::Make(1, 1), make_image_filter()); 172 break; 173 case MERGE: 174 filter = new SkMergeImageFilter(make_image_filter(), make_image_filter(), make_xfermode()); 175 break; 176 case COLOR: 177 { 178 SkAutoTUnref<SkColorFilter> cf((R(2) == 1) ? 179 SkColorFilter::CreateModeFilter(make_color(), make_xfermode()) : 180 SkColorFilter::CreateLightingFilter(make_color(), make_color())); 181 filter = cf.get() ? SkColorFilterImageFilter::Create(cf, make_image_filter()) : 0; 182 } 183 break; 184 case BLUR: 185 filter = new SkBlurImageFilter(make_scalar(true), make_scalar(true), make_image_filter()); 186 break; 187 case MAGNIFIER: 188 filter = new SkMagnifierImageFilter(make_rect(0), make_scalar(true)); 189 break; 190 case XFERMODE: 191 { 192 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(make_xfermode())); 193 filter = new SkXfermodeImageFilter(mode, make_image_filter(), make_image_filter()); 194 } 195 break; 196 case OFFSET: 197 filter = new SkOffsetImageFilter(make_scalar(), make_scalar(), make_image_filter()); 198 break; 199 case COMPOSE: 200 filter = new SkComposeImageFilter(make_image_filter(), make_image_filter()); 201 break; 202 case DISTANT_LIGHT: 203 filter = (R(2) == 1) ? 204 SkLightingImageFilter::CreateDistantLitDiffuse(make_point(), 205 make_color(), make_scalar(), make_scalar(), make_image_filter()) : 206 SkLightingImageFilter::CreateDistantLitSpecular(make_point(), 207 make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)), 208 make_image_filter()); 209 break; 210 case POINT_LIGHT: 211 filter = (R(2) == 1) ? 212 SkLightingImageFilter::CreatePointLitDiffuse(make_point(), 213 make_color(), make_scalar(), make_scalar(), make_image_filter()) : 214 SkLightingImageFilter::CreatePointLitSpecular(make_point(), 215 make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)), 216 make_image_filter()); 217 break; 218 case SPOT_LIGHT: 219 filter = (R(2) == 1) ? 220 SkLightingImageFilter::CreateSpotLitDiffuse(SkPoint3(0, 0, 0), 221 make_point(), make_scalar(), make_scalar(), make_color(), 222 make_scalar(), make_scalar(), make_image_filter()) : 223 SkLightingImageFilter::CreateSpotLitSpecular(SkPoint3(0, 0, 0), 224 make_point(), make_scalar(), make_scalar(), make_color(), 225 make_scalar(), make_scalar(), SkIntToScalar(R(10)), make_image_filter()); 226 break; 227 case NOISE: 228 { 229 SkAutoTUnref<SkShader> shader((R(2) == 1) ? 230 SkPerlinNoiseShader::CreateFractalNoise( 231 make_scalar(true), make_scalar(true), R(10.0f), make_scalar()) : 232 SkPerlinNoiseShader::CreateTubulence( 233 make_scalar(true), make_scalar(true), R(10.0f), make_scalar())); 234 filter = SkRectShaderImageFilter::Create(shader, 235 SkRect::MakeWH(SkIntToScalar(kBitmapSize), 236 SkIntToScalar(kBitmapSize))); 237 } 238 break; 239 case DROP_SHADOW: 240 filter = new SkDropShadowImageFilter(make_scalar(), make_scalar(), 241 make_scalar(true), make_color(), make_image_filter()); 242 break; 243 case MORPHOLOGY: 244 if (R(2) == 1) 245 filter = new SkDilateImageFilter(R(static_cast<float>(kBitmapSize)), 246 R(static_cast<float>(kBitmapSize)), make_image_filter()); 247 else 248 filter = new SkErodeImageFilter(R(static_cast<float>(kBitmapSize)), 249 R(static_cast<float>(kBitmapSize)), make_image_filter()); 250 break; 251 case BITMAP: 252 filter = new SkBitmapSource(make_bitmap()); 253 break; 254 case DISPLACE: 255 filter = new SkDisplacementMapEffect(make_channel_selector_type(), 256 make_channel_selector_type(), make_scalar(), 257 make_image_filter(false), make_image_filter()); 258 break; 259 default: 260 break; 261 } 262 return (filter || canBeNull) ? filter : make_image_filter(canBeNull); 263} 264 265static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) { 266 canvas->save(); 267 canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), 268 SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize))); 269 canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint); 270 canvas->restore(); 271} 272 273static void do_fuzz(SkCanvas* canvas) { 274 SkPaint paint; 275 paint.setImageFilter(make_image_filter()); 276 drawClippedBitmap(canvas, 0, 0, paint); 277} 278 279////////////////////////////////////////////////////////////////////////////// 280 281class ImageFilterFuzzView : public SampleView { 282public: 283 ImageFilterFuzzView() { 284 this->setBGColor(0xFFDDDDDD); 285 } 286 287protected: 288 // overrides from SkEventSink 289 virtual bool onQuery(SkEvent* evt) { 290 if (SampleCode::TitleQ(*evt)) { 291 SampleCode::TitleR(evt, "ImageFilterFuzzer"); 292 return true; 293 } 294 return this->INHERITED::onQuery(evt); 295 } 296 297 void drawBG(SkCanvas* canvas) { 298 canvas->drawColor(0xFFDDDDDD); 299 } 300 301 virtual void onDrawContent(SkCanvas* canvas) { 302 do_fuzz(canvas); 303 this->inval(0); 304 } 305 306private: 307 typedef SkView INHERITED; 308}; 309 310////////////////////////////////////////////////////////////////////////////// 311 312static SkView* MyFactory() { return new ImageFilterFuzzView; } 313static SkViewRegister reg(MyFactory); 314