Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Unified Diff: src/core/SkBitmapFilter.h

Issue 17381008: More general version of image filtering; reworked to be robust and easier to SSE (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: make temp. scale function private; disable GM and bench for that function Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkBitmapFilter.h
diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e4778876c6e8a1491d83186afda157e49f167f7
--- /dev/null
+++ b/src/core/SkBitmapFilter.h
@@ -0,0 +1,150 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkBitmapFilter_DEFINED
+#define SkBitmapFilter_DEFINED
+
+#include "SkMath.h"
+
+// size of the precomputed bitmap filter tables for high quality filtering.
+// Used to precompute the shape of the filter kernel.
+// Table size chosen from experiments to see where I could start to see a difference.
+
+#define SKBITMAP_FILTER_TABLE_SIZE 32
+
+class SkBitmapFilter {
+ public:
+ SkBitmapFilter(float width)
+ : fWidth(width), fInvWidth(1.f/width) {
+ precomputed = false;
+ }
+
+ SkFixed lookup( float x ) const {
+ if (!precomputed) {
+ precomputeTable();
+ }
+ int filter_idx = int(fabsf(x * invWidth() * SKBITMAP_FILTER_TABLE_SIZE));
+ return fFilterTable[ SkTMin(filter_idx, SKBITMAP_FILTER_TABLE_SIZE-1) ];
+ }
+
+ SkFixed lookupFloat( float x ) const {
+ if (!precomputed) {
+ precomputeTable();
+ }
+ int filter_idx = int(fabsf(x * invWidth() * SKBITMAP_FILTER_TABLE_SIZE));
+ return fFilterTableFloat[ SkTMin(filter_idx, SKBITMAP_FILTER_TABLE_SIZE-1) ];
+ }
+
+ float width() const { return fWidth; }
+ float invWidth() const { return fInvWidth; }
+ virtual float evaluate(float x) const = 0;
+ protected:
+ float fWidth;
+ float fInvWidth;
+
+ mutable bool precomputed;
+ mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE];
+ mutable float fFilterTableFloat[SKBITMAP_FILTER_TABLE_SIZE];
+ private:
+ void precomputeTable() const {
+ precomputed = true;
+ SkFixed *ftp = fFilterTable;
+ float *ftp_float = fFilterTableFloat;
+ for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) {
+ float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABLE_SIZE;
+ float filter_value = evaluate(fx);
+ *ftp_float++ = filter_value;
+ *ftp++ = SkFloatToFixed(filter_value);
+ }
+ }
+};
+
+class SkMitchellFilter: public SkBitmapFilter {
+ public:
+ SkMitchellFilter(float b, float c, float width=2.0f)
+ : SkBitmapFilter(width), B(b), C(c) {
+ }
+
+ virtual float evaluate(float x) const SK_OVERRIDE {
+ x = fabsf(x);
+ float ret;
+ if (x > 2.f) {
+ return 0;
+ } else if (x > 1.f) {
+ return ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x +
+ (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f);
+ } else {
+ return ((12 - 9*B - 6*C) * x*x*x +
+ (-18 + 12*B + 6*C) * x*x +
+ (6 - 2*B)) * (1.f/6.f);
+ }
+ }
+ protected:
+ float B, C;
+};
+
+class SkGaussianFilter: public SkBitmapFilter {
+ public:
+ SkGaussianFilter(float a, float width=2.0f)
+ : SkBitmapFilter(width), alpha(a), expWidth(expf(-alpha * width * width)) {
+ }
+
+ virtual float evaluate(float x) const SK_OVERRIDE {
+ return SkTMax(0.f, float(expf(-alpha*x*x) - expWidth));
+ }
+ protected:
+ float alpha, expWidth;
+};
+
+class SkTriangleFilter: public SkBitmapFilter {
+ public:
+ SkTriangleFilter(float width=1)
+ : SkBitmapFilter(width) {
+ }
+
+ virtual float evaluate(float x) const SK_OVERRIDE {
+ return SkTMax(0.f, fWidth - fabsf(x));
+ }
+ protected:
+};
+
+class SkBoxFilter: public SkBitmapFilter {
+ public:
+ SkBoxFilter(float width=0.5f)
+ : SkBitmapFilter(width) {
+ }
+
+ virtual float evaluate(float x) const SK_OVERRIDE {
+ return 1;
+ }
+ protected:
+};
+
+
+class SkSincFilter: public SkBitmapFilter {
+ public:
+ SkSincFilter(float t, float width=3.f)
+ : SkBitmapFilter(width), tau(t) {
+ }
+
+ virtual float evaluate(float x) const SK_OVERRIDE {
+ x = sk_float_abs(x * fInvWidth);
+ if (x < 1e-5f) return 1.f;
+ if (x > 1.f) return 0.f;
+ x *= M_PI;
+ float sinc = sk_float_sin(x) / x;
+ float lanczos = sk_float_sin(x * tau) / (x * tau);
+ return sinc * lanczos;
+ }
+ protected:
+ float tau;
+};
+
+
+#endif

Powered by Google App Engine
This is Rietveld 408576698