mirror-kde-plasma-desktop/applets/taskmanager/plugin/blur.cpp
Aleix Pol 88ae0b60b8 Initial import from the monolithic kde-workspace.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
techbase wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:

http://community.kde.org/Frameworks/GitOldHistory

If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.

Branched from the monolithic repo kde-workspace, frameworks  branch, at commit
049113e719dd2fc4446d054fa1a3aada330094f0
2014-03-31 04:23:39 +02:00

154 lines
4.1 KiB
C++

#ifndef BLUR_CPP
#define BLUR_CPP
/*
* Copyright 2007 Jani Huhtanen <jani.huhtanen@tut.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cmath>
// Exponential blur, Jani Huhtanen, 2006
//
template<int aprec, int zprec>
static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha);
template<int aprec,int zprec>
static inline void blurrow(QImage &im, int line, int alpha);
template<int aprec, int zprec>
static inline void blurcol(QImage &im, int col, int alpha);
/*
* expblur(QImage &img, int radius)
*
* In-place blur of image 'img' with kernel
* of approximate radius 'radius'.
*
* Blurs with two sided exponential impulse
* response.
*
* aprec = precision of alpha parameter
* in fixed-point format 0.aprec
*
* zprec = precision of state parameters
* zR,zG,zB and zA in fp format 8.zprec
*/
template<int aprec,int zprec>
void expblur(QImage &img, int radius)
{
if (radius < 1) {
return;
}
img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
/* Calculate the alpha such that 90% of
the kernel is within the radius.
(Kernel extends to infinity)
*/
int alpha = (int)((1 << aprec) * (1.0f - std::exp(-2.3f / (radius + 1.f))));
int height = img.height();
int width = img.width();
for (int row=0; row<height; row++) {
blurrow<aprec,zprec>(img, row, alpha);
}
for (int col=0; col<width; col++) {
blurcol<aprec,zprec>(img, col, alpha);
}
return;
}
template<int aprec, int zprec>
static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
{
int R, G, B, A;
R = *bptr;
G = *(bptr + 1);
B = *(bptr + 2);
A = *(bptr + 3);
zR += (alpha * ((R << zprec) - zR)) >> aprec;
zG += (alpha * ((G << zprec) - zG)) >> aprec;
zB += (alpha * ((B << zprec) - zB)) >> aprec;
zA += (alpha * ((A << zprec) - zA)) >> aprec;
*bptr = zR >> zprec;
*(bptr+1) = zG >> zprec;
*(bptr+2) = zB >> zprec;
*(bptr+3) = zA >> zprec;
}
template<int aprec,int zprec>
static inline void blurrow(QImage &im, int line, int alpha)
{
int zR, zG, zB, zA;
QRgb *ptr = (QRgb *)im.scanLine(line);
int width = im.width();
zR = *((unsigned char *)ptr ) << zprec;
zG = *((unsigned char *)ptr + 1) << zprec;
zB = *((unsigned char *)ptr + 2) << zprec;
zA = *((unsigned char *)ptr + 3) << zprec;
for (int index=1; index<width; index++) {
blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
}
for (int index=width-2; index>=0; index--) {
blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
}
}
template<int aprec, int zprec>
static inline void blurcol(QImage &im, int col, int alpha)
{
int zR, zG, zB, zA;
QRgb *ptr = (QRgb *)im.bits();
ptr += col;
int height = im.height();
int width = im.width();
zR = *((unsigned char *)ptr ) << zprec;
zG = *((unsigned char *)ptr + 1) << zprec;
zB = *((unsigned char *)ptr + 2) << zprec;
zA = *((unsigned char *)ptr + 3) << zprec;
for (int index=width; index<(height-1)*width; index+=width) {
blurinner<aprec,zprec>((unsigned char *)&ptr[index], zR, zG, zB, zA, alpha);
}
for (int index=(height-2)*width; index>=0; index-=width) {
blurinner<aprec,zprec>((unsigned char *)&ptr[index], zR, zG, zB, zA, alpha);
}
}
template<class T>
inline const T &qClamp(const T &x, const T &low, const T &high)
{
if (x < low) {
return low;
} else if (x > high) {
return high;
} else {
return x;
}
}
#endif