Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / samplecode / SampleFilterFuzz.cpp
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 "SkAlphaThresholdFilter.h"
9 #include "SkBitmapSource.h"
10 #include "SkBlurImageFilter.h"
11 #include "SkCanvas.h"
12 #include "SkColorFilter.h"
13 #include "SkColorFilterImageFilter.h"
14 #include "SkComposeImageFilter.h"
15 #include "SkData.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"
29 #include "SkRandom.h"
30 #include "SkRectShaderImageFilter.h"
31 #include "SkTestImageFilters.h"
32 #include "SkTileImageFilter.h"
33 #include "SkView.h"
34 #include "SkXfermodeImageFilter.h"
35 #include <stdio.h>
36 #include <time.h>
37
38 //#define SK_ADD_RANDOM_BIT_FLIPS
39 //#define SK_FUZZER_IS_VERBOSE
40
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;
45
46 static const int kBitmapSize = 24;
47
48 static int R(float x) {
49     return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x);
50 }
51
52 #if defined _WIN32
53 #pragma warning ( push )
54 // we are intentionally causing an overflow here
55 //      (warning C4756: overflow in constant arithmetic)
56 #pragma warning ( disable : 4756 )
57 #endif
58
59 static float huge() {
60     double d = 1e100;
61     float f = (float)d;
62     return f;
63 }
64
65 #if defined _WIN32
66 #pragma warning ( pop )
67 #endif
68
69 static float make_number(bool positiveOnly) {
70     float f = positiveOnly ? 1.0f : 0.0f;
71     float v = f;
72     int sel;
73
74     if (return_large) sel = R(6); else sel = R(4);
75     if (!return_undef && sel == 0) sel = 1;
76
77     if (R(2) == 1) v = (float)(R(100)+f); else
78
79     switch (sel) {
80         case 0: break;
81         case 1: v = f; break;
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;
86     }
87
88     if (!positiveOnly && (R(4) == 1)) v = -v;
89     return v;
90 }
91
92 static SkScalar make_scalar(bool positiveOnly = false) {
93     return make_number(positiveOnly);
94 }
95
96 static SkRect make_rect() {
97     return SkRect::MakeWH(SkIntToScalar(R(static_cast<float>(kBitmapSize))),
98                           SkIntToScalar(R(static_cast<float>(kBitmapSize))));
99 }
100
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);
107 }
108
109 static SkMatrix make_matrix() {
110     SkMatrix m;
111     for (int i = 0; i < 9; ++i) {
112         m[i] = make_scalar();
113     }
114     return m;
115 }
116
117 static SkXfermode::Mode make_xfermode() {
118     return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1));
119 }
120
121 static SkColor make_color() {
122     return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090;
123 }
124
125 static SkPoint3 make_point() {
126     return SkPoint3(make_scalar(), make_scalar(), make_scalar(true));
127 }
128
129 static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() {
130     return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1);
131 }
132
133 static bool valid_for_raster_canvas(const SkImageInfo& info) {
134     switch (info.colorType()) {
135         case kAlpha_8_SkColorType:
136         case kRGB_565_SkColorType:
137             return true;
138         case kN32_SkColorType:
139             return kPremul_SkAlphaType == info.alphaType() ||
140                    kOpaque_SkAlphaType == info.alphaType();
141         default:
142             break;
143     }
144     return false;
145 }
146
147 static SkColorType rand_colortype() {
148     return (SkColorType)R(kLastEnum_SkColorType + 1);
149 }
150
151 static void rand_bitmap_for_canvas(SkBitmap* bitmap) {
152     SkImageInfo info;
153     do {
154         info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(),
155                                  kPremul_SkAlphaType);
156     } while (!valid_for_raster_canvas(info) || !bitmap->tryAllocPixels(info));
157 }
158
159 static void make_g_bitmap(SkBitmap& bitmap) {
160     rand_bitmap_for_canvas(&bitmap);
161
162     SkCanvas canvas(bitmap);
163     canvas.clear(0x00000000);
164     SkPaint paint;
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);
171 }
172
173 static void make_checkerboard_bitmap(SkBitmap& bitmap) {
174     rand_bitmap_for_canvas(&bitmap);
175
176     SkCanvas canvas(bitmap);
177     canvas.clear(0x00000000);
178     SkPaint darkPaint;
179     darkPaint.setColor(0xFF804020);
180     SkPaint lightPaint;
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) {
186             canvas.save();
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);
192             canvas.restore();
193         }
194     }
195 }
196
197 static const SkBitmap& make_bitmap() {
198     static SkBitmap bitmap[2];
199     static bool initialized = false;
200     if (!initialized) {
201         make_g_bitmap(bitmap[0]);
202         make_checkerboard_bitmap(bitmap[1]);
203         initialized = true;
204     }
205     return bitmap[R(2)];
206 }
207
208 static void drawSomething(SkCanvas* canvas) {
209     SkPaint paint;
210
211     canvas->save();
212     canvas->scale(0.5f, 0.5f);
213     canvas->drawBitmap(make_bitmap(), 0, 0, NULL);
214     canvas->restore();
215
216     const char beforeStr[] = "before circle";
217     const char afterStr[] = "after circle";
218
219     paint.setAntiAlias(true);
220
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);
228 }
229
230 static SkImageFilter* make_image_filter(bool canBeNull = true) {
231     SkImageFilter* filter = 0;
232
233     // Add a 1 in 3 chance to get a NULL input
234     if (canBeNull && (R(3) == 1)) { return filter; }
235
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 };
240
241     switch (R(NUM_FILTERS)) {
242     case ALPHA_THRESHOLD:
243         filter = SkAlphaThresholdFilter::Create(make_region(), make_scalar(), make_scalar());
244         break;
245     case MERGE:
246         filter = SkMergeImageFilter::Create(make_image_filter(), make_image_filter(), make_xfermode());
247         break;
248     case COLOR:
249     {
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;
254     }
255         break;
256     case BLUR:
257         filter = SkBlurImageFilter::Create(make_scalar(true), make_scalar(true), make_image_filter());
258         break;
259     case MAGNIFIER:
260         filter = SkMagnifierImageFilter::Create(make_rect(), make_scalar(true));
261         break;
262     case DOWN_SAMPLE:
263         filter = SkDownSampleImageFilter::Create(make_scalar());
264         break;
265     case XFERMODE:
266     {
267         SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(make_xfermode()));
268         filter = SkXfermodeImageFilter::Create(mode, make_image_filter(), make_image_filter());
269     }
270         break;
271     case OFFSET:
272         filter = SkOffsetImageFilter::Create(make_scalar(), make_scalar(), make_image_filter());
273         break;
274     case MATRIX:
275         filter = SkMatrixImageFilter::Create(make_matrix(),
276                                              (SkPaint::FilterLevel)R(4),
277                                              make_image_filter());
278         break;
279     case MATRIX_CONVOLUTION:
280     {
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();
288         }
289         SkIPoint kernelOffset = SkIPoint::Make(R(SkIntToScalar(size.width())),
290                                                R(SkIntToScalar(size.height())));
291         filter = SkMatrixConvolutionImageFilter::Create(size,
292                                                         kernel.begin(),
293                                                         make_scalar(),
294                                                         make_scalar(),
295                                                         kernelOffset,
296                                                         (SkMatrixConvolutionImageFilter::TileMode)R(3),
297                                                         R(2) == 1,
298                                                         make_image_filter(),
299                                                         &cropR);
300     }
301         break;
302     case COMPOSE:
303         filter = SkComposeImageFilter::Create(make_image_filter(), make_image_filter());
304         break;
305     case DISTANT_LIGHT:
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());
312         break;
313     case POINT_LIGHT:
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());
320         break;
321     case SPOT_LIGHT:
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());
329         break;
330     case NOISE:
331     {
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);
340     }
341         break;
342     case DROP_SHADOW:
343         filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(),
344                      make_scalar(true), make_scalar(true), make_color(), make_image_filter());
345         break;
346     case MORPHOLOGY:
347         if (R(2) == 1) {
348             filter = SkDilateImageFilter::Create(R(static_cast<float>(kBitmapSize)),
349                 R(static_cast<float>(kBitmapSize)), make_image_filter());
350         } else {
351             filter = SkErodeImageFilter::Create(R(static_cast<float>(kBitmapSize)),
352                 R(static_cast<float>(kBitmapSize)), make_image_filter());
353         }
354         break;
355     case BITMAP:
356         if (R(2) == 1) {
357             filter = SkBitmapSource::Create(make_bitmap(), make_rect(), make_rect());
358         } else {
359             filter = SkBitmapSource::Create(make_bitmap());
360         }
361         break;
362     case DISPLACE:
363         filter = SkDisplacementMapEffect::Create(make_channel_selector_type(),
364                                                  make_channel_selector_type(), make_scalar(),
365                                                  make_image_filter(false), make_image_filter());
366         break;
367     case TILE:
368         filter = SkTileImageFilter::Create(make_rect(), make_rect(), make_image_filter(false));
369         break;
370     case PICTURE:
371     {
372         SkRTreeFactory factory;
373         SkPictureRecorder recorder;
374         SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(kBitmapSize), 
375                                                             SkIntToScalar(kBitmapSize), 
376                                                             &factory, 0);
377         drawSomething(recordingCanvas);
378         SkAutoTUnref<SkPicture> pict(recorder.endRecording());
379         filter = SkPictureImageFilter::Create(pict.get(), make_rect());
380     }
381         break;
382     default:
383         break;
384     }
385     return (filter || canBeNull) ? filter : make_image_filter(canBeNull);
386 }
387
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
398                 switch(R(3)) {
399                 case 0:
400                     *p ^= 0xFF; // Flip entire byte
401                     break;
402                 case 1:
403                     *p = 0xFF; // Set all bits to 1
404                     break;
405                 case 2:
406                     *p = 0x00; // Set all bits to 0
407                     break;
408                 }
409             } else {
410                 *p ^= (1 << R(8));
411             }
412         }
413     }
414 #endif // SK_ADD_RANDOM_BIT_FLIPS
415     SkFlattenable* flattenable = SkValidatingDeserializeFlattenable(ptr, len,
416                                     SkImageFilter::GetFlattenableType());
417     return static_cast<SkImageFilter*>(flattenable);
418 }
419
420 static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
421     canvas->save();
422     canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
423         SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize)));
424     canvas->drawBitmap(make_bitmap(), SkIntToScalar(x), SkIntToScalar(y), &paint);
425     canvas->restore();
426 }
427
428 static void do_fuzz(SkCanvas* canvas) {
429     SkImageFilter* filter = make_serialized_image_filter();
430
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);
436     }
437     numFilters++;
438     if (filter) {
439         numValidFilters++;
440     }
441     printf("Filter no : %u. Valid filters so far : %u\r", numFilters, numValidFilters);
442     fflush(stdout);
443 #endif
444
445     SkPaint paint;
446     SkSafeUnref(paint.setImageFilter(filter));
447     drawClippedBitmap(canvas, 0, 0, paint);
448 }
449
450 //////////////////////////////////////////////////////////////////////////////
451
452 class ImageFilterFuzzView : public SampleView {
453 public:
454     ImageFilterFuzzView() {
455         this->setBGColor(0xFFDDDDDD);
456     }
457
458 protected:
459     // overrides from SkEventSink
460     virtual bool onQuery(SkEvent* evt) {
461         if (SampleCode::TitleQ(*evt)) {
462             SampleCode::TitleR(evt, "ImageFilterFuzzer");
463             return true;
464         }
465         return this->INHERITED::onQuery(evt);
466     }
467
468     void drawBG(SkCanvas* canvas) {
469         canvas->drawColor(0xFFDDDDDD);
470     }
471
472     virtual void onDrawContent(SkCanvas* canvas) {
473         do_fuzz(canvas);
474         this->inval(0);
475     }
476
477 private:
478     typedef SkView INHERITED;
479 };
480
481 //////////////////////////////////////////////////////////////////////////////
482
483 static SkView* MyFactory() { return new ImageFilterFuzzView; }
484 static SkViewRegister reg(MyFactory);