| Index: src/core/SkBitmapFilter.h
|
| diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h
|
| index 38c2448c690406d148a8e409f142fc7a7f95cab8..6a9e3d7c01c49b3cf4a1f32affa7646dad04ccaa 100644
|
| --- a/src/core/SkBitmapFilter.h
|
| +++ b/src/core/SkBitmapFilter.h
|
| @@ -26,28 +26,30 @@ class SkBitmapFilter {
|
| fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1);
|
| }
|
|
|
| - SkFixed lookup( float x ) const {
|
| + 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 ];
|
| + return fFilterTable[filter_idx];
|
| }
|
|
|
| - SkScalar lookupScalar( float x ) const {
|
| + 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 ];
|
| + return fFilterTableScalar[filter_idx];
|
| }
|
|
|
| float width() const { return fWidth; }
|
| float invWidth() const { return fInvWidth; }
|
| virtual float evaluate(float x) const = 0;
|
| virtual ~SkBitmapFilter() {}
|
| +
|
| + static SkBitmapFilter* Allocate();
|
| protected:
|
| float fWidth;
|
| float fInvWidth;
|
| @@ -126,29 +128,47 @@ class SkBoxFilter: public SkBitmapFilter {
|
| }
|
|
|
| virtual float evaluate(float x) const SK_OVERRIDE {
|
| - return 1;
|
| + return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f;
|
| }
|
| protected:
|
| };
|
|
|
| +class SkHammingFilter: public SkBitmapFilter {
|
| +public:
|
| + SkHammingFilter(float width=1.f)
|
| + : SkBitmapFilter(width) {
|
| + }
|
| + virtual float evaluate(float x) const SK_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 sinc discontinuity at the origin.
|
| + }
|
| + const float xpi = x * static_cast<float>(M_PI);
|
| +
|
| + return ((sk_float_sin(xpi) / xpi) * // sinc(x)
|
| + (0.54f + 0.46f * sk_float_cos(xpi / fWidth))); // hamming(x)
|
| + }
|
| +};
|
|
|
| -class SkSincFilter: public SkBitmapFilter {
|
| +class SkLanczosFilter: public SkBitmapFilter {
|
| public:
|
| - SkSincFilter(float t, float width=3.f)
|
| - : SkBitmapFilter(width), tau(t) {
|
| + SkLanczosFilter(float width=3.f)
|
| + : SkBitmapFilter(width) {
|
| }
|
|
|
| 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 *= SK_ScalarPI;
|
| - float sinc = sk_float_sin(x) / x;
|
| - float lanczos = sk_float_sin(x * tau) / (x * tau);
|
| - return sinc * lanczos;
|
| - }
|
| - protected:
|
| - float tau;
|
| + 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>(M_PI);
|
| + return (sk_float_sin(xpi) / xpi) * // sinc(x)
|
| + sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth)
|
| + }
|
| };
|
|
|
|
|
|
|