~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to karbon/plugins/filtereffects/BlurEffect.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* This file is part of the KDE project
2
2
 * Copyright (c) 2009 Jan Hambrecht <jaham@gmx.net>
3
 
 * 
 
3
 *
4
4
 * This library is free software; you can redistribute it and/or
5
5
 * modify it under the terms of the GNU Lesser General Public
6
6
 * License as published by the Free Software Foundation; either
7
7
 * version 2 of the License, or (at your option) any later version.
8
 
 * 
 
8
 *
9
9
 * This library is distributed in the hope that it will be useful,
10
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
12
 * Library General Public License for more details.
13
 
 * 
 
13
 *
14
14
 * You should have received a copy of the GNU Lesser General Public License
15
15
 * along with this library; see the file COPYING.LIB.  If not, write to
16
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
19
 
20
20
#include "BlurEffect.h"
21
21
#include "KoFilterEffectRenderContext.h"
 
22
#include "KoFilterEffectLoadingContext.h"
22
23
#include "KoViewConverter.h"
23
24
#include "KoXmlWriter.h"
24
25
#include "KoXmlReader.h"
33
34
    if (radius < 1) {
34
35
        return;
35
36
    }
36
 
    
 
37
 
37
38
    QRgb *pix = (QRgb*)img.bits();
38
39
    int w   = img.width();
39
40
    int h   = img.height();
40
 
    int wm  = w-1;
41
 
    int hm  = h-1;
42
 
    int wh  = w*h;
43
 
    int div = radius+radius+1;
44
 
    
 
41
    int wm  = w - 1;
 
42
    int hm  = h - 1;
 
43
    int wh  = w * h;
 
44
    int div = radius + radius + 1;
 
45
 
45
46
    int *r = new int[wh];
46
47
    int *g = new int[wh];
47
48
    int *b = new int[wh];
48
49
    int *a = new int[wh];
49
50
    int rsum, gsum, bsum, asum, x, y, i, yp, yi, yw;
50
51
    QRgb p;
51
 
    int *vmin = new int[qMax(w,h)];
52
 
    
53
 
    int divsum = (div+1)>>1;
 
52
    int *vmin = new int[qMax(w, h)];
 
53
 
 
54
    int divsum = (div + 1) >> 1;
54
55
    divsum *= divsum;
55
56
    int *dv = new int[256*divsum];
56
 
    for (i=0; i < 256*divsum; ++i) {
57
 
        dv[i] = (i/divsum);
 
57
    for (i = 0; i < 256*divsum; ++i) {
 
58
        dv[i] = (i / divsum);
58
59
    }
59
 
    
 
60
 
60
61
    yw = yi = 0;
61
 
    
 
62
 
62
63
    int **stack = new int*[div];
63
 
    for(int i = 0; i < div; ++i) {
 
64
    for (int i = 0; i < div; ++i) {
64
65
        stack[i] = new int[4];
65
66
    }
66
 
    
67
 
    
 
67
 
 
68
 
68
69
    int stackpointer;
69
70
    int stackstart;
70
71
    int *sir;
71
72
    int rbs;
72
 
    int r1 = radius+1;
 
73
    int r1 = radius + 1;
73
74
    int routsum, goutsum, boutsum, aoutsum;
74
75
    int rinsum, ginsum, binsum, ainsum;
75
 
    
76
 
    for (y = 0; y < h; ++y){
 
76
 
 
77
    for (y = 0; y < h; ++y) {
77
78
        rinsum = ginsum = binsum = ainsum
78
 
        = routsum = goutsum = boutsum = aoutsum
79
 
        = rsum = gsum = bsum = asum = 0;
80
 
        for(i =- radius; i <= radius; ++i) {
81
 
            p = pix[yi+qMin(wm,qMax(i,0))];
 
79
                                   = routsum = goutsum = boutsum = aoutsum
 
80
                                                                   = rsum = gsum = bsum = asum = 0;
 
81
        for (i = - radius; i <= radius; ++i) {
 
82
            p = pix[yi+qMin(wm, qMax(i, 0))];
82
83
            sir = stack[i+radius];
83
84
            sir[0] = qRed(p);
84
85
            sir[1] = qGreen(p);
85
86
            sir[2] = qBlue(p);
86
87
            sir[3] = qAlpha(p);
87
 
            
88
 
            rbs = r1-abs(i);
89
 
            rsum += sir[0]*rbs;
90
 
            gsum += sir[1]*rbs;
91
 
            bsum += sir[2]*rbs;
92
 
            asum += sir[3]*rbs;
93
 
            
94
 
            if (i > 0){
 
88
 
 
89
            rbs = r1 - abs(i);
 
90
            rsum += sir[0] * rbs;
 
91
            gsum += sir[1] * rbs;
 
92
            bsum += sir[2] * rbs;
 
93
            asum += sir[3] * rbs;
 
94
 
 
95
            if (i > 0) {
95
96
                rinsum += sir[0];
96
97
                ginsum += sir[1];
97
98
                binsum += sir[2];
104
105
            }
105
106
        }
106
107
        stackpointer = radius;
107
 
        
108
 
        for (x=0; x < w; ++x) {
109
 
            
 
108
 
 
109
        for (x = 0; x < w; ++x) {
 
110
 
110
111
            r[yi] = dv[rsum];
111
112
            g[yi] = dv[gsum];
112
113
            b[yi] = dv[bsum];
113
114
            a[yi] = dv[asum];
114
 
            
 
115
 
115
116
            rsum -= routsum;
116
117
            gsum -= goutsum;
117
118
            bsum -= boutsum;
118
119
            asum -= aoutsum;
119
 
            
120
 
            stackstart = stackpointer-radius+div;
 
120
 
 
121
            stackstart = stackpointer - radius + div;
121
122
            sir = stack[stackstart%div];
122
 
            
 
123
 
123
124
            routsum -= sir[0];
124
125
            goutsum -= sir[1];
125
126
            boutsum -= sir[2];
126
127
            aoutsum -= sir[3];
127
 
            
 
128
 
128
129
            if (y == 0) {
129
 
                vmin[x] = qMin(x+radius+1,wm);
 
130
                vmin[x] = qMin(x + radius + 1, wm);
130
131
            }
131
132
            p = pix[yw+vmin[x]];
132
 
            
 
133
 
133
134
            sir[0] = qRed(p);
134
135
            sir[1] = qGreen(p);
135
136
            sir[2] = qBlue(p);
136
137
            sir[3] = qAlpha(p);
137
 
            
 
138
 
138
139
            rinsum += sir[0];
139
140
            ginsum += sir[1];
140
141
            binsum += sir[2];
141
142
            ainsum += sir[3];
142
 
            
 
143
 
143
144
            rsum += rinsum;
144
145
            gsum += ginsum;
145
146
            bsum += binsum;
146
147
            asum += ainsum;
147
 
            
148
 
            stackpointer = (stackpointer+1)%div;
 
148
 
 
149
            stackpointer = (stackpointer + 1) % div;
149
150
            sir = stack[(stackpointer)%div];
150
 
            
 
151
 
151
152
            routsum += sir[0];
152
153
            goutsum += sir[1];
153
154
            boutsum += sir[2];
154
155
            aoutsum += sir[3];
155
 
            
 
156
 
156
157
            rinsum -= sir[0];
157
158
            ginsum -= sir[1];
158
159
            binsum -= sir[2];
159
160
            ainsum -= sir[3];
160
 
            
 
161
 
161
162
            ++yi;
162
163
        }
163
164
        yw += w;
164
165
    }
165
 
    for (x=0; x < w; ++x){
166
 
        rinsum = ginsum = binsum = ainsum 
167
 
        = routsum = goutsum = boutsum = aoutsum 
168
 
        = rsum = gsum = bsum = asum = 0;
169
 
        
170
 
        yp =- radius * w;
171
 
        
172
 
        for(i=-radius; i <= radius; ++i) {
173
 
            yi=qMax(0,yp)+x;
174
 
            
 
166
    for (x = 0; x < w; ++x) {
 
167
        rinsum = ginsum = binsum = ainsum
 
168
                                   = routsum = goutsum = boutsum = aoutsum
 
169
                                                                   = rsum = gsum = bsum = asum = 0;
 
170
 
 
171
        yp = - radius * w;
 
172
 
 
173
        for (i = -radius; i <= radius; ++i) {
 
174
            yi = qMax(0, yp) + x;
 
175
 
175
176
            sir = stack[i+radius];
176
 
            
 
177
 
177
178
            sir[0] = r[yi];
178
179
            sir[1] = g[yi];
179
180
            sir[2] = b[yi];
180
181
            sir[3] = a[yi];
181
 
            
182
 
            rbs = r1-abs(i);
183
 
            
184
 
            rsum += r[yi]*rbs;
185
 
            gsum += g[yi]*rbs;
186
 
            bsum += b[yi]*rbs;
187
 
            asum += a[yi]*rbs;
188
 
            
 
182
 
 
183
            rbs = r1 - abs(i);
 
184
 
 
185
            rsum += r[yi] * rbs;
 
186
            gsum += g[yi] * rbs;
 
187
            bsum += b[yi] * rbs;
 
188
            asum += a[yi] * rbs;
 
189
 
189
190
            if (i > 0) {
190
191
                rinsum += sir[0];
191
192
                ginsum += sir[1];
197
198
                boutsum += sir[2];
198
199
                aoutsum += sir[3];
199
200
            }
200
 
            
201
 
            if (i < hm){
 
201
 
 
202
            if (i < hm) {
202
203
                yp += w;
203
204
            }
204
205
        }
205
 
        
 
206
 
206
207
        yi = x;
207
208
        stackpointer = radius;
208
 
        
209
 
        for (y=0; y < h; ++y){
 
209
 
 
210
        for (y = 0; y < h; ++y) {
210
211
            pix[yi] = qRgba(dv[rsum], dv[gsum], dv[bsum], dv[asum]);
211
 
            
 
212
 
212
213
            rsum -= routsum;
213
214
            gsum -= goutsum;
214
215
            bsum -= boutsum;
215
216
            asum -= aoutsum;
216
 
            
217
 
            stackstart = stackpointer-radius+div;
 
217
 
 
218
            stackstart = stackpointer - radius + div;
218
219
            sir = stack[stackstart%div];
219
 
            
 
220
 
220
221
            routsum -= sir[0];
221
222
            goutsum -= sir[1];
222
223
            boutsum -= sir[2];
223
224
            aoutsum -= sir[3];
224
 
            
225
 
            if (x==0){
226
 
                vmin[y] = qMin(y+r1,hm)*w;
 
225
 
 
226
            if (x == 0) {
 
227
                vmin[y] = qMin(y + r1, hm) * w;
227
228
            }
228
 
            p = x+vmin[y];
229
 
            
 
229
            p = x + vmin[y];
 
230
 
230
231
            sir[0] = r[p];
231
232
            sir[1] = g[p];
232
233
            sir[2] = b[p];
233
234
            sir[3] = a[p];
234
 
            
 
235
 
235
236
            rinsum += sir[0];
236
237
            ginsum += sir[1];
237
238
            binsum += sir[2];
238
239
            ainsum += sir[3];
239
 
            
 
240
 
240
241
            rsum += rinsum;
241
242
            gsum += ginsum;
242
243
            bsum += binsum;
243
244
            asum += ainsum;
244
 
            
245
 
            stackpointer = (stackpointer+1)%div;
 
245
 
 
246
            stackpointer = (stackpointer + 1) % div;
246
247
            sir = stack[stackpointer];
247
 
            
 
248
 
248
249
            routsum += sir[0];
249
250
            goutsum += sir[1];
250
251
            boutsum += sir[2];
251
252
            aoutsum += sir[3];
252
 
            
 
253
 
253
254
            rinsum -= sir[0];
254
255
            ginsum -= sir[1];
255
256
            binsum -= sir[2];
256
257
            ainsum -= sir[3];
257
 
            
 
258
 
258
259
            yi += w;
259
260
        }
260
261
    }
264
265
    delete [] a;
265
266
    delete [] vmin;
266
267
    delete [] dv;
267
 
    
268
 
    for(int i = 0; i < div; ++i) {
 
268
 
 
269
    for (int i = 0; i < div; ++i) {
269
270
        delete [] stack[i];
270
271
    }
271
272
    delete [] stack;
272
273
}
273
274
 
274
275
BlurEffect::BlurEffect()
275
 
: KoFilterEffect(BlurEffectId, i18n( "Gaussian blur" ))
276
 
, m_deviation(0,0)
 
276
        : KoFilterEffect(BlurEffectId, i18n("Gaussian blur"))
 
277
        , m_deviation(0, 0)
277
278
{
278
279
}
279
280
 
292
293
{
293
294
    if (m_deviation.x() == 0.0 || m_deviation.y() == 0.0)
294
295
        return image;
295
 
    
 
296
 
296
297
    // TODO: take filter region into account
297
298
    // TODO: blur with different kernels in x and y
298
299
    // convert from bounding box coordinates
299
 
    QPointF dev = context.coordinateTransformation().map(m_deviation);
 
300
    QPointF dev = context.toUserSpace(m_deviation);
300
301
    // transform to view coordinates
301
302
    dev = context.viewConverter()->documentToView(dev);
302
 
    
 
303
 
303
304
    QImage result = image;
304
305
    fastbluralpha(result, dev.x());
305
 
    
 
306
 
306
307
    return result;
307
308
}
308
309
 
309
 
bool BlurEffect::load(const KoXmlElement &element, const QMatrix &matrix)
 
310
bool BlurEffect::load(const KoXmlElement &element, const KoFilterEffectLoadingContext &context)
310
311
{
311
312
    if (element.tagName() != id())
312
313
        return false;
313
314
 
314
315
    QString deviationStr = element.attribute("stdDeviation");
315
 
    QStringList params = deviationStr.trimmed().split( ',' );
316
 
    
317
 
    switch(params.count()) {
 
316
    QStringList params = deviationStr.replace(',', ' ').simplified().split(' ');
 
317
 
 
318
    switch (params.count()) {
318
319
    case 1:
319
320
        m_deviation.rx() = params[0].toDouble();
320
321
        m_deviation.ry() = m_deviation.x();
326
327
    default:
327
328
        return false;
328
329
    }
329
 
      
330
 
    m_deviation = matrix.map(m_deviation);
331
 
    
 
330
 
 
331
    m_deviation = context.convertFilterPrimitiveUnits(m_deviation);
 
332
 
332
333
    return true;
333
334
}
334
335
 
335
336
void BlurEffect::save(KoXmlWriter &writer)
336
337
{
337
338
    writer.startElement(BlurEffectId);
338
 
    
 
339
 
339
340
    saveCommonAttributes(writer);
340
 
    
 
341
 
341
342
    if (m_deviation.x() != m_deviation.y()) {
342
343
        writer.addAttribute("stdDeviation", QString("%1, %2").arg(m_deviation.x()).arg(m_deviation.y()));
343
344
    } else {
344
345
        writer.addAttribute("stdDeviation", m_deviation.x());
345
346
    }
346
 
    
 
347
 
347
348
    writer.endElement();
348
349
}