krita

kis_filter_strategy.cc

00001 /*
00002  *  Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
00003  *  Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  */
00019 #include <kdebug.h>
00020 #include <klocale.h>
00021 #include "kis_debug_areas.h"
00022 #include "kis_filter_strategy.h"
00023 #include <math.h>
00024 
00025 double KisHermiteFilterStrategy::valueAt(double t) const {
00026         /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
00027         if(t < 0.0) t = -t;
00028         if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
00029         return(0.0);
00030 }
00031 
00032 Q_UINT32 KisHermiteFilterStrategy::intValueAt(Q_INT32 t) const {
00033         /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
00034         if(t < 0) t = -t;
00035         if(t < 256)
00036     {
00037         t =(2 * t - 3*256) * t * t +(256<<16);
00038 
00039         //go from .24 fixed point to .8 fixedpoint (hack only works with positve numbers, which it is)
00040         t = (t + 0x8000) >> 16;
00041 
00042         // go from .8 fixed point to 8bitscale. ie t = (t*255)/256;
00043         if(t >= 128)
00044             return t - 1;
00045         return t;
00046     }
00047         return(0);
00048 }
00049 
00050 double KisCubicFilterStrategy::valueAt(double x) const {
00051     if (x < -2.0)
00052         return(0.0);
00053     if (x < -1.0)
00054         return((2.0+x)*(2.0+x)*(2.0+x)/6.0);
00055     if (x < 0.0)
00056         return((4.0+x*x*(-6.0-3.0*x))/6.0);
00057     if (x < 1.0)
00058         return((4.0+x*x*(-6.0+3.0*x))/6.0);
00059     if (x < 2.0)
00060         return((2.0-x)*(2.0-x)*(2.0-x)/6.0);
00061     return(0.0);
00062 }
00063 
00064 Q_UINT32 KisCubicFilterStrategy::intValueAt(Q_INT32 x) const {
00065     if (x < 2)
00066         return 0;
00067     if (x < -1)
00068         return (2 + x) * (2 + x) * ( 2 + x) / 6;
00069     if ( x < 0)
00070         return (4 + x * x * ( -6 - 3 * x)) / 6;
00071     if (x < 1)
00072         return (4 + x * x * ( -6 + 3 * x)) / 6;
00073     if (x < 2)
00074         return (2 - x) * ( 2 - x) * (2 - x) / 6;    
00075      return 0;   
00076 }
00077 
00078 double KisBoxFilterStrategy::valueAt(double t) const {
00079         if((t > -0.5) && (t <= 0.5)) return(1.0);
00080         return(0.0);
00081 }
00082 
00083 Q_UINT32 KisBoxFilterStrategy::intValueAt(Q_INT32 t) const {
00084         /* f(t) = 1, -0.5 < t <= 0.5 */
00085     if((t > -128) && (t <= 128))
00086         return 255;
00087     return 0;
00088 }
00089 
00090 double KisTriangleFilterStrategy::valueAt(double t) const {
00091         if(t < 0.0) t = -t;
00092         if(t < 1.0) return(1.0 - t);
00093         return(0.0);
00094 }
00095 
00096 Q_UINT32 KisTriangleFilterStrategy::intValueAt(Q_INT32 t) const {
00097         /* f(t) = |t|, -1 <= t <= 1 */
00098         if(t < 0) t = -t;
00099         if(t < 256)
00100     {
00101          // calc 256-1 but also go from .8 fixed point to 8bitscale. ie t = (t*255)/256; ie: if(t>=128) return t-1;
00102         if(t>=128) return 256 - t;
00103         return 255 - t;
00104     }
00105         return(0);
00106 }
00107 
00108 
00109 double KisBellFilterStrategy::valueAt(double t) const {
00110         if(t < 0) t = -t;
00111         if(t < .5) return(.75 - (t * t));
00112         if(t < 1.5) {
00113                 t = (t - 1.5);
00114                 return(.5 * (t * t));
00115         }
00116         return(0.0);
00117 }
00118 
00119 double KisBSplineFilterStrategy::valueAt(double t) const {
00120         double tt;
00121 
00122         if(t < 0) t = -t;
00123         if(t < 1) {
00124                 tt = t * t;
00125                 return((.5 * tt * t) - tt + (2.0 / 3.0));
00126         } else if(t < 2) {
00127                 t = 2 - t;
00128                 return((1.0 / 6.0) * (t * t * t));
00129         }
00130         return(0.0);
00131 }
00132 
00133 double KisLanczos3FilterStrategy::valueAt(double t) const {
00134         if(t < 0) t = -t;
00135         if(t < 3.0) return(sinc(t) * sinc(t/3.0));
00136         return(0.0);
00137 }
00138 
00139 double KisLanczos3FilterStrategy::sinc(double x) const {
00140         const double pi=3.1415926535897932385;
00141         x *= pi;
00142         if(x != 0) return(sin(x) / x);
00143         return(1.0);
00144 }
00145 
00146 double KisMitchellFilterStrategy::valueAt(double t) const {
00147         const double B=1.0/3.0;
00148         const double C=1.0/3.0;
00149         double tt;
00150 
00151         tt = t * t;
00152         if(t < 0) t = -t;
00153         if(t < 1.0) {
00154                 t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt)) + ((-18.0 + 12.0 * B + 6.0 * C) * tt) + (6.0 - 2 * B));
00155                 return(t / 6.0);
00156         } else if(t < 2.0) {
00157                 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));
00158                 return(t / 6.0);
00159                 }
00160         return(0.0);
00161 }
00162 
00163 KisFilterStrategyRegistry *KisFilterStrategyRegistry::m_singleton = 0;
00164 
00165 KisFilterStrategyRegistry::KisFilterStrategyRegistry()
00166 {
00167     Q_ASSERT(KisFilterStrategyRegistry::m_singleton == 0);
00168     KisFilterStrategyRegistry::m_singleton = this;
00169 }
00170 
00171 KisFilterStrategyRegistry::~KisFilterStrategyRegistry()
00172 {
00173 }
00174 
00175 KisFilterStrategyRegistry* KisFilterStrategyRegistry::instance()
00176 {
00177     if(KisFilterStrategyRegistry::m_singleton == 0)
00178     {
00179         KisFilterStrategyRegistry::m_singleton = new KisFilterStrategyRegistry();
00180         Q_CHECK_PTR(KisFilterStrategyRegistry::m_singleton);
00181         m_singleton->add(new KisHermiteFilterStrategy);
00182         m_singleton->add(new KisBoxFilterStrategy);
00183         m_singleton->add(new KisTriangleFilterStrategy);
00184         m_singleton->add(new KisBellFilterStrategy);
00185         m_singleton->add(new KisBSplineFilterStrategy);
00186 //         m_singleton->add(new KisLanczos3FilterStrategy);
00187         m_singleton->add(new KisMitchellFilterStrategy);
00188 //         m_singleton->add(new KisCubicFilterStrategy);
00189     }
00190     return KisFilterStrategyRegistry::m_singleton;
00191 }
00192 
KDE Home | KDE Accessibility Home | Description of Access Keys