Skip to content

Commit 93f4388

Browse files
alimpfardawesomekling
authored andcommitted
LibGfx+PixelPaint: Fix distortions in convolutions with size != 4 or 5
1 parent 95434d7 commit 93f4388

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

Applications/PixelPaint/FilterParams.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,15 @@ template<size_t N>
121121
struct FilterParameters<Gfx::SpatialGaussianBlurFilter<N>> {
122122
static OwnPtr<typename Gfx::SpatialGaussianBlurFilter<N>::Parameters> get()
123123
{
124+
constexpr static ssize_t offset = N / 2;
124125
Matrix<N, float> kernel;
125126
auto sigma = 1.0f;
126127
auto s = 2.0f * sigma * sigma;
127128

128-
for (auto x = -(ssize_t)N / 2; x <= (ssize_t)N / 2; x++) {
129-
for (auto y = -(ssize_t)N / 2; y <= (ssize_t)N / 2; y++) {
129+
for (auto x = -offset; x <= offset; x++) {
130+
for (auto y = -offset; y <= offset; y++) {
130131
auto r = sqrt(x * x + y * y);
131-
kernel.elements()[x + 2][y + 2] = (exp(-(r * r) / s)) / (M_PI * s);
132+
kernel.elements()[x + offset][y + offset] = (exp(-(r * r) / s)) / (M_PI * s);
132133
}
133134
}
134135

Libraries/LibGfx/Filters/GenericConvolutionFilter.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class GenericConvolutionFilter : public Filter {
7373
class ApplyCache {
7474
template<size_t>
7575
friend class GenericConvolutionFilter;
76+
7677
private:
7778
RefPtr<Gfx::Bitmap> m_target;
7879
};
@@ -120,23 +121,24 @@ class GenericConvolutionFilter : public Filter {
120121
Bitmap* render_target_bitmap = (&target != &source) ? &target : apply_cache.m_target.ptr();
121122

122123
// FIXME: Help! I am naive!
124+
constexpr static ssize_t offset = N / 2;
123125
for (auto i_ = 0; i_ < target_rect.width(); ++i_) {
124-
auto i = i_ + target_rect.x();
126+
ssize_t i = i_ + target_rect.x();
125127
for (auto j_ = 0; j_ < target_rect.height(); ++j_) {
126-
auto j = j_ + target_rect.y();
128+
ssize_t j = j_ + target_rect.y();
127129
FloatVector3 value(0, 0, 0);
128-
for (auto k = 0; k < 4; ++k) {
129-
auto ki = i + k - 2;
130-
if (i < source_rect.x() || i > source_rect.right()) {
130+
for (auto k = 0l; k < (ssize_t)N; ++k) {
131+
auto ki = i + k - offset;
132+
if (ki < source_rect.x() || ki > source_rect.right()) {
131133
if (parameters.should_wrap())
132134
ki = (ki + source.size().width()) % source.size().width(); // TODO: fix up using source_rect
133135
else
134136
continue;
135137
}
136138

137-
for (auto l = 0; l < 4; ++l) {
138-
auto lj = j + l - 2;
139-
if (j < source_rect.y() || j > source_rect.bottom()) {
139+
for (auto l = 0l; l < (ssize_t)N; ++l) {
140+
auto lj = j + l - offset;
141+
if (lj < source_rect.y() || lj > source_rect.bottom()) {
140142
if (parameters.should_wrap())
141143
lj = (lj + source.size().height()) % source.size().height(); // TODO: fix up using source_rect
142144
else
@@ -150,7 +152,7 @@ class GenericConvolutionFilter : public Filter {
150152
}
151153
}
152154

153-
// The float->u8 overflow is intentional.
155+
value.clamp(0, 255);
154156
render_target_bitmap->set_pixel(i, j, Color(value.x(), value.y(), value.z(), source.get_pixel(i + source_delta_x, j + source_delta_y).alpha()));
155157
}
156158
}

Libraries/LibGfx/Vector3.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ class Vector3 {
8787
return *this * inv_length;
8888
}
8989

90+
Vector3 clamped(T m, T x) const
91+
{
92+
Vector3 copy { *this };
93+
copy.clamp(m, x);
94+
return copy;
95+
}
96+
97+
void clamp(T min_value, T max_value)
98+
{
99+
m_x = max(min_value, m_x);
100+
m_y = max(min_value, m_y);
101+
m_z = max(min_value, m_z);
102+
m_x = min(max_value, m_x);
103+
m_y = min(max_value, m_y);
104+
m_z = min(max_value, m_z);
105+
}
106+
90107
void normalize()
91108
{
92109
T inv_length = 1 / length();

0 commit comments

Comments
 (0)