Commit e5d465a5 authored by Gilles Caulier's avatar Gilles Caulier 🗼
Browse files

RadialBlur effect : add support of multicore CPU based on QtConcurrents API....

RadialBlur effect : add support of multicore CPU based on QtConcurrents API. Computation time is divided by 5 with i7 (8 core CPU)
CCBUGS: 289204
parent 268286e7
......@@ -140,7 +140,7 @@ void BlurFXFilter::filterImage()
}
}
void BlurFXFilter::zoomBlurMultithreaded(const ArgsZoomBlur& prm)
void BlurFXFilter::zoomBlurMultithreaded(const Args1& prm)
{
int nh, nw;
int sumR, sumG, sumB, nCount=0;
......@@ -255,7 +255,7 @@ void BlurFXFilter::zoomBlur(DImg* const orgImage, DImg* const destImage, int X,
QList<uint> vals = multithreadedSteps(xMax, xMin);
QList <QFuture<void> > tasks;
ArgsZoomBlur prm;
Args1 prm;
prm.orgImage = orgImage;
prm.destImage = destImage;
prm.X = X;
......@@ -289,6 +289,85 @@ void BlurFXFilter::zoomBlur(DImg* const orgImage, DImg* const destImage, int X,
}
}
void BlurFXFilter::radialBlurMultithreaded(const Args1& prm)
{
int Width = prm.orgImage->width();
int Height = prm.orgImage->height();
uchar* data = prm.orgImage->bits();
bool sixteenBit = prm.orgImage->sixteenBit();
int bytesDepth = prm.orgImage->bytesDepth();
uchar* pResBits = prm.destImage->bits();
int sumR, sumG, sumB, nw, nh;
double Radius, Angle, AngleRad;
DColor color;
int offset;
QScopedArrayPointer<double> nMultArray(new double[prm.Distance * 2 + 1]);
for (int i = -prm.Distance; i <= prm.Distance; ++i)
{
nMultArray[i + prm.Distance] = i * ANGLE_RATIO;
}
// number of added pixels
int nCount = 0;
for (uint w = prm.start; runningFlag() && (w < prm.stop); ++w)
{
// ...we enter this loop to sum the bits
// we initialize the variables
sumR = sumG = sumB = nCount = 0;
nw = prm.X - w;
nh = prm.Y - prm.h;
Radius = qSqrt(nw * nw + nh * nh);
AngleRad = qAtan2((double)nh, (double)nw);
for (int a = -prm.Distance; runningFlag() && (a <= prm.Distance); ++a)
{
Angle = AngleRad + nMultArray[a + prm.Distance];
// we need to calc the positions
nw = (int)(prm.X - Radius * qCos(Angle));
nh = (int)(prm.Y - Radius * qSin(Angle));
if (IsInside(Width, Height, nw, nh))
{
// read color
offset = GetOffset(Width, nw, nh, bytesDepth);
color.setColor(data + offset, sixteenBit);
// we sum the bits
sumR += color.red();
sumG += color.green();
sumB += color.blue();
++nCount;
}
}
if (nCount == 0)
{
nCount = 1;
}
// calculate pointer
offset = GetOffset(Width, w, prm.h, bytesDepth);
// read color to preserve alpha
color.setColor(data + offset, sixteenBit);
// now, we have to calc the arithmetic average
color.setRed(sumR / nCount);
color.setGreen(sumG / nCount);
color.setBlue(sumB / nCount);
// write color to destination
color.setPixel(pResBits + offset);
}
}
/* Function to apply the radialBlur effect backported from ImageProcessing version 2
*
* data => The image data in RGBA mode.
......@@ -314,18 +393,11 @@ void BlurFXFilter::radialBlur(DImg* const orgImage, DImg* const destImage, int X
int progress;
int Width = orgImage->width();
int Height = orgImage->height();
uchar* data = orgImage->bits();
bool sixteenBit = orgImage->sixteenBit();
int bytesDepth = orgImage->bytesDepth();
uchar* pResBits = destImage->bits();
// We working on full image.
int xMin = 0;
int xMax = Width;
int xMax = orgImage->width();
int yMin = 0;
int yMax = Height;
int yMax = orgImage->height();
// If we working in preview mode, else we using the preview area.
if (pArea.isValid())
......@@ -336,79 +408,34 @@ void BlurFXFilter::radialBlur(DImg* const orgImage, DImg* const destImage, int X
yMax = pArea.y() + pArea.height();
}
int sumR, sumG, sumB, nw, nh;
double Radius, Angle, AngleRad;
DColor color;
int offset;
QScopedArrayPointer<double> nMultArray(new double[Distance * 2 + 1]);
for (int i = -Distance; i <= Distance; ++i)
{
nMultArray[i + Distance] = i * ANGLE_RATIO;
}
QList<uint> vals = multithreadedSteps(xMax, xMin);
QList <QFuture<void> > tasks;
// number of added pixels
int nCount = 0;
Args1 prm;
prm.orgImage = orgImage;
prm.destImage = destImage;
prm.X = X;
prm.Y = Y;
prm.Distance = Distance;
// we have reached the main loop
for (int h = yMin; runningFlag() && (h < yMax); ++h)
{
for (int w = xMin; runningFlag() && (w < xMax); ++w)
for (int j = 0 ; runningFlag() && (j < vals.count()-1) ; ++j)
{
// ...we enter this loop to sum the bits
// we initialize the variables
sumR = sumG = sumB = nCount = 0;
nw = X - w;
nh = Y - h;
Radius = qSqrt(nw * nw + nh * nh);
AngleRad = qAtan2((double)nh, (double)nw);
for (int a = -Distance; runningFlag() && (a <= Distance); ++a)
{
Angle = AngleRad + nMultArray[a + Distance];
// we need to calc the positions
nw = (int)(X - Radius * qCos(Angle));
nh = (int)(Y - Radius * qSin(Angle));
if (IsInside(Width, Height, nw, nh))
{
// read color
offset = GetOffset(Width, nw, nh, bytesDepth);
color.setColor(data + offset, sixteenBit);
// we sum the bits
sumR += color.red();
sumG += color.green();
sumB += color.blue();
++nCount;
}
}
if (nCount == 0)
{
nCount = 1;
}
// calculate pointer
offset = GetOffset(Width, w, h, bytesDepth);
// read color to preserve alpha
color.setColor(data + offset, sixteenBit);
// now, we have to calc the arithmetic average
color.setRed(sumR / nCount);
color.setGreen(sumG / nCount);
color.setBlue(sumB / nCount);
// write color to destination
color.setPixel(pResBits + offset);
prm.start = vals[j];
prm.stop = vals[j+1];
prm.h = h;
tasks.append(QtConcurrent::run(this,
&BlurFXFilter::radialBlurMultithreaded,
prm
));
}
foreach(QFuture<void> t, tasks)
t.waitForFinished();
// Update the progress bar in dialog.
progress = (int)(((double)(h - yMin) * 100.0) / (yMax - yMin));
......
......@@ -97,7 +97,7 @@ public:
private:
struct ArgsZoomBlur
struct Args1
{
uint start;
uint stop;
......@@ -120,9 +120,10 @@ private:
// Backported from ImageProcessing version 2
void zoomBlur(DImg* const orgImage, DImg* const destImage, int X, int Y, int Distance, const QRect& pArea=QRect());
void zoomBlurMultithreaded(const ArgsZoomBlur& prm);
void zoomBlurMultithreaded(const Args1& prm);
void radialBlur(DImg* const orgImage, DImg* const destImage, int X, int Y, int Distance, const QRect& pArea=QRect());
void radialBlurMultithreaded(const Args1& prm);
void focusBlur(DImg* const orgImage, DImg* const destImage, int X, int Y, int BlurRadius, int BlendRadius,
bool bInversed=false, const QRect& pArea=QRect());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment