2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
7 #include "SampleCode.h"
8 #include "SkAlphaThresholdFilter.h"
9 #include "SkBitmapSource.h"
10 #include "SkBlurImageFilter.h"
12 #include "SkColorFilter.h"
13 #include "SkColorFilterImageFilter.h"
14 #include "SkComposeImageFilter.h"
16 #include "SkDisplacementMapEffect.h"
17 #include "SkDropShadowImageFilter.h"
18 #include "SkFlattenableSerialization.h"
19 #include "SkLightingImageFilter.h"
20 #include "SkMagnifierImageFilter.h"
21 #include "SkMatrixImageFilter.h"
22 #include "SkMatrixConvolutionImageFilter.h"
23 #include "SkMergeImageFilter.h"
24 #include "SkMorphologyImageFilter.h"
25 #include "SkOffsetImageFilter.h"
26 #include "SkPerlinNoiseShader.h"
27 #include "SkPictureImageFilter.h"
28 #include "SkPictureRecorder.h"
30 #include "SkRectShaderImageFilter.h"
31 #include "SkTestImageFilters.h"
32 #include "SkTileImageFilter.h"
34 #include "SkXfermodeImageFilter.h"
38 //#define SK_ADD_RANDOM_BIT_FLIPS
39 //#define SK_FUZZER_IS_VERBOSE
41 static const uint32_t kSeed = (uint32_t)(time(NULL));
42 static SkRandom gRand(kSeed);
43 static bool return_large = false;
44 static bool return_undef = false;
46 static const int kBitmapSize = 24;
48 static int R(float x) {
49 return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x);
53 #pragma warning ( push )
54 // we are intentionally causing an overflow here
55 // (warning C4756: overflow in constant arithmetic)
56 #pragma warning ( disable : 4756 )
66 #pragma warning ( pop )
69 static float make_number(bool positiveOnly) {
70 float f = positiveOnly ? 1.0f : 0.0f;
74 if (return_large) sel = R(6); else sel = R(4);
75 if (!return_undef && sel == 0) sel = 1;
77 if (R(2) == 1) v = (float)(R(100)+f); else
82 case 2: v = 0.000001f; break;
83 case 3: v = 10000.0f; break;
84 case 4: v = 2000000000.0f; break;
85 case 5: v = huge(); break;
88 if (!positiveOnly && (R(4) == 1)) v = -v;
92 static SkScalar make_scalar(bool positiveOnly = false) {
93 return make_number(positiveOnly);
96 static SkRect make_rect() {
97 return SkRect::MakeWH(SkIntToScalar(R(static_cast<float>(kBitmapSize))),
98 SkIntToScalar(R(static_cast<float>(kBitmapSize))));
101 static SkRegion make_region() {
102 SkIRect iRegion = SkIRect::MakeXYWH(R(static_cast<float>(kBitmapSize)),
103 R(static_cast<float>(kBitmapSize)),
104 R(static_cast<float>(kBitmapSize)),
105 R(static_cast<float>(kBitmapSize)));
106 return SkRegion(iRegion);
109 static SkMatrix make_matrix() {
111 for (int i = 0; i < 9; ++i) {
112 m[i] = make_scalar();
117 static SkXfermode::Mode make_xfermode() {
118 return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1));
121 static SkColor make_color() {
122 return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090;
125 static SkPoint3 make_point() {
126 return SkPoint3(make_scalar(), make_scalar(), make_scalar(true));
129 static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() {
130 return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1);
133 static bool valid_for_raster_canvas(const SkImageInfo& info) {
134 switch (info.colorType()) {
135 case kAlpha_8_SkColorType:
136 case kRGB_565_SkColorType:
138 case kN32_SkColorType:
139 return kPremul_SkAlphaType == info.alphaType() ||
140 kOpaque_SkAlphaType == info.alphaType();
147 static SkColorType rand_colortype() {
148 return (SkColorType)R(kLastEnum_SkColorType + 1);
151 static void rand_bitmap_for_canvas(SkBitmap* bitmap) {
154 info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(),
155 kPremul_SkAlphaType);
156 } while (!valid_for_raster_canvas(info) || !bitmap->tryAllocPixels(info));
159 static void make_g_bitmap(SkBitmap& bitmap) {
160 rand_bitmap_for_canvas(&bitmap);
162 SkCanvas canvas(bitmap);
163 canvas.clear(0x00000000);
165 paint.setAntiAlias(true);
166 paint.setColor(0xFF884422);
167 paint.setTextSize(SkIntToScalar(kBitmapSize/2));
168 const char* str = "g";
169 canvas.drawText(str, strlen(str), SkIntToScalar(kBitmapSize/8),
170 SkIntToScalar(kBitmapSize/4), paint);
173 static void make_checkerboard_bitmap(SkBitmap& bitmap) {
174 rand_bitmap_for_canvas(&bitmap);
176 SkCanvas canvas(bitmap);
177 canvas.clear(0x00000000);
179 darkPaint.setColor(0xFF804020);
181 lightPaint.setColor(0xFF244484);
182 const int i = kBitmapSize / 8;
183 const SkScalar f = SkIntToScalar(i);
184 for (int y = 0; y < kBitmapSize; y += i) {
185 for (int x = 0; x < kBitmapSize; x += i) {
187 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
188 canvas.drawRect(SkRect::MakeXYWH(0, 0, f, f), darkPaint);
189 canvas.drawRect(SkRect::MakeXYWH(f, 0, f, f), lightPaint);
190 canvas.drawRect(SkRect::MakeXYWH(0, f, f, f), lightPaint);
191 canvas.drawRect(SkRect::MakeXYWH(f, f, f, f), darkPaint);
197 static const SkBitmap& make_bitmap() {
198 static SkBitmap bitmap[2];
199 static bool initialized = false;
201 make_g_bitmap(bitmap[0]);
202 make_checkerboard_bitmap(bitmap[1]);
208 static void drawSomething(SkCanvas* canvas) {
212 canvas->scale(0.5f, 0.5f);
213 canvas->drawBitmap(make_bitmap(), 0, 0, NULL);
216 const char beforeStr[] = "before circle";
217 const char afterStr[] = "after circle";
219 paint.setAntiAlias(true);
221 paint.setColor(SK_ColorRED);
222 canvas->drawData(beforeStr, sizeof(beforeStr));
223 canvas->drawCircle(SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/3), paint);
224 canvas->drawData(afterStr, sizeof(afterStr));
225 paint.setColor(SK_ColorBLACK);
226 paint.setTextSize(SkIntToScalar(kBitmapSize/3));
227 canvas->drawText("Picture", 7, SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/4), paint);
230 static SkImageFilter* make_image_filter(bool canBeNull = true) {
231 SkImageFilter* filter = 0;
233 // Add a 1 in 3 chance to get a NULL input
234 if (canBeNull && (R(3) == 1)) { return filter; }
236 enum { ALPHA_THRESHOLD, MERGE, COLOR, BLUR, MAGNIFIER,
237 DOWN_SAMPLE, XFERMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
238 DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW,
239 MORPHOLOGY, BITMAP, DISPLACE, TILE, PICTURE, NUM_FILTERS };
241 switch (R(NUM_FILTERS)) {
242 case ALPHA_THRESHOLD:
243 filter = SkAlphaThresholdFilter::Create(make_region(), make_scalar(), make_scalar());
246 filter = SkMergeImageFilter::Create(make_image_filter(), make_image_filter(), make_xfermode());
250 SkAutoTUnref<SkColorFilter> cf((R(2) == 1) ?
251 SkColorFilter::CreateModeFilter(make_color(), make_xfermode()) :
252 SkColorFilter::CreateLightingFilter(make_color(), make_color()));
253 filter = cf.get() ? SkColorFilterImageFilter::Create(cf, make_image_filter()) : 0;
257 filter = SkBlurImageFilter::Create(make_scalar(true), make_scalar(true), make_image_filter());
260 filter = SkMagnifierImageFilter::Create(make_rect(), make_scalar(true));
263 filter = SkDownSampleImageFilter::Create(make_scalar());
267 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(make_xfermode()));
268 filter = SkXfermodeImageFilter::Create(mode, make_image_filter(), make_image_filter());
272 filter = SkOffsetImageFilter::Create(make_scalar(), make_scalar(), make_image_filter());
275 filter = SkMatrixImageFilter::Create(make_matrix(),
276 (SkPaint::FilterLevel)R(4),
277 make_image_filter());
279 case MATRIX_CONVOLUTION:
281 SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
282 SkIntToScalar(kBitmapSize)));
283 SkISize size = SkISize::Make(R(10)+1, R(10)+1);
284 int arraySize = size.width() * size.height();
285 SkTArray<SkScalar> kernel(arraySize);
286 for (int i = 0; i < arraySize; ++i) {
287 kernel.push_back() = make_scalar();
289 SkIPoint kernelOffset = SkIPoint::Make(R(SkIntToScalar(size.width())),
290 R(SkIntToScalar(size.height())));
291 filter = SkMatrixConvolutionImageFilter::Create(size,
296 (SkMatrixConvolutionImageFilter::TileMode)R(3),
303 filter = SkComposeImageFilter::Create(make_image_filter(), make_image_filter());
306 filter = (R(2) == 1) ?
307 SkLightingImageFilter::CreateDistantLitDiffuse(make_point(),
308 make_color(), make_scalar(), make_scalar(), make_image_filter()) :
309 SkLightingImageFilter::CreateDistantLitSpecular(make_point(),
310 make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)),
311 make_image_filter());
314 filter = (R(2) == 1) ?
315 SkLightingImageFilter::CreatePointLitDiffuse(make_point(),
316 make_color(), make_scalar(), make_scalar(), make_image_filter()) :
317 SkLightingImageFilter::CreatePointLitSpecular(make_point(),
318 make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)),
319 make_image_filter());
322 filter = (R(2) == 1) ?
323 SkLightingImageFilter::CreateSpotLitDiffuse(SkPoint3(0, 0, 0),
324 make_point(), make_scalar(), make_scalar(), make_color(),
325 make_scalar(), make_scalar(), make_image_filter()) :
326 SkLightingImageFilter::CreateSpotLitSpecular(SkPoint3(0, 0, 0),
327 make_point(), make_scalar(), make_scalar(), make_color(),
328 make_scalar(), make_scalar(), SkIntToScalar(R(10)), make_image_filter());
332 SkAutoTUnref<SkShader> shader((R(2) == 1) ?
333 SkPerlinNoiseShader::CreateFractalNoise(
334 make_scalar(true), make_scalar(true), R(10.0f), make_scalar()) :
335 SkPerlinNoiseShader::CreateTurbulence(
336 make_scalar(true), make_scalar(true), R(10.0f), make_scalar()));
337 SkImageFilter::CropRect cropR(SkRect::MakeWH(SkIntToScalar(kBitmapSize),
338 SkIntToScalar(kBitmapSize)));
339 filter = SkRectShaderImageFilter::Create(shader, &cropR);
343 filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(),
344 make_scalar(true), make_scalar(true), make_color(), make_image_filter());
348 filter = SkDilateImageFilter::Create(R(static_cast<float>(kBitmapSize)),
349 R(static_cast<float>(kBitmapSize)), make_image_filter());
351 filter = SkErodeImageFilter::Create(R(static_cast<float>(kBitmapSize)),
352 R(static_cast<float>(kBitmapSize)), make_image_filter());
357 filter = SkBitmapSource::Create(make_bitmap(), make_rect(), make_rect());
359 filter = SkBitmapSource::Create(make_bitmap());
363 filter = SkDisplacementMapEffect::Create(make_channel_selector_type(),
364 make_channel_selector_type(), make_scalar(),
365 make_image_filter(false), make_image_filter());
368 filter = SkTileImageFilter::Create(make_rect(), make_rect(), make_image_filter(false));
372 SkRTreeFactory factory;
373 SkPictureRecorder recorder;
374 SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(kBitmapSize),
375 SkIntToScalar(kBitmapSize),
377 drawSomething(recordingCanvas);
378 SkAutoTUnref<SkPicture> pict(recorder.endRecording());
379 filter = SkPictureImageFilter::Create(pict.get(), make_rect());
385 return (filter || canBeNull) ? filter : make_image_filter(canBeNull);
388 static SkImageFilter* make_serialized_image_filter() {
389 SkAutoTUnref<SkImageFilter> filter(make_image_filter(false));
390 SkAutoTUnref<SkData> data(SkValidatingSerializeFlattenable(filter));
391 const unsigned char* ptr = static_cast<const unsigned char*>(data->data());
392 size_t len = data->size();
393 #ifdef SK_ADD_RANDOM_BIT_FLIPS
394 unsigned char* p = const_cast<unsigned char*>(ptr);
395 for (size_t i = 0; i < len; ++i, ++p) {
396 if (R(250) == 1) { // 0.4% of the time, flip a bit or byte
397 if (R(10) == 1) { // Then 10% of the time, change a whole byte
400 *p ^= 0xFF; // Flip entire byte
403 *p = 0xFF; // Set all bits to 1
406 *p = 0x00; // Set all bits to 0
414 #endif // SK_ADD_RANDOM_BIT_FLIPS
415 SkFlattenable* flattenable = SkValidatingDeserializeFlattenable(ptr, len,
416 SkImageFilter::GetFlattenableType());
417 return static_cast<SkImageFilter*>(flattenable);
420 static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
422 canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
423 SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize)));
424 canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint);
428 static void do_fuzz(SkCanvas* canvas) {
429 SkImageFilter* filter = make_serialized_image_filter();
431 #ifdef SK_FUZZER_IS_VERBOSE
432 static uint32_t numFilters = 0;
433 static uint32_t numValidFilters = 0;
434 if (0 == numFilters) {
435 printf("Fuzzing with %u\n", kSeed);
441 printf("Filter no : %u. Valid filters so far : %u\r", numFilters, numValidFilters);
446 SkSafeUnref(paint.setImageFilter(filter));
447 drawClippedBitmap(canvas, 0, 0, paint);
450 //////////////////////////////////////////////////////////////////////////////
452 class ImageFilterFuzzView : public SampleView {
454 ImageFilterFuzzView() {
455 this->setBGColor(0xFFDDDDDD);
459 // overrides from SkEventSink
460 virtual bool onQuery(SkEvent* evt) {
461 if (SampleCode::TitleQ(*evt)) {
462 SampleCode::TitleR(evt, "ImageFilterFuzzer");
465 return this->INHERITED::onQuery(evt);
468 void drawBG(SkCanvas* canvas) {
469 canvas->drawColor(0xFFDDDDDD);
472 virtual void onDrawContent(SkCanvas* canvas) {
478 typedef SkView INHERITED;
481 //////////////////////////////////////////////////////////////////////////////
483 static SkView* MyFactory() { return new ImageFilterFuzzView; }
484 static SkViewRegister reg(MyFactory);