aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBitmapFilter.h
diff options
context:
space:
mode:
authorGravatar humper@google.com <humper@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-19 20:20:04 +0000
committerGravatar humper@google.com <humper@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-19 20:20:04 +0000
commit138ebc3e4061cf533ea2f7f3717239670fdc6e43 (patch)
treea9bbf3d68a36e5938b5a41df954ad0471b2e20e2 /src/core/SkBitmapFilter.h
parentd322cf4939872bbff063468d7357c76eb6250d0f (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.h56
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)
+ }
};