/src/FreeImage/Source/FreeImageToolkit/Filters.h

https://bitbucket.org/cabalistic/ogredeps/ · 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. #ifndef _FILTERS_H_
  22. #define _FILTERS_H_
  23. /**
  24. CGenericFilter is a generic abstract filter class used to access to the filter library.<br>
  25. Filters used in this library have been mainly taken from the following references : <br>
  26. <b>Main reference</b> : <br>
  27. Paul Heckbert, C code to zoom raster images up or down, with nice filtering.
  28. UC Berkeley, August 1989. [online] http://www-2.cs.cmu.edu/afs/cs.cmu.edu/Web/People/ph/heckbert.html
  29. <b>Heckbert references</b> : <br>
  30. <ul>
  31. <li>Oppenheim A.V., Schafer R.W., Digital Signal Processing, Prentice-Hall, 1975
  32. <li>Hamming R.W., Digital Filters, Prentice-Hall, Englewood Cliffs, NJ, 1983
  33. <li>Pratt W.K., Digital Image Processing, John Wiley and Sons, 1978
  34. <li>Hou H.S., Andrews H.C., "Cubic Splines for Image Interpolation and Digital Filtering",
  35. IEEE Trans. Acoustics, Speech, and Signal Proc., vol. ASSP-26, no. 6, pp. 508-517, Dec. 1978.
  36. </ul>
  37. */
  38. class CGenericFilter
  39. {
  40. protected:
  41. #define FILTER_PI double (3.1415926535897932384626433832795)
  42. #define FILTER_2PI double (2.0 * 3.1415926535897932384626433832795)
  43. #define FILTER_4PI double (4.0 * 3.1415926535897932384626433832795)
  44. /// Filter support
  45. double m_dWidth;
  46. public:
  47. /// Constructor
  48. CGenericFilter (double dWidth) : m_dWidth (dWidth) {}
  49. /// Destructor
  50. virtual ~CGenericFilter() {}
  51. /// Returns the filter support
  52. double GetWidth() { return m_dWidth; }
  53. /// Change the filter suport
  54. void SetWidth (double dWidth) { m_dWidth = dWidth; }
  55. /// Returns F(dVal) where F is the filter's impulse response
  56. virtual double Filter (double dVal) = 0;
  57. };
  58. // -----------------------------------------------------------------------------------
  59. // Filters library
  60. // All filters are centered on 0
  61. // -----------------------------------------------------------------------------------
  62. /**
  63. Box filter<br>
  64. Box, pulse, Fourier window, 1st order (constant) b-spline.<br><br>
  65. <b>Reference</b> : <br>
  66. Glassner A.S., Principles of digital image synthesis. Morgan Kaufmann Publishers, Inc, San Francisco, Vol. 2, 1995
  67. */
  68. class CBoxFilter : public CGenericFilter
  69. {
  70. public:
  71. /**
  72. Constructor<br>
  73. Default fixed width = 0.5
  74. */
  75. CBoxFilter() : CGenericFilter(0.5) {}
  76. virtual ~CBoxFilter() {}
  77. double Filter (double dVal) { return (fabs(dVal) <= m_dWidth ? 1.0 : 0.0); }
  78. };
  79. /** Bilinear filter
  80. */
  81. class CBilinearFilter : public CGenericFilter
  82. {
  83. public:
  84. CBilinearFilter () : CGenericFilter(1) {}
  85. virtual ~CBilinearFilter() {}
  86. double Filter (double dVal) {
  87. dVal = fabs(dVal);
  88. return (dVal < m_dWidth ? m_dWidth - dVal : 0.0);
  89. }
  90. };
  91. /**
  92. Mitchell & Netravali's two-param cubic filter<br>
  93. The parameters b and c can be used to adjust the properties of the cubic.
  94. They are sometimes referred to as "blurring" and "ringing" respectively.
  95. The default is b = 1/3 and c = 1/3, which were the values recommended by
  96. Mitchell and Netravali as yielding the most visually pleasing results in subjective tests of human beings.
  97. Larger values of b and c can produce interesting op-art effects--for example, try b = 0 and c = -5. <br><br>
  98. <b>Reference</b> : <br>
  99. Don P. Mitchell and Arun N. Netravali, Reconstruction filters in computer graphics.
  100. In John Dill, editor, Computer Graphics (SIGGRAPH '88 Proceedings), Vol. 22, No. 4, August 1988, pp. 221-228.
  101. */
  102. class CBicubicFilter : public CGenericFilter
  103. {
  104. protected:
  105. // data for parameterized Mitchell filter
  106. double p0, p2, p3;
  107. double q0, q1, q2, q3;
  108. public:
  109. /**
  110. Constructor<br>
  111. Default fixed width = 2
  112. @param b Filter parameter (default value is 1/3)
  113. @param c Filter parameter (default value is 1/3)
  114. */
  115. CBicubicFilter (double b = (1/(double)3), double c = (1/(double)3)) : CGenericFilter(2) {
  116. p0 = (6 - 2*b) / 6;
  117. p2 = (-18 + 12*b + 6*c) / 6;
  118. p3 = (12 - 9*b - 6*c) / 6;
  119. q0 = (8*b + 24*c) / 6;
  120. q1 = (-12*b - 48*c) / 6;
  121. q2 = (6*b + 30*c) / 6;
  122. q3 = (-b - 6*c) / 6;
  123. }
  124. virtual ~CBicubicFilter() {}
  125. double Filter(double dVal) {
  126. dVal = fabs(dVal);
  127. if(dVal < 1)
  128. return (p0 + dVal*dVal*(p2 + dVal*p3));
  129. if(dVal < 2)
  130. return (q0 + dVal*(q1 + dVal*(q2 + dVal*q3)));
  131. return 0;
  132. }
  133. };
  134. /**
  135. Catmull-Rom spline, Overhauser spline<br>
  136. When using CBicubicFilter filters, you have to set parameters b and c such that <br>
  137. b + 2 * c = 1<br>
  138. in order to use the numerically most accurate filter.<br>
  139. This gives for b = 0 the maximum value for c = 0.5, which is the Catmull-Rom
  140. spline and a good suggestion for sharpness.<br><br>
  141. <b>References</b> : <br>
  142. <ul>
  143. <li>Mitchell Don P., Netravali Arun N., Reconstruction filters in computer graphics.
  144. In John Dill, editor, Computer Graphics (SIGGRAPH '88 Proceedings), Vol. 22, No. 4, August 1988, pp. 221-228.
  145. <li>Keys R.G., Cubic Convolution Interpolation for Digital Image Processing.
  146. IEEE Trans. Acoustics, Speech, and Signal Processing, vol. 29, no. 6, pp. 1153-1160, Dec. 1981.
  147. </ul>
  148. */
  149. class CCatmullRomFilter : public CGenericFilter
  150. {
  151. public:
  152. /**
  153. Constructor<br>
  154. Default fixed width = 2
  155. */
  156. CCatmullRomFilter() : CGenericFilter(2) {}
  157. virtual ~CCatmullRomFilter() {}
  158. double Filter(double dVal) {
  159. if(dVal < -2) return 0;
  160. if(dVal < -1) return (0.5*(4 + dVal*(8 + dVal*(5 + dVal))));
  161. if(dVal < 0) return (0.5*(2 + dVal*dVal*(-5 - 3*dVal)));
  162. if(dVal < 1) return (0.5*(2 + dVal*dVal*(-5 + 3*dVal)));
  163. if(dVal < 2) return (0.5*(4 + dVal*(-8 + dVal*(5 - dVal))));
  164. return 0;
  165. }
  166. };
  167. /**
  168. Lanczos-windowed sinc filter<br>
  169. Lanczos3 filter is an alternative to CBicubicFilter with high values of c about 0.6 ... 0.75
  170. which produces quite strong sharpening. It usually offers better quality (fewer artifacts) and a sharp image.<br><br>
  171. */
  172. class CLanczos3Filter : public CGenericFilter
  173. {
  174. public:
  175. /**
  176. Constructor<br>
  177. Default fixed width = 3
  178. */
  179. CLanczos3Filter() : CGenericFilter(3) {}
  180. virtual ~CLanczos3Filter() {}
  181. double Filter(double dVal) {
  182. dVal = fabs(dVal);
  183. if(dVal < m_dWidth) {
  184. return (sinc(dVal) * sinc(dVal / m_dWidth));
  185. }
  186. return 0;
  187. }
  188. private:
  189. double sinc(double value) {
  190. if(value != 0) {
  191. value *= FILTER_PI;
  192. return (sin(value) / value);
  193. }
  194. return 1;
  195. }
  196. };
  197. /**
  198. 4th order (cubic) b-spline<br>
  199. */
  200. class CBSplineFilter : public CGenericFilter
  201. {
  202. public:
  203. /**
  204. Constructor<br>
  205. Default fixed width = 2
  206. */
  207. CBSplineFilter() : CGenericFilter(2) {}
  208. virtual ~CBSplineFilter() {}
  209. double Filter(double dVal) {
  210. dVal = fabs(dVal);
  211. if(dVal < 1) return (4 + dVal*dVal*(-6 + 3*dVal)) / 6;
  212. if(dVal < 2) {
  213. double t = 2 - dVal;
  214. return (t*t*t / 6);
  215. }
  216. return 0;
  217. }
  218. };
  219. // -----------------------------------------------------------------------------------
  220. // Window function library
  221. // -----------------------------------------------------------------------------------
  222. /**
  223. Blackman window
  224. */
  225. class CBlackmanFilter : public CGenericFilter
  226. {
  227. public:
  228. /**
  229. Constructor<br>
  230. Default width = 0.5
  231. */
  232. CBlackmanFilter (double dWidth = double(0.5)) : CGenericFilter(dWidth) {}
  233. virtual ~CBlackmanFilter() {}
  234. double Filter (double dVal) {
  235. if(fabs (dVal) > m_dWidth) {
  236. return 0;
  237. }
  238. double dN = 2 * m_dWidth + 1;
  239. dVal /= (dN - 1);
  240. return 0.42 + 0.5*cos(FILTER_2PI*dVal) + 0.08*cos(FILTER_4PI*dVal);
  241. }
  242. };
  243. #endif // _FILTERS_H_