aboutsummaryrefslogtreecommitdiffhomepage
path: root/fuzz/FuzzGradients.cpp
diff options
context:
space:
mode:
authorGravatar kjlubick <kjlubick@google.com>2016-08-12 06:26:03 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-12 06:26:03 -0700
commit1eda1eb2039518f534c4b893482c8b0f8c4abeab (patch)
tree46e124a5d65335b815a36083339a154e49bc0e62 /fuzz/FuzzGradients.cpp
parent5aeb2fa25384b9d3202a1e8c6cd6832038419fe6 (diff)
Create gradient fuzzers
Diffstat (limited to 'fuzz/FuzzGradients.cpp')
-rw-r--r--fuzz/FuzzGradients.cpp294
1 files changed, 294 insertions, 0 deletions
diff --git a/fuzz/FuzzGradients.cpp b/fuzz/FuzzGradients.cpp
new file mode 100644
index 0000000000..d24bdbe057
--- /dev/null
+++ b/fuzz/FuzzGradients.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Fuzz.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkSurface.h"
+#include "SkTLazy.h"
+
+#include <algorithm>
+
+const int MAX_COUNT = 400;
+
+bool makeMatrix(Fuzz* fuzz, SkMatrix* m) {
+ SkScalar scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2;
+ if (!fuzz->next<SkScalar>(&scaleX) ||
+ !fuzz->next<SkScalar>(&skewX) ||
+ !fuzz->next<SkScalar>(&transX) ||
+ !fuzz->next<SkScalar>(&skewY) ||
+ !fuzz->next<SkScalar>(&scaleY) ||
+ !fuzz->next<SkScalar>(&transY) ||
+ !fuzz->next<SkScalar>(&persp0) ||
+ !fuzz->next<SkScalar>(&persp1) ||
+ !fuzz->next<SkScalar>(&persp2)) {
+ return false;
+ }
+ m->setAll(scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2);
+ return true;
+}
+
+bool initGradientParams(Fuzz* fuzz, uint32_t* count, SkColor** colors, SkScalar** pos,
+ SkShader::TileMode* mode) {
+ if (fuzz->remaining() < sizeof(uint32_t)) {
+ return false;
+ }
+ uint32_t t_count;
+ SkColor* t_colors;
+ SkScalar* t_pos;
+
+ t_count = fuzz->nextRangeU(0, MAX_COUNT);
+ if (t_count == 1) {
+ t_count = 2;
+ }
+
+ if (fuzz->remaining() < (1 + t_count * (sizeof(SkColor) + sizeof(SkScalar)))) {
+ return false;
+ }
+ t_colors = new SkColor[t_count];
+ t_pos = new SkScalar[t_count];
+ for (uint32_t i = 0; i < t_count; i++) {
+ fuzz->next<SkColor>(&t_colors[i]);
+ fuzz->next<SkScalar>(&t_pos[i]);
+ }
+
+ if (t_count == 0) {
+ *count = 0;
+ *colors = NULL;
+ *pos = NULL;
+ } else {
+ std::sort(t_pos, t_pos + t_count);
+ t_pos[0] = 0;
+ t_pos[t_count - 1] = 1;
+ *count = t_count;
+ *colors = t_colors;
+ *pos = t_pos;
+ }
+
+ *mode = static_cast<SkShader::TileMode>(fuzz->nextRangeU(0, 3));
+ return true;
+}
+
+void fuzzLinearGradient(Fuzz* fuzz) {
+ SkScalar a, b, c, d;
+ bool useLocalMatrix, useGlobalMatrix;
+ if (!fuzz->next<SkScalar>(&a) ||
+ !fuzz->next<SkScalar>(&b) ||
+ !fuzz->next<SkScalar>(&c) ||
+ !fuzz->next<SkScalar>(&d) ||
+ !fuzz->next<bool>(&useLocalMatrix) ||
+ !fuzz->next<bool>(&useGlobalMatrix)) {
+ return;
+ }
+ SkPoint pts[2] = {SkPoint::Make(a,b), SkPoint::Make(c, d)};
+
+ uint32_t count;
+ SkColor* colors;
+ SkScalar* pos;
+ SkShader::TileMode mode;
+ if (!initGradientParams(fuzz, &count, &colors, &pos, &mode)) {
+ return;
+ }
+
+ SkPaint p;
+ uint32_t flags;
+ if (!fuzz->next(&flags)) {
+ return;
+ }
+
+ SkTLazy<SkMatrix> localMatrix;
+ if (useLocalMatrix && !makeMatrix(fuzz, localMatrix.init())) {
+ return;
+ }
+ p.setShader(SkGradientShader::MakeLinear(pts, colors, pos, count, mode,
+ flags, localMatrix.getMaybeNull()));
+
+ sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50));
+ if (useGlobalMatrix) {
+ SkMatrix gm;
+ if (!makeMatrix(fuzz, &gm)) {
+ return;
+ }
+ SkCanvas* c = surface->getCanvas();
+ c->setMatrix(gm);
+ c->drawPaint(p);
+ } else {
+ surface->getCanvas()->drawPaint(p);
+ }
+}
+
+void fuzzRadialGradient(Fuzz* fuzz) {
+ SkScalar a, b, radius;
+ bool useLocalMatrix, useGlobalMatrix;
+ if (!fuzz->next<SkScalar>(&a) ||
+ !fuzz->next<SkScalar>(&b) ||
+ !fuzz->next<SkScalar>(&radius) ||
+ !fuzz->next<bool>(&useLocalMatrix) ||
+ !fuzz->next<bool>(&useGlobalMatrix)) {
+ return;
+ }
+ SkPoint center = SkPoint::Make(a,b);
+
+ uint32_t count;
+ SkColor* colors;
+ SkScalar* pos;
+ SkShader::TileMode mode;
+ if (!initGradientParams(fuzz, &count, &colors, &pos, &mode)) {
+ return;
+ }
+
+ SkPaint p;
+ uint32_t flags;
+ if (!fuzz->next(&flags)) {
+ return;
+ }
+
+ SkTLazy<SkMatrix> localMatrix;
+ if (useLocalMatrix && !makeMatrix(fuzz, localMatrix.init())) {
+ return;
+ }
+ p.setShader(SkGradientShader::MakeRadial(center, radius, colors, pos,
+ count, mode, flags, localMatrix.getMaybeNull()));
+
+
+ sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50));
+ if (useGlobalMatrix) {
+ SkMatrix gm;
+ if (!makeMatrix(fuzz, &gm)) {
+ return;
+ }
+ SkCanvas* c = surface->getCanvas();
+ c->setMatrix(gm);
+ c->drawPaint(p);
+ } else {
+ surface->getCanvas()->drawPaint(p);
+ }
+}
+
+void fuzzTwoPointConicalGradient(Fuzz* fuzz) {
+ SkScalar a, b, startRadius, c, d, endRadius;
+ bool useLocalMatrix, useGlobalMatrix;
+ if (!fuzz->next<SkScalar>(&a) ||
+ !fuzz->next<SkScalar>(&b) ||
+ !fuzz->next<SkScalar>(&startRadius) ||
+ !fuzz->next<SkScalar>(&c) ||
+ !fuzz->next<SkScalar>(&d) ||
+ !fuzz->next<SkScalar>(&endRadius) ||
+ !fuzz->next<bool>(&useLocalMatrix) ||
+ !fuzz->next<bool>(&useGlobalMatrix)) {
+ return;
+ }
+ SkPoint start = SkPoint::Make(a, b);
+ SkPoint end = SkPoint::Make(c, d);
+
+ uint32_t count;
+ SkColor* colors;
+ SkScalar* pos;
+ SkShader::TileMode mode;
+ if (!initGradientParams(fuzz, &count, &colors, &pos, &mode)) {
+ return;
+ }
+
+ SkPaint p;
+ uint32_t flags;
+ if (!fuzz->next(&flags)) {
+ return;
+ }
+
+ SkTLazy<SkMatrix> localMatrix;
+ if (useLocalMatrix && !makeMatrix(fuzz, localMatrix.init())) {
+ return;
+ }
+ p.setShader(SkGradientShader::MakeTwoPointConical(start, startRadius, end,
+ endRadius, colors, pos, count, mode, flags, localMatrix.getMaybeNull()));
+
+ sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50));
+ if (useGlobalMatrix) {
+ SkMatrix gm;
+ if (!makeMatrix(fuzz, &gm)) {
+ return;
+ }
+ SkCanvas* c = surface->getCanvas();
+ c->setMatrix(gm);
+ c->drawPaint(p);
+ } else {
+ surface->getCanvas()->drawPaint(p);
+ }
+}
+
+void fuzzSweepGradient(Fuzz* fuzz) {
+ SkScalar cx, cy;
+ bool useLocalMatrix, useGlobalMatrix;
+ if (!fuzz->next<SkScalar>(&cx) ||
+ !fuzz->next<SkScalar>(&cy) ||
+ !fuzz->next<bool>(&useLocalMatrix) ||
+ !fuzz->next<bool>(&useGlobalMatrix)) {
+ return;
+ }
+
+ uint32_t count;
+ SkColor* colors;
+ SkScalar* pos;
+ SkShader::TileMode mode;
+ if (!initGradientParams(fuzz, &count, &colors, &pos, &mode)) {
+ return;
+ }
+
+ SkPaint p;
+ if (useLocalMatrix) {
+ SkMatrix m;
+ if (!makeMatrix(fuzz, &m)) {
+ return;
+ }
+ uint32_t flags;
+ if (!fuzz->next(&flags)) {
+ return;
+ }
+ p.setShader(SkGradientShader::MakeSweep(cx, cy, colors, pos, count, flags, &m));
+ } else {
+ p.setShader(SkGradientShader::MakeSweep(cx, cy, colors, pos, count));
+ }
+
+
+ sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50));
+ if (useGlobalMatrix) {
+ SkMatrix gm;
+ if (!makeMatrix(fuzz, &gm)) {
+ return;
+ }
+ SkCanvas* c = surface->getCanvas();
+ c->setMatrix(gm);
+ c->drawPaint(p);
+ } else {
+ surface->getCanvas()->drawPaint(p);
+ }
+}
+
+DEF_FUZZ(Gradients, fuzz) {
+ uint8_t i;
+ if (!fuzz->next<uint8_t>(&i)) {
+ return;
+ }
+
+ switch(i) {
+ case 0:
+ SkDebugf("LinearGradient\n");
+ fuzzLinearGradient(fuzz);
+ return;
+ case 1:
+ SkDebugf("RadialGradient\n");
+ fuzzRadialGradient(fuzz);
+ return;
+ case 2:
+ SkDebugf("TwoPointConicalGradient\n");
+ fuzzTwoPointConicalGradient(fuzz);
+ return;
+ }
+ SkDebugf("SweepGradient\n");
+ fuzzSweepGradient(fuzz);
+ return;
+}