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

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

SoftenerBlur effect : add support of multicore CPU based on QtConcurrents API. Computation time is divided by 2 with i7 (8 core CPU)
CCBUGS: 289204
parent 87d533f8
......@@ -642,26 +642,14 @@ void BlurFXFilter::motionBlur(DImg* const orgImage, DImg* const destImage, int D
}
}
/* Function to apply the softenerBlur effect
*
* data => The image data in RGBA mode.
* Width => Width of image.
* Height => Height of image.
*
* Theory => An interesting blur-like function. In dark tones we apply a
* blur with 3x3 dimentions, in light tones, we apply a blur with
* 5x5 dimentions. Easy, hun?
*/
void BlurFXFilter::softenerBlur(DImg* const orgImage, DImg* const destImage)
void BlurFXFilter::softenerBlurMultithreaded(const Args& prm)
{
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();
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 SomaR = 0, SomaG = 0, SomaB = 0;
int Gray;
......@@ -671,83 +659,121 @@ void BlurFXFilter::softenerBlur(DImg* const orgImage, DImg* const destImage)
int grayLimit = sixteenBit ? 32767 : 127;
for (int h = 0; runningFlag() && (h < Height); ++h)
for (uint w = prm.start; runningFlag() && (w < prm.stop); ++w)
{
for (int w = 0; runningFlag() && (w < Width); ++w)
{
SomaR = SomaG = SomaB = 0;
SomaR = SomaG = SomaB = 0;
offset = GetOffset(Width, w, h, bytesDepth);
color.setColor(data + offset, sixteenBit);
offset = GetOffset(Width, w, prm.h, bytesDepth);
color.setColor(data + offset, sixteenBit);
Gray = (color.red() + color.green() + color.blue()) / 3;
Gray = (color.red() + color.green() + color.blue()) / 3;
if (Gray > grayLimit)
if (Gray > grayLimit)
{
// 7x7
for (int a = -3; runningFlag() && (a <= 3); ++a)
{
// 7x7
for (int a = -3; runningFlag() && (a <= 3); ++a)
for (int b = -3; runningFlag() && (b <= 3); ++b)
{
for (int b = -3; runningFlag() && (b <= 3); ++b)
if ((((int)prm.h + a) < 0) || (((int)w + b) < 0))
{
if ((h + a < 0) || (w + b < 0))
{
offsetSoma = offset;
}
else
{
offsetSoma = GetOffset(Width, (w + Lim_Max(w, b, Width)),
(h + Lim_Max(h, a, Height)), bytesDepth);
}
colorSoma.setColor(data + offsetSoma, sixteenBit);
SomaR += colorSoma.red();
SomaG += colorSoma.green();
SomaB += colorSoma.blue();
offsetSoma = offset;
}
else
{
offsetSoma = GetOffset(Width, (w + Lim_Max(w, b, Width)),
(prm.h + Lim_Max(prm.h, a, Height)), bytesDepth);
}
}
// 7*7 = 49
color.setRed(SomaR / 49);
color.setGreen(SomaG / 49);
color.setBlue(SomaB / 49);
color.setPixel(pResBits + offset);
colorSoma.setColor(data + offsetSoma, sixteenBit);
SomaR += colorSoma.red();
SomaG += colorSoma.green();
SomaB += colorSoma.blue();
}
}
else
// 7*7 = 49
color.setRed(SomaR / 49);
color.setGreen(SomaG / 49);
color.setBlue(SomaB / 49);
color.setPixel(pResBits + offset);
}
else
{
// 3x3
for (int a = -1; runningFlag() && (a <= 1); ++a)
{
// 3x3
for (int a = -1; runningFlag() && (a <= 1); ++a)
for (int b = -1; runningFlag() && (b <= 1); ++b)
{
for (int b = -1; runningFlag() && (b <= 1); ++b)
if ((((int)prm.h + a) < 0) || (((int)w + b) < 0))
{
if ((h + a < 0) || (w + b < 0))
{
offsetSoma = offset;
}
else
{
offsetSoma = GetOffset(Width, (w + Lim_Max(w, b, Width)),
(h + Lim_Max(h, a, Height)), bytesDepth);
}
colorSoma.setColor(data + offsetSoma, sixteenBit);
SomaR += colorSoma.red();
SomaG += colorSoma.green();
SomaB += colorSoma.blue();
offsetSoma = offset;
}
}
else
{
offsetSoma = GetOffset(Width, (w + Lim_Max(w, b, Width)),
(prm.h + Lim_Max(prm.h, a, Height)), bytesDepth);
}
colorSoma.setColor(data + offsetSoma, sixteenBit);
// 3*3 = 9
color.setRed(SomaR / 9);
color.setGreen(SomaG / 9);
color.setBlue(SomaB / 9);
color.setPixel(pResBits + offset);
SomaR += colorSoma.red();
SomaG += colorSoma.green();
SomaB += colorSoma.blue();
}
}
// 3*3 = 9
color.setRed(SomaR / 9);
color.setGreen(SomaG / 9);
color.setBlue(SomaB / 9);
color.setPixel(pResBits + offset);
}
}
}
/* Function to apply the softenerBlur effect
*
* data => The image data in RGBA mode.
* Width => Width of image.
* Height => Height of image.
*
* Theory => An interesting blur-like function. In dark tones we apply a
* blur with 3x3 dimentions, in light tones, we apply a blur with
* 5x5 dimentions. Easy, hun?
*/
void BlurFXFilter::softenerBlur(DImg* const orgImage, DImg* const destImage)
{
int progress;
QList<uint> vals = multithreadedSteps(orgImage->width());
QList <QFuture<void> > tasks;
Args prm;
prm.orgImage = orgImage;
prm.destImage = destImage;
// we have reached the main loop
for (uint h = 0; runningFlag() && (h < orgImage->height()); ++h)
{
for (int j = 0 ; runningFlag() && (j < vals.count()-1) ; ++j)
{
prm.start = vals[j];
prm.stop = vals[j+1];
prm.h = h;
tasks.append(QtConcurrent::run(this,
&BlurFXFilter::softenerBlurMultithreaded,
prm
));
}
foreach(QFuture<void> t, tasks)
t.waitForFinished();
// Update the progress bar in dialog.
progress = (int)(((double)h * 100.0) / Height);
progress = (int)(((double)h * 100.0) / orgImage->height());
if (progress % 5 == 0)
{
......
......@@ -130,6 +130,7 @@ private:
// Backported from ImageProcessing version 1
void softenerBlur(DImg* const orgImage, DImg* const destImage);
void softenerBlurMultithreaded(const Args& prm);
void shakeBlur(DImg* const orgImage, DImg* const destImage, int Distance);
void shakeBlurStage1Multithreaded(const Args& prm);
......
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