Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(658)

Side by Side Diff: src/core/SkBitmapFilter.h

Issue 19335002: Production quality fast image up/downsampler (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: clean up use of filter quality flags Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <limits>
13 #include "SkMath.h" 14 #include "SkMath.h"
14 15
15 // size of the precomputed bitmap filter tables for high quality filtering. 16 // size of the precomputed bitmap filter tables for high quality filtering.
16 // Used to precompute the shape of the filter kernel. 17 // 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. 18 // Table size chosen from experiments to see where I could start to see a differ ence.
18 19
19 #define SKBITMAP_FILTER_TABLE_SIZE 128 20 #define SKBITMAP_FILTER_TABLE_SIZE 128
20 21
21 class SkBitmapFilter { 22 class SkBitmapFilter {
22 public: 23 public:
23 SkBitmapFilter(float width) 24 SkBitmapFilter(float width)
24 : fWidth(width), fInvWidth(1.f/width) { 25 : fWidth(width), fInvWidth(1.f/width) {
25 fPrecomputed = false; 26 fPrecomputed = false;
26 fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1); 27 fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1);
27 } 28 }
28 29
29 SkFixed lookup( float x ) const { 30 SkFixed lookup(float x) const {
30 if (!fPrecomputed) { 31 if (!fPrecomputed) {
31 precomputeTable(); 32 precomputeTable();
32 } 33 }
33 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); 34 int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
34 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); 35 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
35 return fFilterTable[ filter_idx ]; 36 return fFilterTable[filter_idx];
36 } 37 }
37 38
38 SkScalar lookupScalar( float x ) const { 39 SkScalar lookupScalar(float x) const {
39 if (!fPrecomputed) { 40 if (!fPrecomputed) {
40 precomputeTable(); 41 precomputeTable();
41 } 42 }
42 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); 43 int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
43 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); 44 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
44 return fFilterTableScalar[ filter_idx ]; 45 return fFilterTableScalar[filter_idx];
45 } 46 }
46 47
47 float width() const { return fWidth; } 48 float width() const { return fWidth; }
48 float invWidth() const { return fInvWidth; } 49 float invWidth() const { return fInvWidth; }
49 virtual float evaluate(float x) const = 0; 50 virtual float evaluate(float x) const = 0;
50 virtual ~SkBitmapFilter() {} 51 virtual ~SkBitmapFilter() {}
52
53 static SkBitmapFilter *allocate();
51 protected: 54 protected:
52 float fWidth; 55 float fWidth;
53 float fInvWidth; 56 float fInvWidth;
54 57
55 float fLookupMultiplier; 58 float fLookupMultiplier;
56 59
57 mutable bool fPrecomputed; 60 mutable bool fPrecomputed;
58 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; 61 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE];
59 mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE]; 62 mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE];
60 private: 63 private:
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 protected: 122 protected:
120 }; 123 };
121 124
122 class SkBoxFilter: public SkBitmapFilter { 125 class SkBoxFilter: public SkBitmapFilter {
123 public: 126 public:
124 SkBoxFilter(float width=0.5f) 127 SkBoxFilter(float width=0.5f)
125 : SkBitmapFilter(width) { 128 : SkBitmapFilter(width) {
126 } 129 }
127 130
128 virtual float evaluate(float x) const SK_OVERRIDE { 131 virtual float evaluate(float x) const SK_OVERRIDE {
129 return 1; 132 return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f;
130 } 133 }
131 protected: 134 protected:
132 }; 135 };
133 136
137 class SkHammingFilter: public SkBitmapFilter {
138 public:
139 SkHammingFilter(float width=1.f)
140 : SkBitmapFilter(width) {
141 }
142 virtual float evaluate(float x) const {
143 if (x <= -fWidth || x >= fWidth)
144 return 0.0f; // Outside of the window.
145 if (x > -std::numeric_limits<float>::epsilon() &&
146 x < std::numeric_limits<float>::epsilon())
147 return 1.0f; // Special case the sinc discontinuity at the origin.
148 const float xpi = x * static_cast<float>(M_PI);
149
150 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.
151 (0.54f + 0.46f * cos(xpi / fWidth))); // hamming(x)
152 }
153 };
134 154
135 class SkSincFilter: public SkBitmapFilter { 155 class SkSincFilter: public SkBitmapFilter {
136 public: 156 public:
137 SkSincFilter(float t, float width=3.f) 157 SkSincFilter(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 > -std::numeric_limits<float>::epsilon() &&
146 float sinc = sk_float_sin(x) / x; 166 x < std::numeric_limits<float>::epsilon()) {
147 float lanczos = sk_float_sin(x * tau) / (x * tau); 167 return 1.0f; // Special case the discontinuity at the origin.
148 return sinc * lanczos; 168 }
149 } 169 float xpi = x * static_cast<float>(M_PI);
150 protected: 170 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.
151 float tau; 171 sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/filter_size)
172 }
152 }; 173 };
153 174
154 175
155 #endif 176 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698