OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #ifndef SkBitmapFilter_DEFINED | 10 #ifndef SkBitmapFilter_DEFINED |
11 #define SkBitmapFilter_DEFINED | 11 #define SkBitmapFilter_DEFINED |
12 | 12 |
13 #include "SkMath.h" | 13 #include "SkMath.h" |
14 | 14 |
15 // size of the precomputed bitmap filter tables for high quality filtering. | 15 // size of the precomputed bitmap filter tables for high quality filtering. |
16 // Used to precompute the shape of the filter kernel. | 16 // Used to precompute the shape of the filter kernel. |
17 // Table size chosen from experiments to see where I could start to see a differ
ence. | 17 // Table size chosen from experiments to see where I could start to see a differ
ence. |
18 | 18 |
19 #define SKBITMAP_FILTER_TABLE_SIZE 128 | 19 #define SKBITMAP_FILTER_TABLE_SIZE 128 |
20 | 20 |
21 class SkBitmapFilter { | 21 class SkBitmapFilter { |
22 public: | 22 public: |
23 SkBitmapFilter(float width) | 23 SkBitmapFilter(float width) |
24 : fWidth(width), fInvWidth(1.f/width) { | 24 : fWidth(width), fInvWidth(1.f/width) { |
25 fPrecomputed = false; | 25 fPrecomputed = false; |
26 fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1); | 26 fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1); |
27 } | 27 } |
28 | 28 |
29 SkFixed lookup( float x ) const { | 29 SkFixed lookup(float x) const { |
30 if (!fPrecomputed) { | 30 if (!fPrecomputed) { |
31 precomputeTable(); | 31 precomputeTable(); |
32 } | 32 } |
33 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); | 33 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); |
34 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); | 34 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); |
35 return fFilterTable[ filter_idx ]; | 35 return fFilterTable[filter_idx]; |
36 } | 36 } |
37 | 37 |
38 SkScalar lookupScalar( float x ) const { | 38 SkScalar lookupScalar(float x) const { |
39 if (!fPrecomputed) { | 39 if (!fPrecomputed) { |
40 precomputeTable(); | 40 precomputeTable(); |
41 } | 41 } |
42 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); | 42 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); |
43 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); | 43 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); |
44 return fFilterTableScalar[ filter_idx ]; | 44 return fFilterTableScalar[filter_idx]; |
45 } | 45 } |
46 | 46 |
47 float width() const { return fWidth; } | 47 float width() const { return fWidth; } |
48 float invWidth() const { return fInvWidth; } | 48 float invWidth() const { return fInvWidth; } |
49 virtual float evaluate(float x) const = 0; | 49 virtual float evaluate(float x) const = 0; |
50 virtual ~SkBitmapFilter() {} | 50 virtual ~SkBitmapFilter() {} |
| 51 |
| 52 static SkBitmapFilter* Allocate(); |
51 protected: | 53 protected: |
52 float fWidth; | 54 float fWidth; |
53 float fInvWidth; | 55 float fInvWidth; |
54 | 56 |
55 float fLookupMultiplier; | 57 float fLookupMultiplier; |
56 | 58 |
57 mutable bool fPrecomputed; | 59 mutable bool fPrecomputed; |
58 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; | 60 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; |
59 mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE]; | 61 mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE]; |
60 private: | 62 private: |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 protected: | 121 protected: |
120 }; | 122 }; |
121 | 123 |
122 class SkBoxFilter: public SkBitmapFilter { | 124 class SkBoxFilter: public SkBitmapFilter { |
123 public: | 125 public: |
124 SkBoxFilter(float width=0.5f) | 126 SkBoxFilter(float width=0.5f) |
125 : SkBitmapFilter(width) { | 127 : SkBitmapFilter(width) { |
126 } | 128 } |
127 | 129 |
128 virtual float evaluate(float x) const SK_OVERRIDE { | 130 virtual float evaluate(float x) const SK_OVERRIDE { |
129 return 1; | 131 return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f; |
130 } | 132 } |
131 protected: | 133 protected: |
132 }; | 134 }; |
133 | 135 |
| 136 class SkHammingFilter: public SkBitmapFilter { |
| 137 public: |
| 138 SkHammingFilter(float width=1.f) |
| 139 : SkBitmapFilter(width) { |
| 140 } |
| 141 virtual float evaluate(float x) const SK_OVERRIDE { |
| 142 if (x <= -fWidth || x >= fWidth) { |
| 143 return 0.0f; // Outside of the window. |
| 144 } |
| 145 if (x > -FLT_EPSILON && x < FLT_EPSILON) { |
| 146 return 1.0f; // Special case the sinc discontinuity at the origin. |
| 147 } |
| 148 const float xpi = x * static_cast<float>(M_PI); |
134 | 149 |
135 class SkSincFilter: public SkBitmapFilter { | 150 return ((sk_float_sin(xpi) / xpi) * // sinc(x) |
| 151 (0.54f + 0.46f * sk_float_cos(xpi / fWidth))); // hamming(x) |
| 152 } |
| 153 }; |
| 154 |
| 155 class SkLanczosFilter: public SkBitmapFilter { |
136 public: | 156 public: |
137 SkSincFilter(float t, float width=3.f) | 157 SkLanczosFilter(float width=3.f) |
138 : SkBitmapFilter(width), tau(t) { | 158 : SkBitmapFilter(width) { |
139 } | 159 } |
140 | 160 |
141 virtual float evaluate(float x) const SK_OVERRIDE { | 161 virtual float evaluate(float x) const SK_OVERRIDE { |
142 x = sk_float_abs(x * fInvWidth); | 162 if (x <= -fWidth || x >= fWidth) { |
143 if (x < 1e-5f) return 1.f; | 163 return 0.0f; // Outside of the window. |
144 if (x > 1.f) return 0.f; | 164 } |
145 x *= SK_ScalarPI; | 165 if (x > -FLT_EPSILON && x < FLT_EPSILON) { |
146 float sinc = sk_float_sin(x) / x; | 166 return 1.0f; // Special case the discontinuity at the origin. |
147 float lanczos = sk_float_sin(x * tau) / (x * tau); | 167 } |
148 return sinc * lanczos; | 168 float xpi = x * static_cast<float>(M_PI); |
149 } | 169 return (sk_float_sin(xpi) / xpi) * // sinc(x) |
150 protected: | 170 sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth
) |
151 float tau; | 171 } |
152 }; | 172 }; |
153 | 173 |
154 | 174 |
155 #endif | 175 #endif |
OLD | NEW |