diff options
author | 2013-07-19 20:20:04 +0000 | |
---|---|---|
committer | 2013-07-19 20:20:04 +0000 | |
commit | 138ebc3e4061cf533ea2f7f3717239670fdc6e43 (patch) | |
tree | a9bbf3d68a36e5938b5a41df954ad0471b2e20e2 /src/core/SkBitmapFilter.h | |
parent | d322cf4939872bbff063468d7357c76eb6250d0f (diff) |
The image resampling code has been transplanted from Chrome; it's incredibly fast.
We've tested this CL plumbed into Chrome and done benchmarking with excellent results.
This CL can land independent of any Chrome changes; it's completely internal to skia.
BUG=
R=reed@google.com
Review URL: https://codereview.chromium.org/19335002
git-svn-id: http://skia.googlecode.com/svn/trunk@10206 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkBitmapFilter.h')
-rw-r--r-- | src/core/SkBitmapFilter.h | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h index 38c2448c69..6a9e3d7c01 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) + } }; |