• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
imagefilter.cpp
Go to the documentation of this file.
1//krazy:exclude=copyright (email of Maxim is missing)
2/*
3 This file is a part of the KDE project
4
5 Copyright © 2006 Zack Rusin <zack@kde.org>
6 Copyright © 2006-2007, 2008 Fredrik Höglund <fredrik@kde.org>
7
8 The stack blur algorithm was invented by Mario Klingemann <mario@quasimondo.com>
9
10 This implementation is based on the version in Anti-Grain Geometry Version 2.4,
11 Copyright © 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions
15 are met:
16
17 1. Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22
23 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include "imagefilter_p.h"
36
37#include <QPainter>
38#include <QImage>
39#include <QColor>
40#include <QDebug>
41
42#include <cmath>
43#include <string.h>
44
45using namespace KIO;
46
47static const quint32 stack_blur8_mul[255] =
48{
49 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,
50 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,
51 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,
52 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,
53 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,
54 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,
55 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,
56 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,
57 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,
58 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,
59 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,
60 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,
61 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,
62 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,
63 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,
64 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259
65};
66
67static const quint32 stack_blur8_shr[255] =
68{
69 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
70 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,
71 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
72 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
73 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
74 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
75 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
76 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
77 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
78 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
79 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
80 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
81 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
82 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
83 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
84 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24
85};
86
87inline static void blurHorizontal(QImage &image, unsigned int *stack, int div, int radius)
88{
89 int stackindex;
90 int stackstart;
91
92 quint32 * const pixels = reinterpret_cast<quint32 *>(image.bits());
93 quint32 pixel;
94
95 int w = image.width();
96 int h = image.height();
97 int wm = w - 1;
98
99 unsigned int mul_sum = stack_blur8_mul[radius];
100 unsigned int shr_sum = stack_blur8_shr[radius];
101
102 unsigned int sum, sum_in, sum_out;
103
104 for (int y = 0; y < h; y++)
105 {
106 sum = 0;
107 sum_in = 0;
108 sum_out = 0;
109
110 const int yw = y * w;
111 pixel = pixels[yw];
112 for (int i = 0; i <= radius; i++)
113 {
114 stack[i] = qAlpha(pixel);
115
116 sum += stack[i] * (i + 1);
117 sum_out += stack[i];
118 }
119
120 for (int i = 1; i <= radius; i++)
121 {
122 pixel = pixels[yw + qMin(i, wm)];
123
124 unsigned int *stackpix = &stack[i + radius];
125 *stackpix = qAlpha(pixel);
126
127 sum += *stackpix * (radius + 1 - i);
128 sum_in += *stackpix;
129 }
130
131 stackindex = radius;
132 for (int x = 0, i = yw; x < w; x++)
133 {
134 pixels[i++] = (((sum * mul_sum) >> shr_sum) << 24) & 0xff000000;
135
136 sum -= sum_out;
137
138 stackstart = stackindex + div - radius;
139 if (stackstart >= div)
140 stackstart -= div;
141
142 unsigned int *stackpix = &stack[stackstart];
143
144 sum_out -= *stackpix;
145
146 pixel = pixels[yw + qMin(x + radius + 1, wm)];
147
148 *stackpix = qAlpha(pixel);
149
150 sum_in += *stackpix;
151 sum += sum_in;
152
153 if (++stackindex >= div)
154 stackindex = 0;
155
156 stackpix = &stack[stackindex];
157
158 sum_out += *stackpix;
159 sum_in -= *stackpix;
160 } // for (x = 0, ...)
161 } // for (y = 0, ...)
162}
163
164inline static void blurVertical(QImage &image, unsigned int *stack, int div, int radius)
165{
166 int stackindex;
167 int stackstart;
168
169 quint32 * const pixels = reinterpret_cast<quint32 *>(image.bits());
170 quint32 pixel;
171
172 int w = image.width();
173 int h = image.height();
174 int hm = h - 1;
175
176 int mul_sum = stack_blur8_mul[radius];
177 int shr_sum = stack_blur8_shr[radius];
178
179 unsigned int sum, sum_in, sum_out;
180
181 for (int x = 0; x < w; x++)
182 {
183 sum = 0;
184 sum_in = 0;
185 sum_out = 0;
186
187 pixel = pixels[x];
188 for (int i = 0; i <= radius; i++)
189 {
190 stack[i] = qAlpha(pixel);
191
192 sum += stack[i] * (i + 1);
193 sum_out += stack[i];
194 }
195
196 for (int i = 1; i <= radius; i++)
197 {
198 pixel = pixels[qMin(i, hm) * w + x];
199
200 unsigned int *stackpix = &stack[i + radius];
201 *stackpix = qAlpha(pixel);
202
203 sum += *stackpix * (radius + 1 - i);
204 sum_in += *stackpix;
205 }
206
207 stackindex = radius;
208 for (int y = 0, i = x; y < h; y++, i += w)
209 {
210 pixels[i] = (((sum * mul_sum) >> shr_sum) << 24) & 0xff000000;
211
212 sum -= sum_out;
213
214 stackstart = stackindex + div - radius;
215 if (stackstart >= div)
216 stackstart -= div;
217
218 unsigned int *stackpix = &stack[stackstart];
219
220 sum_out -= *stackpix;
221
222 pixel = pixels[qMin(y + radius + 1, hm) * w + x];
223
224 *stackpix = qAlpha(pixel);
225
226 sum_in += *stackpix;
227 sum += sum_in;
228
229 if (++stackindex >= div)
230 stackindex = 0;
231
232 stackpix = &stack[stackindex];
233
234 sum_out += *stackpix;
235 sum_in -= *stackpix;
236 } // for (y = 0, ...)
237 } // for (x = 0, ...)
238}
239
240static void stackBlur(QImage &image, float radius)
241{
242 radius = qRound(radius);
243
244 int div = int(radius * 2) + 1;
245 unsigned int *stack = new unsigned int[div];
246
247 blurHorizontal(image, stack, div, radius);
248 blurVertical(image, stack, div, radius);
249
250 delete [] stack;
251}
252
253void ImageFilter::shadowBlur(QImage &image, float radius, const QColor &color)
254{
255 if (radius < 0)
256 return;
257
258 if (radius > 0)
259 stackBlur(image, radius);
260
261 // Correct the color and opacity of the shadow
262 QPainter p(&image);
263 p.setCompositionMode(QPainter::CompositionMode_SourceIn);
264 p.fillRect(image.rect(), color);
265}
266
267// kate: space-indent on; indent-width 4; replace-tabs on;
KIO::ImageFilter::shadowBlur
static void shadowBlur(QImage &image, float radius, const QColor &color)
Definition: imagefilter.cpp:253
blurHorizontal
static void blurHorizontal(QImage &image, unsigned int *stack, int div, int radius)
Definition: imagefilter.cpp:87
blurVertical
static void blurVertical(QImage &image, unsigned int *stack, int div, int radius)
Definition: imagefilter.cpp:164
stack_blur8_shr
static const quint32 stack_blur8_shr[255]
Definition: imagefilter.cpp:67
stackBlur
static void stackBlur(QImage &image, float radius)
Definition: imagefilter.cpp:240
stack_blur8_mul
static const quint32 stack_blur8_mul[255]
Definition: imagefilter.cpp:47
imagefilter_p.h
KIO
A namespace for KIO globals.
Definition: kbookmarkmenu.h:55
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal