OLD | NEW |
(Empty) | |
| 1 |
| 2 /* |
| 3 * Copyright 2013 Google Inc. |
| 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. |
| 7 */ |
| 8 |
| 9 |
| 10 #ifndef SkBitmapFilter_DEFINED |
| 11 #define SkBitmapFilter_DEFINED |
| 12 |
| 13 #include "SkMath.h" |
| 14 |
| 15 // size of the precomputed bitmap filter tables for high quality filtering. |
| 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. |
| 18 |
| 19 #define SKBITMAP_FILTER_TABLE_SIZE 32 |
| 20 |
| 21 class SkBitmapFilter { |
| 22 public: |
| 23 SkBitmapFilter(float width) |
| 24 : fWidth(width), fInvWidth(1.f/width) { |
| 25 precomputed = false; |
| 26 } |
| 27 |
| 28 SkFixed lookup( float x ) const { |
| 29 if (!precomputed) { |
| 30 precomputeTable(); |
| 31 } |
| 32 int filter_idx = int(fabsf(x * invWidth() * SKBITMAP_FILTER_TABLE_SIZE
)); |
| 33 return fFilterTable[ SkTMin(filter_idx, SKBITMAP_FILTER_TABLE_SIZE-1)
]; |
| 34 } |
| 35 |
| 36 float lookupFloat( float x ) const { |
| 37 if (!precomputed) { |
| 38 precomputeTable(); |
| 39 } |
| 40 int filter_idx = int(fabsf(x * invWidth() * SKBITMAP_FILTER_TABLE_SIZE
)); |
| 41 return fFilterTableFloat[ SkTMin(filter_idx, SKBITMAP_FILTER_TABLE_SIZ
E-1) ]; |
| 42 } |
| 43 |
| 44 float width() const { return fWidth; } |
| 45 float invWidth() const { return fInvWidth; } |
| 46 virtual float evaluate(float x) const = 0; |
| 47 virtual ~SkBitmapFilter() {} |
| 48 protected: |
| 49 float fWidth; |
| 50 float fInvWidth; |
| 51 |
| 52 mutable bool precomputed; |
| 53 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; |
| 54 mutable float fFilterTableFloat[SKBITMAP_FILTER_TABLE_SIZE]; |
| 55 private: |
| 56 void precomputeTable() const { |
| 57 precomputed = true; |
| 58 SkFixed *ftp = fFilterTable; |
| 59 float *ftp_float = fFilterTableFloat; |
| 60 for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) { |
| 61 float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABL
E_SIZE; |
| 62 float filter_value = evaluate(fx); |
| 63 *ftp_float++ = filter_value; |
| 64 *ftp++ = SkFloatToFixed(filter_value); |
| 65 } |
| 66 } |
| 67 }; |
| 68 |
| 69 class SkMitchellFilter: public SkBitmapFilter { |
| 70 public: |
| 71 SkMitchellFilter(float b, float c, float width=2.0f) |
| 72 : SkBitmapFilter(width), B(b), C(c) { |
| 73 } |
| 74 |
| 75 virtual float evaluate(float x) const SK_OVERRIDE { |
| 76 x = fabsf(x); |
| 77 if (x > 2.f) { |
| 78 return 0; |
| 79 } else if (x > 1.f) { |
| 80 return ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x + |
| 81 (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f); |
| 82 } else { |
| 83 return ((12 - 9*B - 6*C) * x*x*x + |
| 84 (-18 + 12*B + 6*C) * x*x + |
| 85 (6 - 2*B)) * (1.f/6.f); |
| 86 } |
| 87 } |
| 88 protected: |
| 89 float B, C; |
| 90 }; |
| 91 |
| 92 class SkGaussianFilter: public SkBitmapFilter { |
| 93 public: |
| 94 SkGaussianFilter(float a, float width=2.0f) |
| 95 : SkBitmapFilter(width), alpha(a), expWidth(expf(-alpha * width * width))
{ |
| 96 } |
| 97 |
| 98 virtual float evaluate(float x) const SK_OVERRIDE { |
| 99 return SkTMax(0.f, float(expf(-alpha*x*x) - expWidth)); |
| 100 } |
| 101 protected: |
| 102 float alpha, expWidth; |
| 103 }; |
| 104 |
| 105 class SkTriangleFilter: public SkBitmapFilter { |
| 106 public: |
| 107 SkTriangleFilter(float width=1) |
| 108 : SkBitmapFilter(width) { |
| 109 } |
| 110 |
| 111 virtual float evaluate(float x) const SK_OVERRIDE { |
| 112 return SkTMax(0.f, fWidth - fabsf(x)); |
| 113 } |
| 114 protected: |
| 115 }; |
| 116 |
| 117 class SkBoxFilter: public SkBitmapFilter { |
| 118 public: |
| 119 SkBoxFilter(float width=0.5f) |
| 120 : SkBitmapFilter(width) { |
| 121 } |
| 122 |
| 123 virtual float evaluate(float x) const SK_OVERRIDE { |
| 124 return 1; |
| 125 } |
| 126 protected: |
| 127 }; |
| 128 |
| 129 |
| 130 class SkSincFilter: public SkBitmapFilter { |
| 131 public: |
| 132 SkSincFilter(float t, float width=3.f) |
| 133 : SkBitmapFilter(width), tau(t) { |
| 134 } |
| 135 |
| 136 virtual float evaluate(float x) const SK_OVERRIDE { |
| 137 x = sk_float_abs(x * fInvWidth); |
| 138 if (x < 1e-5f) return 1.f; |
| 139 if (x > 1.f) return 0.f; |
| 140 x *= (float) M_PI; |
| 141 float sinc = sk_float_sin(x) / x; |
| 142 float lanczos = sk_float_sin(x * tau) / (x * tau); |
| 143 return sinc * lanczos; |
| 144 } |
| 145 protected: |
| 146 float tau; |
| 147 }; |
| 148 |
| 149 |
| 150 #endif |
OLD | NEW |