Chromium Code Reviews| Index: src/core/SkBitmapFilter.h |
| diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h |
| index 38c2448c690406d148a8e409f142fc7a7f95cab8..749f602f903f59511558a7e33616fe3df3bb7a07 100644 |
| --- a/src/core/SkBitmapFilter.h |
| +++ b/src/core/SkBitmapFilter.h |
| @@ -10,6 +10,7 @@ |
| #ifndef SkBitmapFilter_DEFINED |
| #define SkBitmapFilter_DEFINED |
| +#include <limits> |
| #include "SkMath.h" |
| // size of the precomputed bitmap filter tables for high quality filtering. |
| @@ -26,28 +27,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 +129,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 { |
| + if (x <= -fWidth || x >= fWidth) |
| + return 0.0f; // Outside of the window. |
| + if (x > -std::numeric_limits<float>::epsilon() && |
| + x < std::numeric_limits<float>::epsilon()) |
| + return 1.0f; // Special case the sinc discontinuity at the origin. |
| + const float xpi = x * static_cast<float>(M_PI); |
| + |
| + return ((sin(xpi) / xpi) * // sinc(x) |
|
reed1
2013/07/18 13:42:12
this is the double version of sin. Do you want sk_
humper
2013/07/18 17:11:04
Done.
|
| + (0.54f + 0.46f * cos(xpi / fWidth))); // hamming(x) |
| + } |
| +}; |
| class SkSincFilter: public SkBitmapFilter { |
| public: |
| - SkSincFilter(float t, float width=3.f) |
| - : SkBitmapFilter(width), tau(t) { |
| + SkSincFilter(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 > -std::numeric_limits<float>::epsilon() && |
| + x < std::numeric_limits<float>::epsilon()) { |
| + return 1.0f; // Special case the discontinuity at the origin. |
| + } |
| + float xpi = x * static_cast<float>(M_PI); |
| + return (sin(xpi) / xpi) * // sinc(x) |
|
reed1
2013/07/18 13:42:12
similar question about sin -vs- sk_float_sin
humper
2013/07/18 17:11:04
Done.
|
| + sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/filter_size) |
| + } |
| }; |