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

KIO

  • sources
  • kde-4.14
  • kdelibs
  • 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 
45 using namespace KIO;
46 
47 static 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 
67 static 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 
87 inline 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 
164 inline 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 
240 static 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 
253 void 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;
QPainter::fillRect
void fillRect(const QRectF &rectangle, const QBrush &brush)
QPainter::setCompositionMode
void setCompositionMode(CompositionMode mode)
blurVertical
static void blurVertical(QImage &image, unsigned int *stack, int div, int radius)
Definition: imagefilter.cpp:164
quint32
stackBlur
static void stackBlur(QImage &image, float radius)
Definition: imagefilter.cpp:240
stack_blur8_shr
static const quint32 stack_blur8_shr[255]
Definition: imagefilter.cpp:67
blurHorizontal
static void blurHorizontal(QImage &image, unsigned int *stack, int div, int radius)
Definition: imagefilter.cpp:87
QImage::width
int width() const
QPainter
QImage::rect
QRect rect() const
stack_blur8_mul
static const quint32 stack_blur8_mul[255]
Definition: imagefilter.cpp:47
QColor
imagefilter_p.h
QImage
QImage::bits
uchar * bits()
QImage::height
int height() const
KIO::ImageFilter::shadowBlur
static void shadowBlur(QImage &image, float radius, const QColor &color)
Definition: imagefilter.cpp:253
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:52 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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