Chromium Code Reviews| Index: samplecode/SampleFilterFuzz.cpp |
| diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c69a1124503f8fa906a5307771599de56962371e |
| --- /dev/null |
| +++ b/samplecode/SampleFilterFuzz.cpp |
| @@ -0,0 +1,305 @@ |
| + |
| +/* |
| + * Copyright 2011 Google Inc. |
|
scroggo
2013/08/21 23:25:27
2013
sugoi1
2013/08/22 15:41:00
Done.
|
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| +#include "SampleCode.h" |
| +#include "SkView.h" |
| +#include "SkCanvas.h" |
| +#include "SkDevice.h" |
| +#include "SkRandom.h" |
| +#include "SkFlattenableSerialization.h" |
| +#include "SkBicubicImageFilter.h" |
| +#include "SkMergeImageFilter.h" |
| +#include "SkColorFilter.h" |
| +#include "SkColorFilterImageFilter.h" |
| +#include "SkBlurImageFilter.h" |
| +#include "SkMagnifierImageFilter.h" |
| +#include "SkXfermodeImageFilter.h" |
| +#include "SkOffsetImageFilter.h" |
| +#include "SkComposeImageFilter.h" |
| +#include "SkLightingImageFilter.h" |
| +#include "SkPerlinNoiseShader.h" |
| +#include "SkRectShaderImageFilter.h" |
| +#include "SkDropShadowImageFilter.h" |
| +#include "SkMorphologyImageFilter.h" |
| +#include "SkBitmapSource.h" |
| +#include "SkDisplacementMapEffect.h" |
| + |
| +static const uint32_t kSeed = 1; |
| +static SkRandom gRand(kSeed); |
| +static bool return_large = false; |
|
Stephen White
2013/08/21 20:49:26
Shouldn't we also be randomizing these values, or
sugoi
2013/08/21 21:12:09
I'd like to add more "randomness" in the next vers
|
| +static bool return_undef = false; |
| + |
| +static const int kBitmapSize = 24; |
| + |
| +static int R(float x) { |
| + return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x); |
| +} |
| + |
| +#if defined _WIN32 |
| +#pragma warning ( push ) |
| +// we are intentionally causing an overflow here |
| +// (warning C4756: overflow in constant arithmetic) |
| +#pragma warning ( disable : 4756 ) |
| +#endif |
| + |
| +static float huge() { |
| + double d = 1e100; |
| + float f = (float)d; |
| + return f; |
| +} |
| + |
| +#if defined _WIN32 |
| +#pragma warning ( pop ) |
| +#endif |
| + |
| +static float make_number(bool positiveOnly) { |
| + float f = positiveOnly ? 1 : 0; |
| + float v = f; |
| + int sel; |
| + |
| + if (return_large) sel = R(6); else sel = R(4); |
| + if (!return_undef && sel == 0) sel = 1; |
| + |
| + if (R(2) == 1) v = (float)(R(100)+f); else |
| + |
| + switch (sel) { |
| + case 0: break; |
| + case 1: v = f; break; |
| + case 2: v = 0.000001f; break; |
| + case 3: v = 10000; break; |
| + case 4: v = 2000000000; break; |
| + case 5: v = huge(); break; |
| + } |
| + |
| + if (!positiveOnly && (R(4) == 1)) v = -v; |
| + return v; |
| +} |
| + |
| +static SkScalar make_scalar(bool positiveOnly = false) { |
| + return SkFloatToScalar(make_number(positiveOnly)); |
| +} |
| + |
| +static SkRect make_rect(int offset = 1) { |
| + return SkRect::MakeWH(SkIntToScalar(R(kBitmapSize)+offset), |
| + SkIntToScalar(R(kBitmapSize)+offset)); |
| +} |
| + |
| +static SkXfermode::Mode make_xfermode() { |
| + return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1)); |
| +} |
| + |
| +static SkColor make_color() { |
| + return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090; |
| +} |
| + |
| +static SkPoint3 make_point() { |
| + return SkPoint3(make_scalar(), make_scalar(), make_scalar(true)); |
| +} |
| + |
| +static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() { |
| + return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1); |
| +} |
| + |
| +static void make_g_bitmap(SkBitmap& bitmap) { |
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, kBitmapSize, kBitmapSize); |
| + bitmap.allocPixels(); |
| + SkDevice device(bitmap); |
| + SkCanvas canvas(&device); |
| + canvas.clear(0x00000000); |
| + SkPaint paint; |
| + paint.setAntiAlias(true); |
| + paint.setColor(0xFF884422); |
| + paint.setTextSize(SkIntToScalar(kBitmapSize/2)); |
| + const char* str = "g"; |
| + canvas.drawText(str, strlen(str), SkIntToScalar(kBitmapSize/8), SkIntToScalar(kBitmapSize/4), paint); |
|
scroggo
2013/08/21 23:25:27
100 chars
sugoi1
2013/08/22 15:41:00
Done.
|
| +} |
| + |
| +static void make_checkerboard_bitmap(SkBitmap& bitmap) { |
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, kBitmapSize, kBitmapSize); |
| + bitmap.allocPixels(); |
| + SkDevice device(bitmap); |
| + SkCanvas canvas(&device); |
| + canvas.clear(0x00000000); |
| + SkPaint darkPaint; |
| + darkPaint.setColor(0xFF804020); |
| + SkPaint lightPaint; |
| + lightPaint.setColor(0xFF244484); |
| + const int i = kBitmapSize / 8; |
| + for (int y = 0; y < kBitmapSize; y += i) { |
| + for (int x = 0; x < kBitmapSize; x += i) { |
| + canvas.save(); |
| + canvas.translate(SkIntToScalar(x), SkIntToScalar(y)); |
| + canvas.drawRect(SkRect::MakeXYWH(0, 0, i, i), darkPaint); |
| + canvas.drawRect(SkRect::MakeXYWH(i, 0, i, i), lightPaint); |
| + canvas.drawRect(SkRect::MakeXYWH(0, i, i, i), lightPaint); |
| + canvas.drawRect(SkRect::MakeXYWH(i, i, i, i), darkPaint); |
| + canvas.restore(); |
| + } |
| + } |
| +} |
| + |
| +static const SkBitmap& make_bitmap() { |
| + static SkBitmap bitmap[2]; |
| + static bool initialized = false; |
| + if (!initialized) { |
| + make_g_bitmap(bitmap[0]); |
| + make_checkerboard_bitmap(bitmap[1]); |
| + initialized = true; |
| + } |
| + return bitmap[R(2)]; |
| +} |
| + |
| +static SkImageFilter* make_image_filter(bool canBeNull = true) { |
| + SkImageFilter* filter = 0; |
| + |
| + // Add a 1 in 3 chance to get a NULL input |
| + if (canBeNull && (R(3) == 1)) { return filter; } |
| + |
| + enum { BICUBIC, MERGE, COLOR, BLUR, MAGNIFIER, XFERMODE, OFFSET, COMPOSE, |
| + DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW, |
| + MORPHOLOGY, BITMAP, DISPLACE, NUM_FILTERS }; |
| + |
| + switch (R(NUM_FILTERS)) { |
| + case BICUBIC: |
| + // Scale is set to 1 here so that it can fit in the DAG without resizing the output |
| + filter = SkBicubicImageFilter::CreateMitchell(SkSize::Make(1, 1), make_image_filter()); |
| + break; |
| + case MERGE: |
| + filter = new SkMergeImageFilter(make_image_filter(), make_image_filter(), make_xfermode()); |
| + break; |
| + case COLOR: |
| + { |
| + SkAutoTUnref<SkColorFilter> cf((R(2) == 1) ? |
| + SkColorFilter::CreateModeFilter(make_color(), make_xfermode()) : |
| + SkColorFilter::CreateLightingFilter(make_color(), make_color())); |
| + filter = cf.get() ? SkColorFilterImageFilter::Create(cf, make_image_filter()) : 0; |
| + } |
| + break; |
| + case BLUR: |
| + filter = new SkBlurImageFilter(make_scalar(true), make_scalar(true), make_image_filter()); |
| + break; |
| + case MAGNIFIER: |
| + filter = new SkMagnifierImageFilter(make_rect(0), make_scalar(true)); |
| + break; |
| + case XFERMODE: |
| + { |
| + SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(make_xfermode())); |
| + filter = new SkXfermodeImageFilter(mode, make_image_filter(), make_image_filter()); |
| + } |
| + break; |
| + case OFFSET: |
| + filter = new SkOffsetImageFilter(make_scalar(), make_scalar(), make_image_filter()); |
| + break; |
| + case COMPOSE: |
| + filter = new SkComposeImageFilter(make_image_filter(), make_image_filter()); |
| + break; |
| + case DISTANT_LIGHT: |
| + filter = (R(2) == 1) ? |
| + SkLightingImageFilter::CreateDistantLitDiffuse(make_point(), |
| + make_color(), make_scalar(), make_scalar(), make_image_filter()) : |
| + SkLightingImageFilter::CreateDistantLitSpecular(make_point(), |
| + make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)), |
| + make_image_filter()); |
| + break; |
| + case POINT_LIGHT: |
| + filter = (R(2) == 1) ? |
| + SkLightingImageFilter::CreatePointLitDiffuse(make_point(), |
| + make_color(), make_scalar(), make_scalar(), make_image_filter()) : |
| + SkLightingImageFilter::CreatePointLitSpecular(make_point(), |
| + make_color(), make_scalar(), make_scalar(), SkIntToScalar(R(10)), |
| + make_image_filter()); |
| + break; |
| + case SPOT_LIGHT: |
| + filter = (R(2) == 1) ? |
| + SkLightingImageFilter::CreateSpotLitDiffuse(SkPoint3(0, 0, 0), |
|
Stephen White
2013/08/21 20:49:26
Maybe we should have a make_point3 that we could u
sugoi
2013/08/21 21:12:09
I had some issue with having this value randomized
|
| + make_point(), make_scalar(), make_scalar(), make_color(), |
| + make_scalar(), make_scalar(), make_image_filter()) : |
| + SkLightingImageFilter::CreateSpotLitSpecular(SkPoint3(0, 0, 0), |
| + make_point(), make_scalar(), make_scalar(), make_color(), |
| + make_scalar(), make_scalar(), SkIntToScalar(R(10)), make_image_filter()); |
| + break; |
| + case NOISE: |
| + { |
| + SkAutoTUnref<SkShader> shader((R(2) == 1) ? |
| + SkPerlinNoiseShader::CreateFractalNoise(make_scalar(true), make_scalar(true), R(10), make_scalar()) : |
|
scroggo
2013/08/21 23:25:27
100 chars
sugoi1
2013/08/22 15:41:00
Done.
|
| + SkPerlinNoiseShader::CreateTubulence(make_scalar(true), make_scalar(true), R(10), make_scalar())); |
|
scroggo
2013/08/21 23:25:27
100 chars
sugoi1
2013/08/22 15:41:00
Done.
|
| + filter = SkRectShaderImageFilter::Create(shader, SkRect::MakeWH(kBitmapSize, kBitmapSize)); |
| + } |
| + break; |
| + case DROP_SHADOW: |
| + filter = new SkDropShadowImageFilter(make_scalar(), make_scalar(), |
| + make_scalar(true), make_color(), make_image_filter()); |
| + break; |
| + case MORPHOLOGY: |
| + if (R(2) == 1) |
| + filter = new SkDilateImageFilter(R(kBitmapSize), R(kBitmapSize), make_image_filter()); |
| + else |
| + filter = new SkErodeImageFilter(R(kBitmapSize), R(kBitmapSize), make_image_filter()); |
| + break; |
| + case BITMAP: |
| + filter = new SkBitmapSource(make_bitmap()); |
| + break; |
| + case DISPLACE: |
| + filter = new SkDisplacementMapEffect(make_channel_selector_type(), |
| + make_channel_selector_type(), make_scalar(), |
| + make_image_filter(false), make_image_filter()); |
| + break; |
| + default: |
| + break; |
| + } |
| + return (filter || canBeNull) ? filter : make_image_filter(canBeNull); |
| +} |
| + |
| +void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) { |
| + canvas->save(); |
| + canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), |
| + SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize))); |
| + canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint); |
| + canvas->restore(); |
| +} |
| + |
| +static void do_fuzz(SkCanvas* canvas) { |
| + SkPaint paint; |
| + paint.setImageFilter(make_image_filter()); |
| + drawClippedBitmap(canvas, 0, 0, paint); |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| +class ImageFilterFuzzView : public SampleView { |
| +public: |
| + ImageFilterFuzzView() { |
| + this->setBGColor(0xFFDDDDDD); |
| + } |
| + |
| +protected: |
| + // overrides from SkEventSink |
| + virtual bool onQuery(SkEvent* evt) { |
| + if (SampleCode::TitleQ(*evt)) { |
| + SampleCode::TitleR(evt, "ImageFilterFuzzer"); |
| + return true; |
| + } |
| + return this->INHERITED::onQuery(evt); |
| + } |
| + |
| + void drawBG(SkCanvas* canvas) { |
| + canvas->drawColor(0xFFDDDDDD); |
| + } |
| + |
| + virtual void onDrawContent(SkCanvas* canvas) { |
| + do_fuzz(canvas); |
| + this->inval(0); |
| + } |
| + |
| +private: |
| + typedef SkView INHERITED; |
| +}; |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| +static SkView* MyFactory() { return new ImageFilterFuzzView; } |
| +static SkViewRegister reg(MyFactory); |