/src/FreeImage/Source/FreeImageToolkit/Filters.h
C++ Header | 287 lines | 123 code | 32 blank | 132 comment | 13 complexity | 57baaf8baaa355fb565aacee7bc4995e MD5 | raw file
1// ========================================================== 2// Upsampling / downsampling filters 3// 4// Design and implementation by 5// - Hervé Drolon (drolon@infonie.fr) 6// 7// This file is part of FreeImage 3 8// 9// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY 10// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES 11// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE 12// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED 13// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT 14// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY 15// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL 16// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER 17// THIS DISCLAIMER. 18// 19// Use at your own risk! 20// ========================================================== 21 22#ifndef _FILTERS_H_ 23#define _FILTERS_H_ 24 25/** 26 CGenericFilter is a generic abstract filter class used to access to the filter library.<br> 27 Filters used in this library have been mainly taken from the following references : <br> 28<b>Main reference</b> : <br> 29Paul Heckbert, C code to zoom raster images up or down, with nice filtering. 30UC Berkeley, August 1989. [online] http://www-2.cs.cmu.edu/afs/cs.cmu.edu/Web/People/ph/heckbert.html 31 32<b>Heckbert references</b> : <br> 33<ul> 34<li>Oppenheim A.V., Schafer R.W., Digital Signal Processing, Prentice-Hall, 1975 35<li>Hamming R.W., Digital Filters, Prentice-Hall, Englewood Cliffs, NJ, 1983 36<li>Pratt W.K., Digital Image Processing, John Wiley and Sons, 1978 37<li>Hou H.S., Andrews H.C., "Cubic Splines for Image Interpolation and Digital Filtering", 38IEEE Trans. Acoustics, Speech, and Signal Proc., vol. ASSP-26, no. 6, pp. 508-517, Dec. 1978. 39</ul> 40 41*/ 42class CGenericFilter 43{ 44protected: 45 46 #define FILTER_PI double (3.1415926535897932384626433832795) 47 #define FILTER_2PI double (2.0 * 3.1415926535897932384626433832795) 48 #define FILTER_4PI double (4.0 * 3.1415926535897932384626433832795) 49 50 /// Filter support 51 double m_dWidth; 52 53public: 54 55 /// Constructor 56 CGenericFilter (double dWidth) : m_dWidth (dWidth) {} 57 /// Destructor 58 virtual ~CGenericFilter() {} 59 60 /// Returns the filter support 61 double GetWidth() { return m_dWidth; } 62 /// Change the filter suport 63 void SetWidth (double dWidth) { m_dWidth = dWidth; } 64 65 /// Returns F(dVal) where F is the filter's impulse response 66 virtual double Filter (double dVal) = 0; 67}; 68 69// ----------------------------------------------------------------------------------- 70// Filters library 71// All filters are centered on 0 72// ----------------------------------------------------------------------------------- 73 74/** 75 Box filter<br> 76 Box, pulse, Fourier window, 1st order (constant) b-spline.<br><br> 77 78 <b>Reference</b> : <br> 79 Glassner A.S., Principles of digital image synthesis. Morgan Kaufmann Publishers, Inc, San Francisco, Vol. 2, 1995 80*/ 81class CBoxFilter : public CGenericFilter 82{ 83public: 84 /** 85 Constructor<br> 86 Default fixed width = 0.5 87 */ 88 CBoxFilter() : CGenericFilter(0.5) {} 89 virtual ~CBoxFilter() {} 90 91 double Filter (double dVal) { return (fabs(dVal) <= m_dWidth ? 1.0 : 0.0); } 92}; 93 94/** Bilinear filter 95*/ 96class CBilinearFilter : public CGenericFilter 97{ 98public: 99 100 CBilinearFilter () : CGenericFilter(1) {} 101 virtual ~CBilinearFilter() {} 102 103 double Filter (double dVal) { 104 dVal = fabs(dVal); 105 return (dVal < m_dWidth ? m_dWidth - dVal : 0.0); 106 } 107}; 108 109 110/** 111 Mitchell & Netravali's two-param cubic filter<br> 112 113 The parameters b and c can be used to adjust the properties of the cubic. 114 They are sometimes referred to as "blurring" and "ringing" respectively. 115 The default is b = 1/3 and c = 1/3, which were the values recommended by 116 Mitchell and Netravali as yielding the most visually pleasing results in subjective tests of human beings. 117 Larger values of b and c can produce interesting op-art effects--for example, try b = 0 and c = -5. <br><br> 118 119 <b>Reference</b> : <br> 120 Don P. Mitchell and Arun N. Netravali, Reconstruction filters in computer graphics. 121 In John Dill, editor, Computer Graphics (SIGGRAPH '88 Proceedings), Vol. 22, No. 4, August 1988, pp. 221-228. 122*/ 123class CBicubicFilter : public CGenericFilter 124{ 125protected: 126 // data for parameterized Mitchell filter 127 double p0, p2, p3; 128 double q0, q1, q2, q3; 129 130public: 131 /** 132 Constructor<br> 133 Default fixed width = 2 134 @param b Filter parameter (default value is 1/3) 135 @param c Filter parameter (default value is 1/3) 136 */ 137 CBicubicFilter (double b = (1/(double)3), double c = (1/(double)3)) : CGenericFilter(2) { 138 p0 = (6 - 2*b) / 6; 139 p2 = (-18 + 12*b + 6*c) / 6; 140 p3 = (12 - 9*b - 6*c) / 6; 141 q0 = (8*b + 24*c) / 6; 142 q1 = (-12*b - 48*c) / 6; 143 q2 = (6*b + 30*c) / 6; 144 q3 = (-b - 6*c) / 6; 145 } 146 virtual ~CBicubicFilter() {} 147 148 double Filter(double dVal) { 149 dVal = fabs(dVal); 150 if(dVal < 1) 151 return (p0 + dVal*dVal*(p2 + dVal*p3)); 152 if(dVal < 2) 153 return (q0 + dVal*(q1 + dVal*(q2 + dVal*q3))); 154 return 0; 155 } 156}; 157 158/** 159 Catmull-Rom spline, Overhauser spline<br> 160 161 When using CBicubicFilter filters, you have to set parameters b and c such that <br> 162 b + 2 * c = 1<br> 163 in order to use the numerically most accurate filter.<br> 164 This gives for b = 0 the maximum value for c = 0.5, which is the Catmull-Rom 165 spline and a good suggestion for sharpness.<br><br> 166 167 168 <b>References</b> : <br> 169 <ul> 170 <li>Mitchell Don P., Netravali Arun N., Reconstruction filters in computer graphics. 171 In John Dill, editor, Computer Graphics (SIGGRAPH '88 Proceedings), Vol. 22, No. 4, August 1988, pp. 221-228. 172 <li>Keys R.G., Cubic Convolution Interpolation for Digital Image Processing. 173 IEEE Trans. Acoustics, Speech, and Signal Processing, vol. 29, no. 6, pp. 1153-1160, Dec. 1981. 174 </ul> 175 176*/ 177class CCatmullRomFilter : public CGenericFilter 178{ 179public: 180 181 /** 182 Constructor<br> 183 Default fixed width = 2 184 */ 185 CCatmullRomFilter() : CGenericFilter(2) {} 186 virtual ~CCatmullRomFilter() {} 187 188 double Filter(double dVal) { 189 if(dVal < -2) return 0; 190 if(dVal < -1) return (0.5*(4 + dVal*(8 + dVal*(5 + dVal)))); 191 if(dVal < 0) return (0.5*(2 + dVal*dVal*(-5 - 3*dVal))); 192 if(dVal < 1) return (0.5*(2 + dVal*dVal*(-5 + 3*dVal))); 193 if(dVal < 2) return (0.5*(4 + dVal*(-8 + dVal*(5 - dVal)))); 194 return 0; 195 } 196}; 197 198/** 199 Lanczos-windowed sinc filter<br> 200 201 Lanczos3 filter is an alternative to CBicubicFilter with high values of c about 0.6 ... 0.75 202 which produces quite strong sharpening. It usually offers better quality (fewer artifacts) and a sharp image.<br><br> 203 204*/ 205class CLanczos3Filter : public CGenericFilter 206{ 207public: 208 /** 209 Constructor<br> 210 Default fixed width = 3 211 */ 212 CLanczos3Filter() : CGenericFilter(3) {} 213 virtual ~CLanczos3Filter() {} 214 215 double Filter(double dVal) { 216 dVal = fabs(dVal); 217 if(dVal < m_dWidth) { 218 return (sinc(dVal) * sinc(dVal / m_dWidth)); 219 } 220 return 0; 221 } 222 223private: 224 double sinc(double value) { 225 if(value != 0) { 226 value *= FILTER_PI; 227 return (sin(value) / value); 228 } 229 return 1; 230 } 231}; 232 233/** 234 4th order (cubic) b-spline<br> 235 236*/ 237class CBSplineFilter : public CGenericFilter 238{ 239public: 240 241 /** 242 Constructor<br> 243 Default fixed width = 2 244 */ 245 CBSplineFilter() : CGenericFilter(2) {} 246 virtual ~CBSplineFilter() {} 247 248 double Filter(double dVal) { 249 250 dVal = fabs(dVal); 251 if(dVal < 1) return (4 + dVal*dVal*(-6 + 3*dVal)) / 6; 252 if(dVal < 2) { 253 double t = 2 - dVal; 254 return (t*t*t / 6); 255 } 256 return 0; 257 } 258}; 259 260// ----------------------------------------------------------------------------------- 261// Window function library 262// ----------------------------------------------------------------------------------- 263 264/** 265 Blackman window 266*/ 267class CBlackmanFilter : public CGenericFilter 268{ 269public: 270 /** 271 Constructor<br> 272 Default width = 0.5 273 */ 274 CBlackmanFilter (double dWidth = double(0.5)) : CGenericFilter(dWidth) {} 275 virtual ~CBlackmanFilter() {} 276 277 double Filter (double dVal) { 278 if(fabs (dVal) > m_dWidth) { 279 return 0; 280 } 281 double dN = 2 * m_dWidth + 1; 282 dVal /= (dN - 1); 283 return 0.42 + 0.5*cos(FILTER_2PI*dVal) + 0.08*cos(FILTER_4PI*dVal); 284 } 285}; 286 287#endif // _FILTERS_H_