diff options
Diffstat (limited to 'src/core/SkBitmapFilter.h')
-rw-r--r-- | src/core/SkBitmapFilter.h | 352 |
1 files changed, 171 insertions, 181 deletions
diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h index 038ee98eae..c51a5390aa 100644 --- a/src/core/SkBitmapFilter.h +++ b/src/core/SkBitmapFilter.h @@ -23,154 +23,151 @@ #define SKBITMAP_FILTER_TABLE_SIZE 128 class SkBitmapFilter { - public: - SkBitmapFilter(float width) - : fWidth(width), fInvWidth(1.f/width) { - fPrecomputed = false; - fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1); - } - - SkFixed lookup(float x) const { - if (!fPrecomputed) { - precomputeTable(); - } - int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); - SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); - return fFilterTable[filter_idx]; - } - - SkScalar lookupScalar(float x) const { - if (!fPrecomputed) { - precomputeTable(); - } - int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); - SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); - return fFilterTableScalar[filter_idx]; - } - - float width() const { return fWidth; } - float invWidth() const { return fInvWidth; } - virtual float evaluate(float x) const = 0; +public: + SkBitmapFilter(float width) : fWidth(width), fInvWidth(1.f/width) { + fPrecomputed = false; + fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1); + } + virtual ~SkBitmapFilter() {} + + SkFixed lookup(float x) const { + if (!fPrecomputed) { + precomputeTable(); + } + int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); + SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); + return fFilterTable[filter_idx]; + } + + SkScalar lookupScalar(float x) const { + if (!fPrecomputed) { + precomputeTable(); + } + int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); + SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); + return fFilterTableScalar[filter_idx]; + } + + float width() const { return fWidth; } + float invWidth() const { return fInvWidth; } + virtual float evaluate(float x) const = 0; #ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER - virtual float evaluate_n(float val, float diff, int count, float* output) const { - float sum = 0; - for (int index = 0; index < count; index++) { - float filterValue = evaluate(val); - *output++ = filterValue; - sum += filterValue; - val += diff; - } - return sum; - } + virtual float evaluate_n(float val, float diff, int count, float* output) const { + float sum = 0; + for (int index = 0; index < count; index++) { + float filterValue = evaluate(val); + *output++ = filterValue; + sum += filterValue; + val += diff; + } + return sum; + } #endif - virtual ~SkBitmapFilter() {} - - static SkBitmapFilter* Allocate(); - protected: - float fWidth; - float fInvWidth; - - float fLookupMultiplier; - - mutable bool fPrecomputed; - mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; - mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE]; - private: - void precomputeTable() const { - fPrecomputed = true; - SkFixed *ftp = fFilterTable; - SkScalar *ftpScalar = fFilterTableScalar; - 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); - *ftpScalar++ = filter_value; - *ftp++ = SkFloatToFixed(filter_value); - } - } + static SkBitmapFilter* Allocate(); + +protected: + float fWidth; + float fInvWidth; + float fLookupMultiplier; + + mutable bool fPrecomputed; + mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; + mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE]; + +private: + void precomputeTable() const { + fPrecomputed = true; + SkFixed *ftp = fFilterTable; + SkScalar *ftpScalar = fFilterTableScalar; + 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); + *ftpScalar++ = filter_value; + *ftp++ = SkFloatToFixed(filter_value); + } + } }; -class SkMitchellFilter : public SkBitmapFilter { - public: +class SkMitchellFilter final : public SkBitmapFilter { +public: #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER - SkMitchellFilter() - : INHERITED(2), B(1.f / 3), C(1.f / 3) { - } + SkMitchellFilter() : INHERITED(2), B(1.f / 3), C(1.f / 3) {} #else - SkMitchellFilter() - : INHERITED(2) - , fB(1.f / 3.f) - , fC(1.f / 3.f) - , fA1(-fB - 6*fC) - , fB1(6*fB + 30*fC) - , fC1(-12*fB - 48*fC) - , fD1(8*fB + 24*fC) - , fA2(12 - 9*fB - 6*fC) - , fB2(-18 + 12*fB + 6*fC) - , fD2(6 - 2*fB) { - } + SkMitchellFilter() + : INHERITED(2) + , fB(1.f / 3.f) + , fC(1.f / 3.f) + , fA1(-fB - 6*fC) + , fB1(6*fB + 30*fC) + , fC1(-12*fB - 48*fC) + , fD1(8*fB + 24*fC) + , fA2(12 - 9*fB - 6*fC) + , fB2(-18 + 12*fB + 6*fC) + , fD2(6 - 2*fB) + {} #endif - float evaluate(float x) const override { - x = fabsf(x); - if (x > 2.f) { - return 0; - } else if (x > 1.f) { + float evaluate(float x) const override { + x = fabsf(x); + if (x > 2.f) { + return 0; + } else if (x > 1.f) { #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER - 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); + 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 (((fA1 * x + fB1) * x + fC1) * x + fD1) * (1.f/6.f); + return (((fA1 * x + fB1) * x + fC1) * x + fD1) * (1.f/6.f); #endif - } else { + } else { #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER - return ((12 - 9*B - 6*C) * x*x*x + - (-18 + 12*B + 6*C) * x*x + - (6 - 2*B)) * (1.f/6.f); + return ((12 - 9*B - 6*C) * x*x*x + + (-18 + 12*B + 6*C) * x*x + + (6 - 2*B)) * (1.f/6.f); #else - return ((fA2 * x + fB2) * x*x + fD2) * (1.f/6.f); + return ((fA2 * x + fB2) * x*x + fD2) * (1.f/6.f); #endif - } - } + } + } #ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER - // TODO : native Sk4f abs - static Sk4f abs(const Sk4f& x) { - Sk4f neg = x < Sk4f(0); - return neg.thenElse(Sk4f(0) - x, x); - } - - Sk4f evalcore_n(const Sk4f& val) const { - Sk4f x = abs(val); - Sk4f over2 = x > Sk4f(2); - Sk4f over1 = x > Sk4f(1); - Sk4f poly1 = (((Sk4f(fA1) * x + Sk4f(fB1)) * x + Sk4f(fC1)) * x + Sk4f(fD1)) - * Sk4f(1.f/6.f); - Sk4f poly0 = ((Sk4f(fA2) * x + Sk4f(fB2)) * x*x + Sk4f(fD2)) * Sk4f(1.f/6.f); - return over2.thenElse(Sk4f(0), over1.thenElse(poly1, poly0)); - } - - float evaluate_n(float val, float diff, int count, float* output) const override { - Sk4f sum(0); - while (count >= 4) { - float v0 = val; - float v1 = val += diff; - float v2 = val += diff; - float v3 = val += diff; - val += diff; - Sk4f filterValue = evalcore_n(Sk4f(v0, v1, v2, v3)); - filterValue.store(output); - output += 4; - sum = sum + filterValue; - count -= 4; - } - float sums[4]; - sum.store(sums); - float result = sums[0] + sums[1] + sums[2] + sums[3]; - result += INHERITED::evaluate_n(val, diff, count, output); - return result; - } + // TODO : native Sk4f abs + static Sk4f abs(const Sk4f& x) { + Sk4f neg = x < Sk4f(0); + return neg.thenElse(Sk4f(0) - x, x); + } + + Sk4f evalcore_n(const Sk4f& val) const { + Sk4f x = abs(val); + Sk4f over2 = x > Sk4f(2); + Sk4f over1 = x > Sk4f(1); + Sk4f poly1 = (((Sk4f(fA1) * x + Sk4f(fB1)) * x + Sk4f(fC1)) * x + Sk4f(fD1)) + * Sk4f(1.f/6.f); + Sk4f poly0 = ((Sk4f(fA2) * x + Sk4f(fB2)) * x*x + Sk4f(fD2)) * Sk4f(1.f/6.f); + return over2.thenElse(Sk4f(0), over1.thenElse(poly1, poly0)); + } + + float evaluate_n(float val, float diff, int count, float* output) const override { + Sk4f sum(0); + while (count >= 4) { + float v0 = val; + float v1 = val += diff; + float v2 = val += diff; + float v3 = val += diff; + val += diff; + Sk4f filterValue = evalcore_n(Sk4f(v0, v1, v2, v3)); + filterValue.store(output); + output += 4; + sum = sum + filterValue; + count -= 4; + } + float sums[4]; + sum.store(sums); + float result = sums[0] + sums[1] + sums[2] + sums[3]; + result += INHERITED::evaluate_n(val, diff, count, output); + return result; + } #endif protected: @@ -181,52 +178,47 @@ class SkMitchellFilter : public SkBitmapFilter { float fA1, fB1, fC1, fD1; float fA2, fB2, fD2; #endif - private: - typedef SkBitmapFilter INHERITED; +private: + typedef SkBitmapFilter INHERITED; }; -class SkGaussianFilter: public SkBitmapFilter { - public: - SkGaussianFilter(float a, float width=2.0f) - : SkBitmapFilter(width), alpha(a), expWidth(expf(-alpha * width * width)) { - } +class SkGaussianFilter final : public SkBitmapFilter { + float fAlpha, fExpWidth; - float evaluate(float x) const override { - return SkTMax(0.f, float(expf(-alpha*x*x) - expWidth)); - } - protected: - float alpha, expWidth; +public: + SkGaussianFilter(float a, float width = 2) + : SkBitmapFilter(width) + , fAlpha(a) + , fExpWidth(expf(-a * width * width)) + {} + + float evaluate(float x) const override { + return SkTMax(0.f, float(expf(-fAlpha*x*x) - fExpWidth)); + } }; -class SkTriangleFilter: public SkBitmapFilter { - public: - SkTriangleFilter(float width=1) - : SkBitmapFilter(width) { - } +class SkTriangleFilter final : public SkBitmapFilter { +public: + SkTriangleFilter(float width = 1) : SkBitmapFilter(width) {} - float evaluate(float x) const override { - return SkTMax(0.f, fWidth - fabsf(x)); - } - protected: + float evaluate(float x) const override { + return SkTMax(0.f, fWidth - fabsf(x)); + } }; -class SkBoxFilter: public SkBitmapFilter { - public: - SkBoxFilter(float width=0.5f) - : SkBitmapFilter(width) { - } +class SkBoxFilter final : public SkBitmapFilter { +public: + SkBoxFilter(float width = 0.5f) : SkBitmapFilter(width) {} - float evaluate(float x) const override { - return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f; - } - protected: + float evaluate(float x) const override { + return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f; + } }; -class SkHammingFilter: public SkBitmapFilter { +class SkHammingFilter final : public SkBitmapFilter { public: - SkHammingFilter(float width=1.f) - : SkBitmapFilter(width) { - } + SkHammingFilter(float width = 1) : SkBitmapFilter(width) {} + float evaluate(float x) const override { if (x <= -fWidth || x >= fWidth) { return 0.0f; // Outside of the window. @@ -241,23 +233,21 @@ public: } }; -class SkLanczosFilter: public SkBitmapFilter { - public: - SkLanczosFilter(float width=3.f) - : SkBitmapFilter(width) { - } - - float evaluate(float x) const override { - if (x <= -fWidth || x >= fWidth) { - return 0.0f; // Outside of the window. - } - if (x > -FLT_EPSILON && x < FLT_EPSILON) { - return 1.0f; // Special case the discontinuity at the origin. - } - float xpi = x * static_cast<float>(SK_ScalarPI); - return (sk_float_sin(xpi) / xpi) * // sinc(x) - sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth) - } +class SkLanczosFilter final : public SkBitmapFilter { +public: + SkLanczosFilter(float width = 3.f) : SkBitmapFilter(width) {} + + float evaluate(float x) const override { + if (x <= -fWidth || x >= fWidth) { + return 0.0f; // Outside of the window. + } + if (x > -FLT_EPSILON && x < FLT_EPSILON) { + return 1.0f; // Special case the discontinuity at the origin. + } + float xpi = x * static_cast<float>(SK_ScalarPI); + return (sk_float_sin(xpi) / xpi) * // sinc(x) + sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth) + } }; |