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

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

Twirl effect : add support of multicore CPU based on QtConcurrents API. Computation time is divided by 2 with i7 (8 core CPU)
CCBUGS: 289204
parent 424b9625
......@@ -301,34 +301,14 @@ void DistortionFXFilter::fisheye(DImg* orgImage, DImg* destImage, double Coeff,
}
}
/* Function to apply the twirl effect backported from ImageProcesqSing version 2
*
* data => The image data in RGBA mode.
* Width => Width of image.
* Height => Height of image.
* dist => Distance value.
* Antialias => Smart blurring result.
*
* Theory => Take spiral studies, you will understand better, I'm studying
* hard on this effect, because it is not too fast.
*/
void DistortionFXFilter::twirl(DImg* orgImage, DImg* destImage, int dist, bool AntiAlias)
void DistortionFXFilter::twirlMultithreaded(const Args& prm)
{
// if dist value is zero, we do nothing
if (dist == 0)
{
return;
}
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();
DColor color;
int offset;
......@@ -338,7 +318,7 @@ void DistortionFXFilter::twirl(DImg* orgImage, DImg* destImage, int dist, bool A
double lfXScale = 1.0;
double lfYScale = 1.0;
double lfAngle, lfNewAngle, lfAngleSum, lfCurrentRadius;
double tw, th, nh, nw;
double tw, nh, nw;
if (Width > Height)
{
......@@ -350,50 +330,96 @@ void DistortionFXFilter::twirl(DImg* orgImage, DImg* destImage, int dist, bool A
}
// the angle step is dist divided by 10000
double lfAngleStep = dist / 10000.0;
double lfAngleStep = prm.dist / 10000.0;
// now, we get the minimum radius
double lfRadMax = (double)qMax(Width, Height) / 2.0;
// main loop
double th = lfYScale * (double)(prm.h - nHalfH);
for (int h = 0; runningFlag() && (h < Height); ++h)
for (int w = prm.start; runningFlag() && (w < prm.stop); ++w)
{
th = lfYScale * (double)(h - nHalfH);
tw = lfXScale * (double)(w - nHalfW);
for (int w = 0; runningFlag() && (w < Width); ++w)
// now, we get the distance
lfCurrentRadius = qSqrt(th * th + tw * tw);
// if distance is less than maximum radius...
if (lfCurrentRadius < lfRadMax)
{
tw = lfXScale * (double)(w - nHalfW);
// we find the angle from the center
lfAngle = qAtan2(th, tw);
// we get the accumuled angle
lfAngleSum = lfAngleStep * (-1.0 * (lfCurrentRadius - lfRadMax));
// ok, we sum angle with accumuled to find a new angle
lfNewAngle = lfAngle + lfAngleSum;
// now, we get the distance
lfCurrentRadius = qSqrt(th * th + tw * tw);
// now we find the exact position's x and y
nw = (double)nHalfW + qCos(lfNewAngle) * (lfCurrentRadius / lfXScale);
nh = (double)nHalfH + qSin(lfNewAngle) * (lfCurrentRadius / lfYScale);
// if distance is less than maximum radius...
if (lfCurrentRadius < lfRadMax)
{
// we find the angle from the center
lfAngle = qAtan2(th, tw);
// we get the accumuled angle
lfAngleSum = lfAngleStep * (-1.0 * (lfCurrentRadius - lfRadMax));
// ok, we sum angle with accumuled to find a new angle
lfNewAngle = lfAngle + lfAngleSum;
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, prm.h, nw, nh, prm.AntiAlias);
}
else
{
// copy pixel
offset = getOffset(Width, w, prm.h, bytesDepth);
color.setColor(data + offset, sixteenBit);
color.setPixel(pResBits + offset);
}
}
}
// now we find the exact position's x and y
nw = (double)nHalfW + qCos(lfNewAngle) * (lfCurrentRadius / lfXScale);
nh = (double)nHalfH + qSin(lfNewAngle) * (lfCurrentRadius / lfYScale);
/* Function to apply the twirl effect backported from ImageProcesqSing version 2
*
* data => The image data in RGBA mode.
* Width => Width of image.
* Height => Height of image.
* dist => Distance value.
* Antialias => Smart blurring result.
*
* Theory => Take spiral studies, you will understand better, I'm studying
* hard on this effect, because it is not too fast.
*/
void DistortionFXFilter::twirl(DImg* orgImage, DImg* destImage, int dist, bool AntiAlias)
{
// if dist value is zero, we do nothing
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
}
else
{
// copy pixel
offset = getOffset(Width, w, h, bytesDepth);
color.setColor(data + offset, sixteenBit);
color.setPixel(pResBits + offset);
}
if (dist == 0)
{
return;
}
int progress;
QList<int> vals = multithreadedSteps(orgImage->width());
QList <QFuture<void> > tasks;
Args prm;
prm.orgImage = orgImage;
prm.destImage = destImage;
prm.dist = dist;
prm.AntiAlias = AntiAlias;
// main loop
for (int h = 0; runningFlag() && (h < (int)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,
&DistortionFXFilter::twirlMultithreaded,
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)
{
......
......@@ -111,6 +111,7 @@ private:
DImg* destImage;
double Coeff;
bool AntiAlias;
int dist;
};
private:
......@@ -122,6 +123,8 @@ private:
void fisheyeMultithreaded(const Args& prm);
void twirl(DImg* orgImage, DImg* destImage, int dist, bool AntiAlias=true);
void twirlMultithreaded(const Args& prm);
void cilindrical(DImg* orgImage, DImg* destImage, double Coeff,
bool Horizontal, bool Vertical, bool AntiAlias=true);
void multipleCorners(DImg* orgImage, DImg* destImage, int Factor, bool AntiAlias=true);
......
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