Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Graphics
digiKam
Commits
ed81651f
Commit
ed81651f
authored
May 05, 2014
by
Gilles Caulier
🗼
Browse files
Raindrop Tool : add support of multicore CPU based on QtConcurrent API.
CCBUGS: 289204
parent
5776c84b
Changes
4
Hide whitespace changes
Inline
Side-by-side
NEWS
View file @
ed81651f
...
...
@@ -18,6 +18,7 @@ Editor : Blur tool support multicore CPU.
Editor : Charcoal tool support multicore CPU.
Editor : OilPaint tool support multicore CPU.
Editor : Emboss tool support multicore CPU.
Editor : Raindrop tool support multicore CPU.
Showfoto : Port of Thumbbar to Qt Model/view.
...
...
imageplugins/TODO
View file @
ed81651f
...
...
@@ -29,7 +29,7 @@ filters
/emboss DONE DONE DONE TODO
/oilpaint DONE DONE DONE TODO
/blurfx DONE TODO DONE TODO
/raindrop DONE
TO
DO NO TODO
/raindrop DONE DO
NE
NO TODO
/filmgrain DONE TODO DONE DONE
enhance
...
...
libs/dimg/filters/fx/raindropfilter.cpp
View file @
ed81651f
...
...
@@ -6,7 +6,7 @@
* Date : 2005-05-25
* Description : Raindrop threaded image filter.
*
* Copyright (C) 2005-201
2
by Gilles Caulier <caulier dot gilles at gmail dot com>
* Copyright (C) 2005-201
4
by Gilles Caulier <caulier dot gilles at gmail dot com>
* Copyright (C) 2006-2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
* Copyright (C) 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
*
...
...
@@ -37,6 +37,7 @@
#include <QDateTime>
#include <QRect>
#include <qmath.h>
#include <QtConcurrentRun>
// Local includes
...
...
@@ -109,7 +110,7 @@ void RainDropFilter::filterImage()
// Cut the original image in 4 areas without clipping region.
DImg
zone1
=
m_orgImage
.
copy
(
0
,
0
,
d
->
selection
.
x
(),
h
);
DImg
zone1
=
m_orgImage
.
copy
(
0
,
0
,
d
->
selection
.
x
(),
h
);
DImg
zone2
=
m_orgImage
.
copy
(
d
->
selection
.
x
(),
0
,
d
->
selection
.
x
()
+
d
->
selection
.
width
(),
d
->
selection
.
y
());
DImg
zone3
=
m_orgImage
.
copy
(
d
->
selection
.
x
(),
d
->
selection
.
y
()
+
d
->
selection
.
height
(),
d
->
selection
.
x
()
+
d
->
selection
.
width
(),
h
);
DImg
zone4
=
m_orgImage
.
copy
(
d
->
selection
.
x
()
+
d
->
selection
.
width
(),
0
,
w
,
h
);
...
...
@@ -140,6 +141,29 @@ void RainDropFilter::filterImage()
}
}
void
RainDropFilter
::
rainDropsImageMultithreaded
(
const
Args
&
prm
)
{
int
nRandSize
;
int
nRandX
,
nRandY
;
bool
bResp
=
false
;
int
nWidth
=
prm
.
orgImage
->
width
();
int
nHeight
=
prm
.
orgImage
->
height
();
bool
sixteenBit
=
prm
.
orgImage
->
sixteenBit
();
int
bytesDepth
=
prm
.
orgImage
->
bytesDepth
();
uchar
*
data
=
prm
.
orgImage
->
bits
();
uchar
*
pResBits
=
prm
.
destImage
->
bits
();
for
(
uint
nCounter
=
prm
.
start
;
runningFlag
()
&&
(
bResp
==
false
)
&&
(
nCounter
<
prm
.
stop
)
;
++
nCounter
)
{
nRandX
=
d
->
generator
.
number
(
0
,
nWidth
-
1
);
nRandY
=
d
->
generator
.
number
(
0
,
nHeight
-
1
);
nRandSize
=
d
->
generator
.
number
(
prm
.
MinDropSize
,
prm
.
MaxDropSize
);
bResp
=
CreateRainDrop
(
data
,
nWidth
,
nHeight
,
sixteenBit
,
bytesDepth
,
pResBits
,
prm
.
pStatusBits
,
nRandX
,
nRandY
,
nRandSize
,
prm
.
Coeff
,
prm
.
bLimitRange
);
}
}
/* Function to apply the RainDrops effect backported from ImageProcessing version 2
*
* orgImage => The image
...
...
@@ -161,17 +185,6 @@ void RainDropFilter::filterImage()
void
RainDropFilter
::
rainDropsImage
(
DImg
*
const
orgImage
,
DImg
*
const
destImage
,
int
MinDropSize
,
int
MaxDropSize
,
int
Amount
,
int
Coeff
,
bool
bLimitRange
,
int
progressMin
,
int
progressMax
)
{
bool
bResp
;
int
nRandSize
,
i
;
int
nRandX
,
nRandY
;
int
nCounter
=
0
;
int
nWidth
=
orgImage
->
width
();
int
nHeight
=
orgImage
->
height
();
bool
sixteenBit
=
orgImage
->
sixteenBit
();
int
bytesDepth
=
orgImage
->
bytesDepth
();
uchar
*
data
=
orgImage
->
bits
();
uchar
*
pResBits
=
destImage
->
bits
();
if
(
Amount
<=
0
)
{
return
;
...
...
@@ -187,8 +200,8 @@ void RainDropFilter::rainDropsImage(DImg* const orgImage, DImg* const destImage,
return
;
}
QScopedArrayPointer
<
uchar
>
pStatusBits
(
new
uchar
[
nH
eight
*
nW
idth
]);
memset
(
pStatusBits
.
data
(),
0
,
nH
eight
*
nW
idth
*
sizeof
(
uchar
));
QScopedArrayPointer
<
uchar
>
pStatusBits
(
new
uchar
[
orgImage
->
h
eight
()
*
orgImage
->
w
idth
()
]);
memset
(
pStatusBits
.
data
(),
0
,
orgImage
->
h
eight
()
*
orgImage
->
w
idth
()
*
sizeof
(
uchar
));
// Initially, copy all pixels to destination
...
...
@@ -196,23 +209,45 @@ void RainDropFilter::rainDropsImage(DImg* const orgImage, DImg* const destImage,
// Randomize.
for
(
i
=
0
;
runningFlag
()
&&
(
i
<
Amount
);
++
i
)
uint
nbCore
=
QThreadPool
::
globalInstance
()
->
maxThreadCount
();
float
step
=
10000
/
nbCore
;
uint
vals
[
nbCore
+
1
];
vals
[
0
]
=
0
;
vals
[
nbCore
]
=
10000
;
for
(
uint
i
=
1
;
i
<
nbCore
;
++
i
)
vals
[
i
]
=
vals
[
i
-
1
]
+
step
;
Args
prm
;
prm
.
orgImage
=
orgImage
;
prm
.
destImage
=
destImage
;
prm
.
MinDropSize
=
MinDropSize
;
prm
.
MaxDropSize
=
MaxDropSize
;
prm
.
Coeff
=
Coeff
;
prm
.
bLimitRange
=
bLimitRange
;
prm
.
pStatusBits
=
pStatusBits
.
data
();
for
(
int
i
=
0
;
runningFlag
()
&&
(
i
<
Amount
);
++
i
)
{
nCounter
=
0
;
QList
<
QFuture
<
void
>
>
tasks
;
do
for
(
uint
j
=
0
;
runningFlag
()
&&
(
j
<
nbCore
)
;
++
j
)
{
nRandX
=
d
->
generator
.
number
(
0
,
nWidth
-
1
);
nRandY
=
d
->
generator
.
number
(
0
,
nHeight
-
1
);
nRandSize
=
d
->
generator
.
number
(
MinDropSize
,
MaxDropSize
);
bResp
=
CreateRainDrop
(
data
,
nWidth
,
nHeight
,
sixteenBit
,
bytesDepth
,
pResBits
,
pStatusBits
.
data
(),
nRandX
,
nRandY
,
nRandSize
,
Coeff
,
bLimitRange
);
++
nCounter
;
prm
.
start
=
vals
[
j
];
prm
.
stop
=
vals
[
j
+
1
];
tasks
.
append
(
QtConcurrent
::
run
(
this
,
&
RainDropFilter
::
rainDropsImageMultithreaded
,
prm
));
}
while
((
bResp
==
false
)
&&
(
nCounter
<
10000
)
&&
runningFlag
());
foreach
(
QFuture
<
void
>
t
,
tasks
)
t
.
waitForFinished
();
/*
// Update the progress bar in dialog.
if (nCounter >= 10000)
{
...
...
@@ -221,7 +256,7 @@ void RainDropFilter::rainDropsImage(DImg* const orgImage, DImg* const destImage,
postProgress(progressMax);
break;
}
*/
postProgress
((
int
)(
progressMin
+
((
double
)(
i
)
*
(
double
)(
progressMax
-
progressMin
))
/
(
double
)
Amount
));
}
...
...
@@ -594,5 +629,4 @@ int RainDropFilter::pixelOffset(int Width, int X, int Y, int bytesDepth)
return
(
Y
*
Width
*
bytesDepth
+
X
*
bytesDepth
);
}
}
// namespace Digikam
libs/dimg/filters/fx/raindropfilter.h
View file @
ed81651f
...
...
@@ -6,7 +6,7 @@
* Date : 2005-05-25
* Description : Raindrop threaded image filter.
*
* Copyright (C) 2005-201
2
by Gilles Caulier <caulier dot gilles at gmail dot com>
* Copyright (C) 2005-201
4
by Gilles Caulier <caulier dot gilles at gmail dot com>
* Copyright (C) 2006-2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
* Copyright (C) 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
*
...
...
@@ -77,6 +77,21 @@ public:
void
readParameters
(
const
FilterAction
&
action
);
private:
struct
Args
{
uint
start
;
uint
stop
;
DImg
*
orgImage
;
DImg
*
destImage
;
int
MinDropSize
;
int
MaxDropSize
;
int
Coeff
;
bool
bLimitRange
;
uchar
*
pStatusBits
;
};
private:
void
filterImage
();
...
...
@@ -84,6 +99,8 @@ private:
void
rainDropsImage
(
DImg
*
const
orgImage
,
DImg
*
const
destImage
,
int
MinDropSize
,
int
MaxDropSize
,
int
Amount
,
int
Coeff
,
bool
bLimitRange
,
int
progressMin
,
int
progressMax
);
void
rainDropsImageMultithreaded
(
const
Args
&
prm
);
bool
CreateRainDrop
(
uchar
*
const
pBits
,
int
Width
,
int
Height
,
bool
sixteenBit
,
int
bytesDepth
,
uchar
*
const
pResBits
,
uchar
*
const
pStatusBits
,
int
X
,
int
Y
,
int
DropSize
,
double
Coeff
,
bool
bLimitRange
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment