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
b451f671
Commit
b451f671
authored
May 04, 2014
by
Gilles Caulier
🗼
Browse files
OilPaint Tool : add support of multicore CPU based on QtConcurrent API.
CCBUGS: 289204
parent
cb3bec4e
Changes
4
Hide whitespace changes
Inline
Side-by-side
NEWS
View file @
b451f671
...
...
@@ -16,6 +16,7 @@ Editor : LocalContrast tool support multicore CPU.
Editor : Sharpen tool support multicore CPU.
Editor : Blur tool support multicore CPU.
Editor : Charcoal tool support multicore CPU.
Editor : OilPaint tool support multicore CPU.
Showfoto : Port of Thumbbar to Qt Model/view.
...
...
imageplugins/TODO
View file @
b451f671
...
...
@@ -27,7 +27,7 @@ filters
/charcoal DONE DONE DONE TODO
/distortionfx DONE TODO TODO TODO
/emboss DONE TODO DONE TODO
/oilpaint DONE
TO
DO DONE TODO
/oilpaint DONE DO
NE
DONE TODO
/blurfx DONE TODO DONE TODO
/raindrop DONE TODO NO TODO
/filmgrain DONE TODO DONE DONE
...
...
libs/dimg/filters/fx/oilpaintfilter.cpp
View file @
b451f671
...
...
@@ -6,7 +6,7 @@
* Date : 2005-05-25
* Description : Oil Painting threaded image filter.
*
* Copyright (C) 2005-201
3
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>
*
...
...
@@ -33,6 +33,11 @@
#include <cmath>
#include <cstdlib>
// Qt includes
#include <QtConcurrentRun>
#include <QMutex>
// Local includes
#include "dimg.h"
...
...
@@ -45,23 +50,18 @@ class OilPaintFilter::Private
public:
Private
()
:
intensityCount
(
0
),
brushSize
(
1
),
smoothness
(
30
),
averageColorR
(
0
),
averageColorG
(
0
),
averageColorB
(
0
)
globalProgress
(
0
)
{
}
uchar
*
intensityCount
;
int
brushSize
;
int
smoothness
;
u
int
*
averageColorR
;
uint
*
averageColorG
;
uint
*
averageColorB
;
int
globalProgress
;
QMutex
lock
;
};
OilPaintFilter
::
OilPaintFilter
(
QObject
*
const
parent
)
...
...
@@ -93,48 +93,66 @@ OilPaintFilter::~OilPaintFilter()
* Theory: Using MostFrequentColor function we take the main color in
* a matrix and simply write at the original position.
*/
void
OilPaintFilter
::
f
il
terImage
(
)
void
OilPaintFilter
::
o
il
PaintImageMultithreaded
(
uint
start
,
uint
stop
)
{
int
progress
;
uchar
*
intensityCount
=
new
uchar
[
d
->
smoothness
+
1
];
uint
*
averageColorR
=
new
uint
[
d
->
smoothness
+
1
];
uint
*
averageColorG
=
new
uint
[
d
->
smoothness
+
1
];
uint
*
averageColorB
=
new
uint
[
d
->
smoothness
+
1
];
int
oldProgress
=
0
,
progress
=
0
;
DColor
mostFrequentColor
;
int
w
,
h
;
mostFrequentColor
.
setSixteenBit
(
m_orgImage
.
sixteenBit
());
w
=
(
int
)
m_orgImage
.
width
();
h
=
(
int
)
m_orgImage
.
height
();
uchar
*
dest
=
m_destImage
.
bits
();
int
bytesDepth
=
m_orgImage
.
bytesDepth
();
uchar
*
dptr
=
0
;
// Allocate some arrays to be used.
// Do this here once for all to save a few million new / delete operations
d
->
intensityCount
=
new
uchar
[
d
->
smoothness
+
1
];
d
->
averageColorR
=
new
uint
[
d
->
smoothness
+
1
];
d
->
averageColorG
=
new
uint
[
d
->
smoothness
+
1
];
d
->
averageColorB
=
new
uint
[
d
->
smoothness
+
1
];
for
(
int
h2
=
0
;
runningFlag
()
&&
(
h2
<
h
);
++
h2
)
for
(
uint
h2
=
start
;
runningFlag
()
&&
(
h2
<
stop
);
++
h2
)
{
for
(
int
w2
=
0
;
runningFlag
()
&&
(
w2
<
w
);
++
w2
)
for
(
u
int
w2
=
0
;
runningFlag
()
&&
(
w2
<
m_orgImage
.
width
()
);
++
w2
)
{
mostFrequentColor
=
MostFrequentColor
(
m_orgImage
,
w2
,
h2
,
d
->
brushSize
,
d
->
smoothness
);
dptr
=
dest
+
w2
*
bytesDepth
+
(
w
*
h2
*
bytesDepth
);
mostFrequentColor
=
MostFrequentColor
(
m_orgImage
,
w2
,
h2
,
d
->
brushSize
,
d
->
smoothness
,
intensityCount
,
averageColorR
,
averageColorG
,
averageColorB
);
dptr
=
dest
+
w2
*
m_orgImage
.
bytesDepth
()
+
(
m_orgImage
.
width
()
*
h2
*
m_orgImage
.
bytesDepth
());
mostFrequentColor
.
setPixel
(
dptr
);
}
progress
=
(
int
)(
(
(
double
)
h2
*
100.0
)
/
h
);
progress
=
(
int
)(
(
(
double
)
h2
*
(
100.0
/
QThreadPool
::
globalInstance
()
->
maxThreadCount
())
)
/
(
stop
-
start
)
);
if
(
progress
%
5
==
0
)
if
(
(
progress
%
5
==
0
)
&&
(
progress
>
oldProgress
))
{
postProgress
(
progress
);
d
->
lock
.
lock
();
oldProgress
=
progress
;
d
->
globalProgress
+=
5
;
postProgress
(
d
->
globalProgress
);
d
->
lock
.
unlock
();
}
}
delete
[]
intensityCount
;
delete
[]
averageColorR
;
delete
[]
averageColorG
;
delete
[]
averageColorB
;
}
void
OilPaintFilter
::
filterImage
()
{
int
nbCore
=
QThreadPool
::
globalInstance
()
->
maxThreadCount
();
float
step
=
m_orgImage
.
height
()
/
nbCore
;
QList
<
QFuture
<
void
>
>
tasks
;
for
(
int
j
=
0
;
runningFlag
()
&&
(
j
<
nbCore
)
;
++
j
)
{
tasks
.
append
(
QtConcurrent
::
run
(
this
,
&
OilPaintFilter
::
oilPaintImageMultithreaded
,
(
uint
)(
j
*
step
),
(
uint
)((
j
+
1
)
*
step
)
));
}
// free all the arrays
delete
[]
d
->
intensityCount
;
delete
[]
d
->
averageColorR
;
delete
[]
d
->
averageColorG
;
delete
[]
d
->
averageColorB
;
foreach
(
QFuture
<
void
>
t
,
tasks
)
t
.
waitForFinished
();
}
/** Function to determine the most frequent color in a matrix
...
...
@@ -150,7 +168,8 @@ void OilPaintFilter::filterImage()
* Theory => This function creates a matrix with the analyzed pixel in
* the center of this matrix and find the most frequently color
*/
DColor
OilPaintFilter
::
MostFrequentColor
(
DImg
&
src
,
int
X
,
int
Y
,
int
Radius
,
int
Intensity
)
DColor
OilPaintFilter
::
MostFrequentColor
(
DImg
&
src
,
int
X
,
int
Y
,
int
Radius
,
int
Intensity
,
uchar
*
intensityCount
,
uint
*
averageColorR
,
uint
*
averageColorG
,
uint
*
averageColorB
)
{
int
i
,
w
,
h
,
I
,
Width
,
Height
;
uint
red
,
green
,
blue
;
...
...
@@ -167,7 +186,7 @@ DColor OilPaintFilter::MostFrequentColor(DImg& src, int X, int Y, int Radius, in
Height
=
(
int
)
src
.
height
();
// Erase the array
memset
(
d
->
intensityCount
,
0
,
(
Intensity
+
1
)
*
sizeof
(
uchar
));
memset
(
intensityCount
,
0
,
(
Intensity
+
1
)
*
sizeof
(
uchar
));
for
(
w
=
X
-
Radius
;
w
<=
X
+
Radius
;
++
w
)
{
...
...
@@ -184,19 +203,19 @@ DColor OilPaintFilter::MostFrequentColor(DImg& src, int X, int Y, int Radius, in
blue
=
(
uint
)
color
.
blue
();
I
=
lround
(
GetIntensity
(
red
,
green
,
blue
)
*
Scale
);
d
->
intensityCount
[
I
]
++
;
intensityCount
[
I
]
++
;
if
(
d
->
intensityCount
[
I
]
==
1
)
if
(
intensityCount
[
I
]
==
1
)
{
d
->
averageColorR
[
I
]
=
red
;
d
->
averageColorG
[
I
]
=
green
;
d
->
averageColorB
[
I
]
=
blue
;
averageColorR
[
I
]
=
red
;
averageColorG
[
I
]
=
green
;
averageColorB
[
I
]
=
blue
;
}
else
{
d
->
averageColorR
[
I
]
+=
red
;
d
->
averageColorG
[
I
]
+=
green
;
d
->
averageColorB
[
I
]
+=
blue
;
averageColorR
[
I
]
+=
red
;
averageColorG
[
I
]
+=
green
;
averageColorB
[
I
]
+=
blue
;
}
}
}
...
...
@@ -207,10 +226,10 @@ DColor OilPaintFilter::MostFrequentColor(DImg& src, int X, int Y, int Radius, in
for
(
i
=
0
;
i
<=
Intensity
;
++
i
)
{
if
(
d
->
intensityCount
[
i
]
>
MaxInstance
)
if
(
intensityCount
[
i
]
>
MaxInstance
)
{
I
=
i
;
MaxInstance
=
d
->
intensityCount
[
i
];
MaxInstance
=
intensityCount
[
i
];
}
}
...
...
@@ -218,9 +237,9 @@ DColor OilPaintFilter::MostFrequentColor(DImg& src, int X, int Y, int Radius, in
mostFrequentColor
=
src
.
getPixelColor
(
X
,
Y
);
// Overwrite RGB values to destination.
mostFrequentColor
.
setRed
(
d
->
averageColorR
[
I
]
/
MaxInstance
);
mostFrequentColor
.
setGreen
(
d
->
averageColorG
[
I
]
/
MaxInstance
);
mostFrequentColor
.
setBlue
(
d
->
averageColorB
[
I
]
/
MaxInstance
);
mostFrequentColor
.
setRed
(
averageColorR
[
I
]
/
MaxInstance
);
mostFrequentColor
.
setGreen
(
averageColorG
[
I
]
/
MaxInstance
);
mostFrequentColor
.
setBlue
(
averageColorB
[
I
]
/
MaxInstance
);
return
mostFrequentColor
;
}
...
...
libs/dimg/filters/fx/oilpaintfilter.h
View file @
b451f671
...
...
@@ -6,7 +6,7 @@
* Date : 2005-05-25
* Description : Oil Painting threaded image filter.
*
* Copyright (C) 2005-201
3
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>
*
...
...
@@ -75,8 +75,9 @@ public:
private:
void
filterImage
();
DColor
MostFrequentColor
(
DImg
&
src
,
int
X
,
int
Y
,
int
Radius
,
int
Intensity
);
void
oilPaintImageMultithreaded
(
uint
start
,
uint
stop
);
DColor
MostFrequentColor
(
DImg
&
src
,
int
X
,
int
Y
,
int
Radius
,
int
Intensity
,
uchar
*
intensityCount
,
uint
*
averageColorR
,
uint
*
averageColorG
,
uint
*
averageColorB
);
inline
double
GetIntensity
(
uint
Red
,
uint
Green
,
uint
Blue
);
private:
...
...
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