Page Menu
Home
Search
Configure Global Search
Log In
Paste
P2880
Quick gaussian blur
Active
Public
Actions
Authored by
Lukas Stockner (lukasstockner97)
on Apr 4 2022, 2:30 AM.
Edit Paste
Archive Paste
View Raw File
Subscribe
Mute Notifications
Award Token
Tags
None
Subscribers
None
void
IMB_filter_convolve
(
const
ImBuf
*
source
,
ImBuf
*
dest
,
const
float
*
kernel
,
int
kernel_width
)
{
unsigned
char
*
input
=
(
unsigned
char
*
)
source
->
rect
;
unsigned
char
*
output
=
(
unsigned
char
*
)
dest
->
rect
;
BLI_assert
(
input
&&
output
);
/* Note: This is not particularly optimized. */
int
width
=
source
->
x
;
int
height
=
source
->
y
;
int
stride
=
source
->
x
;
/* Vertical convolution step. */
float
*
temp_row_v
=
MEM_mallocN
(
4
*
width
*
sizeof
(
float
),
__func__
);
for
(
int
y
=
0
;
y
<
height
;
y
++
)
{
memset
(
temp_row_v
,
0
,
4
*
width
*
sizeof
(
float
));
for
(
int
dy
=
max_ii
(
-
kernel_width
+
1
,
-
y
);
dy
<
min_ii
(
kernel_width
,
height
-
y
);
dy
++
)
{
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
float
pixel
[
4
];
srgb_to_linearrgb_uchar4
(
pixel
,
&
input
[
4
*
((
y
+
dy
)
*
stride
+
x
)]);
madd_v4_v4fl
(
temp_row_v
+
4
*
x
,
pixel
,
kernel
[
abs
(
dy
)]);
}
}
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
linearrgb_to_srgb_uchar4
(
&
output
[
4
*
(
y
*
stride
+
x
)],
temp_row_v
+
4
*
x
);
}
}
MEM_freeN
(
temp_row_v
);
/* Horizontal convolution step. */
unsigned
char
*
temp_row_h
=
MEM_mallocN
(
4
*
width
*
sizeof
(
unsigned
char
),
__func__
);
for
(
int
y
=
0
;
y
<
height
;
y
++
)
{
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
float
accum
[
4
],
pixel
[
4
];
zero_v4
(
accum
);
for
(
int
dx
=
max_ii
(
-
kernel_width
+
1
,
-
x
);
dx
<
min_ii
(
kernel_width
,
width
-
x
);
dx
++
)
{
srgb_to_linearrgb_uchar4
(
pixel
,
&
output
[
4
*
(
y
*
stride
+
x
+
dx
)]);
madd_v4_v4fl
(
accum
,
pixel
,
kernel
[
abs
(
dx
)]);
}
linearrgb_to_srgb_uchar4
(
&
temp_row_h
[
4
*
x
],
accum
);
}
memcpy
(
output
+
4
*
y
*
stride
,
temp_row_h
,
4
*
width
*
sizeof
(
unsigned
char
));
}
MEM_freeN
(
temp_row_h
);
}
void
IMB_filter_gaussian
(
const
struct
ImBuf
*
source
,
struct
ImBuf
*
dest
,
float
sigma
)
{
int
w
=
3
*
((
int
)
sigma
);
float
*
kernel
=
MEM_mallocN
(
sizeof
(
float
)
*
w
,
__func__
);
/* Compute gaussian kernel. */
float
fac1
=
0.5f
/
(
sigma
*
sigma
),
fac2
=
1.0f
/
(
sqrtf
(
2.0f
*
M_PI
)
*
sigma
);
float
scale
=
0.0f
;
for
(
int
i
=
0
;
i
<
w
;
i
++
)
{
kernel
[
i
]
=
fac2
*
expf
(
-
i
*
i
*
fac1
);
scale
+=
kernel
[
i
];
if
(
i
>
0
)
{
scale
+=
kernel
[
i
];
}
}
/* Normalize kernel. */
scale
=
1.0f
/
scale
;
for
(
int
i
=
0
;
i
<
w
;
i
++
)
{
kernel
[
i
]
*=
scale
;
}
IMB_filter_convolve
(
source
,
dest
,
kernel
,
w
);
MEM_freeN
(
kernel
);
}
Event Timeline
Lukas Stockner (lukasstockner97)
created this paste.
Apr 4 2022, 2:30 AM
Log In to Comment