1 /****************************************************************************
2 **
3 ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of a Qt Solutions component.
8 **
9 ** Commercial Usage
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Solutions Commercial License Agreement provided
12 ** with the Software or, alternatively, in accordance with the terms
13 ** contained in a written agreement between you and Nokia.
14 **
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file.  Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file.  Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** Please note Third Party Software included with Qt Solutions may impose
37 ** additional restrictions and it is the user's responsibility to ensure
38 ** that they have met the licensing requirements of the GPL, LGPL, or Qt
39 ** Solutions Commercial license and the relevant license of the Third
40 ** Party Software they are using.
41 **
42 ** If you are unsure which license is appropriate for your use, please
43 ** contact Nokia at qt-info@nokia.com.
44 **
45 ****************************************************************************/
46 
47 #ifndef GAUSSBLURFILTER_H
48 #define GAUSSBLURFILTER_H
49 
50 #include "convolutionfilter.h"
51 #include <cmath>
52 
53 #ifndef M_PI
54 #define M_PI 3.1415926535897932384626433832795
55 #endif
56 
57 class GaussBlurFilter : public ConvolutionFilter
58 {
59     public:
GaussBlurFilter()60         GaussBlurFilter() : ConvolutionFilter()
61         {
62             m_radius = 4.0;
63         }
64 
65         ////
66         // INHERITED FROM ConvolutionFilter
67         ////
68         QVariant option(int option) const override;
69 
setOption(int option,const QVariant & value)70         bool setOption(int option, const QVariant &value) override
71         {
72             bool ok = true;
73             switch (option) {
74                 case QtImageFilter::Radius:
75                 {
76                     double radius = value.toDouble(&ok);
77                     if (ok) m_radius = radius;
78                 }
79                 break;
80 
81                 default:
82                     ok = ConvolutionFilter::setOption(option, value);
83                 break;
84             }
85             return ok;
86         }
87 
supportsOption(int option)88         bool supportsOption(int option) const override
89         {
90             if (option == QtImageFilter::Radius) return true;
91             return ConvolutionFilter::supportsOption(option);
92         }
93 
94 	QImage apply(const QImage &image, const QRect& clipRect ) const override;
95 
name()96 	QString name() const override { return QLatin1String("GaussBlur"); }
description()97         QString description() const override { return QObject::tr("A gaussian blur filter", "GaussBlurFilter"); }
98 
99     private:
100         qreal m_radius;
101 };
102 
103 
Gauss2DFunction(int x,int y,qreal deviance)104 static qreal Gauss2DFunction(int x, int y, qreal deviance)
105 {
106     /**
107     * A 2-D gaussian distribution has the shape:
108     *
109     *               1         -(x*x + y*y)/(2*dev*dev)
110     * G(x,y) = ---------- * e^
111     *          2*PI*dev^2
112     *
113     * see http://www.cee.hw.ac.uk/hipr/html/gsmooth.html for a more readable version
114     */
115     return exp(-(x*x + y*y)/(2*deviance*deviance))/(2*M_PI*deviance*deviance);
116 }
117 
option(int option)118 QVariant GaussBlurFilter::option(int option) const
119 {
120     if (option == QtImageFilter::Radius) return true;
121     return ConvolutionFilter::option(option);
122 }
123 
apply(const QImage & image,const QRect & clipRect)124 QImage GaussBlurFilter::apply(const QImage &image, const QRect& clipRect ) const
125 {
126     if (m_radius > 0.0) {
127         int uRadius = (int)ceil(m_radius);
128 
129         double deviance = sqrt(-m_radius*m_radius/(2*log(1/255.0)));
130         QtMatrix<double> matLeft(2 * uRadius + 1, 1);
131 
132         for (int x = -uRadius; x <=uRadius; x++) {
133             matLeft.setData(uRadius + x, 0, Gauss2DFunction(x, 0, deviance));
134         }
135         double scalar = matLeft.at(uRadius, 0);
136         matLeft*=(255.0/scalar);
137         QtMatrix<double> matRight = matLeft.transposed();
138 
139         QtConvolutionKernelMatrix integerMatrixLeft = convertMatrixBasetype<int,double>(matLeft);
140         QtConvolutionKernelMatrix integerMatrixRight = convertMatrixBasetype<int,double>(matRight);
141 
142         auto localThis = const_cast<GaussBlurFilter*>(this);
143         localThis->addKernel(integerMatrixLeft, m_channels, m_borderPolicy);
144         localThis->addKernel(integerMatrixRight, m_channels, m_borderPolicy);
145     }
146     return ConvolutionFilter::apply(image, clipRect);
147 }
148 
149 #endif //GAUSSBLURFILTER_H
150 
151