KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kis_filter_strategy.cc 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
  3. * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. #include <kdebug.h>
  20. #include <tdelocale.h>
  21. #include "kis_debug_areas.h"
  22. #include "kis_filter_strategy.h"
  23. #include <math.h>
  24. double KisHermiteFilterStrategy::valueAt(double t) const {
  25. /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
  26. if(t < 0.0) t = -t;
  27. if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
  28. return(0.0);
  29. }
  30. TQ_UINT32 KisHermiteFilterStrategy::intValueAt(TQ_INT32 t) const {
  31. /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
  32. if(t < 0) t = -t;
  33. if(t < 256)
  34. {
  35. t =(2 * t - 3*256) * t * t +(256<<16);
  36. //go from .24 fixed point to .8 fixedpoint (hack only works with positve numbers, which it is)
  37. t = (t + 0x8000) >> 16;
  38. // go from .8 fixed point to 8bitscale. ie t = (t*255)/256;
  39. if(t >= 128)
  40. return t - 1;
  41. return t;
  42. }
  43. return(0);
  44. }
  45. double KisCubicFilterStrategy::valueAt(double x) const {
  46. if (x < -2.0)
  47. return(0.0);
  48. if (x < -1.0)
  49. return((2.0+x)*(2.0+x)*(2.0+x)/6.0);
  50. if (x < 0.0)
  51. return((4.0+x*x*(-6.0-3.0*x))/6.0);
  52. if (x < 1.0)
  53. return((4.0+x*x*(-6.0+3.0*x))/6.0);
  54. if (x < 2.0)
  55. return((2.0-x)*(2.0-x)*(2.0-x)/6.0);
  56. return(0.0);
  57. }
  58. TQ_UINT32 KisCubicFilterStrategy::intValueAt(TQ_INT32 x) const {
  59. if (x < 2)
  60. return 0;
  61. if (x < -1)
  62. return (2 + x) * (2 + x) * ( 2 + x) / 6;
  63. if ( x < 0)
  64. return (4 + x * x * ( -6 - 3 * x)) / 6;
  65. if (x < 1)
  66. return (4 + x * x * ( -6 + 3 * x)) / 6;
  67. if (x < 2)
  68. return (2 - x) * ( 2 - x) * (2 - x) / 6;
  69. return 0;
  70. }
  71. double KisBoxFilterStrategy::valueAt(double t) const {
  72. if((t > -0.5) && (t <= 0.5)) return(1.0);
  73. return(0.0);
  74. }
  75. TQ_UINT32 KisBoxFilterStrategy::intValueAt(TQ_INT32 t) const {
  76. /* f(t) = 1, -0.5 < t <= 0.5 */
  77. if((t > -128) && (t <= 128))
  78. return 255;
  79. return 0;
  80. }
  81. double KisTriangleFilterStrategy::valueAt(double t) const {
  82. if(t < 0.0) t = -t;
  83. if(t < 1.0) return(1.0 - t);
  84. return(0.0);
  85. }
  86. TQ_UINT32 KisTriangleFilterStrategy::intValueAt(TQ_INT32 t) const {
  87. /* f(t) = |t|, -1 <= t <= 1 */
  88. if(t < 0) t = -t;
  89. if(t < 256)
  90. {
  91. // calc 256-1 but also go from .8 fixed point to 8bitscale. ie t = (t*255)/256; ie: if(t>=128) return t-1;
  92. if(t>=128) return 256 - t;
  93. return 255 - t;
  94. }
  95. return(0);
  96. }
  97. double KisBellFilterStrategy::valueAt(double t) const {
  98. if(t < 0) t = -t;
  99. if(t < .5) return(.75 - (t * t));
  100. if(t < 1.5) {
  101. t = (t - 1.5);
  102. return(.5 * (t * t));
  103. }
  104. return(0.0);
  105. }
  106. double KisBSplineFilterStrategy::valueAt(double t) const {
  107. double tt;
  108. if(t < 0) t = -t;
  109. if(t < 1) {
  110. tt = t * t;
  111. return((.5 * tt * t) - tt + (2.0 / 3.0));
  112. } else if(t < 2) {
  113. t = 2 - t;
  114. return((1.0 / 6.0) * (t * t * t));
  115. }
  116. return(0.0);
  117. }
  118. double KisLanczos3FilterStrategy::valueAt(double t) const {
  119. if(t < 0) t = -t;
  120. if(t < 3.0) return(sinc(t) * sinc(t/3.0));
  121. return(0.0);
  122. }
  123. double KisLanczos3FilterStrategy::sinc(double x) const {
  124. const double pi=3.1415926535897932385;
  125. x *= pi;
  126. if(x != 0) return(sin(x) / x);
  127. return(1.0);
  128. }
  129. double KisMitchellFilterStrategy::valueAt(double t) const {
  130. const double B=1.0/3.0;
  131. const double C=1.0/3.0;
  132. double tt;
  133. tt = t * t;
  134. if(t < 0) t = -t;
  135. if(t < 1.0) {
  136. t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt)) + ((-18.0 + 12.0 * B + 6.0 * C) * tt) + (6.0 - 2 * B));
  137. return(t / 6.0);
  138. } else if(t < 2.0) {
  139. t = (((-1.0 * B - 6.0 * C) * (t * tt)) + ((6.0 * B + 30.0 * C) * tt) + ((-12.0 * B - 48.0 * C) * t) + (8.0 * B + 24 * C));
  140. return(t / 6.0);
  141. }
  142. return(0.0);
  143. }
  144. KisFilterStrategyRegistry *KisFilterStrategyRegistry::m_singleton = 0;
  145. KisFilterStrategyRegistry::KisFilterStrategyRegistry()
  146. {
  147. Q_ASSERT(KisFilterStrategyRegistry::m_singleton == 0);
  148. KisFilterStrategyRegistry::m_singleton = this;
  149. }
  150. KisFilterStrategyRegistry::~KisFilterStrategyRegistry()
  151. {
  152. }
  153. KisFilterStrategyRegistry* KisFilterStrategyRegistry::instance()
  154. {
  155. if(KisFilterStrategyRegistry::m_singleton == 0)
  156. {
  157. KisFilterStrategyRegistry::m_singleton = new KisFilterStrategyRegistry();
  158. TQ_CHECK_PTR(KisFilterStrategyRegistry::m_singleton);
  159. m_singleton->add(new KisHermiteFilterStrategy);
  160. m_singleton->add(new KisBoxFilterStrategy);
  161. m_singleton->add(new KisTriangleFilterStrategy);
  162. m_singleton->add(new KisBellFilterStrategy);
  163. m_singleton->add(new KisBSplineFilterStrategy);
  164. // m_singleton->add(new KisLanczos3FilterStrategy);
  165. m_singleton->add(new KisMitchellFilterStrategy);
  166. // m_singleton->add(new KisCubicFilterStrategy);
  167. }
  168. return KisFilterStrategyRegistry::m_singleton;
  169. }