From 64cc482f8aad87e26c303baec4b8b9ac9d6b6e15 Mon Sep 17 00:00:00 2001 From: Tobias Christiansen Date: Wed, 16 Mar 2022 14:03:28 +0100 Subject: [PATCH] LibGfx: Allow for different {x,y}-radii in FastBoxBlurFilter Use different specified radii for the two seperate passes. The gaussian approximation is not changed to accept two parameters since the math is not exactly straight forward and therefore something for a later patch. For now, let's progress! --- .../LibGfx/Filters/FastBoxBlurFilter.cpp | 38 +++++++++++-------- .../LibGfx/Filters/FastBoxBlurFilter.h | 2 + 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.cpp b/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.cpp index 57c632521e..7cbec6ea7c 100644 --- a/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.cpp +++ b/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.cpp @@ -28,8 +28,13 @@ FastBoxBlurFilter::FastBoxBlurFilter(Bitmap& bitmap) { } -// Based on the super fast blur algorithm by Quasimondo, explored here: https://stackoverflow.com/questions/21418892/understanding-super-fast-blur-algorithm void FastBoxBlurFilter::apply_single_pass(size_t radius) +{ + apply_single_pass(radius, radius); +} + +// Based on the super fast blur algorithm by Quasimondo, explored here: https://stackoverflow.com/questions/21418892/understanding-super-fast-blur-algorithm +void FastBoxBlurFilter::apply_single_pass(size_t radius_x, size_t radius_y) { auto format = m_bitmap.format(); VERIFY(format == BitmapFormat::BGRA8888 || format == BitmapFormat::BGRx8888); @@ -52,7 +57,8 @@ void FastBoxBlurFilter::apply_single_pass(size_t radius) int height = m_bitmap.height(); int width = m_bitmap.width(); - int div = 2 * radius + 1; + int div_x = 2 * radius_x + 1; + int div_y = 2 * radius_y + 1; Vector intermediate_red; Vector intermediate_green; @@ -72,7 +78,7 @@ void FastBoxBlurFilter::apply_single_pass(size_t radius) size_t sum_alpha = 0; // Setup sliding window - for (int i = -(int)radius; i <= (int)radius; ++i) { + for (int i = -(int)radius_x; i <= (int)radius_x; ++i) { auto color_at_px = get_pixel_function(clamp(i, 0, width - 1), y); sum_red += red_value(color_at_px); sum_green += green_value(color_at_px); @@ -81,13 +87,13 @@ void FastBoxBlurFilter::apply_single_pass(size_t radius) } // Slide horizontally for (int x = 0; x < width; ++x) { - intermediate_red[y * width + x] = (sum_red / div); - intermediate_green[y * width + x] = (sum_green / div); - intermediate_blue[y * width + x] = (sum_blue / div); - intermediate_alpha[y * width + x] = (sum_alpha / div); + intermediate_red[y * width + x] = (sum_red / div_x); + intermediate_green[y * width + x] = (sum_green / div_x); + intermediate_blue[y * width + x] = (sum_blue / div_x); + intermediate_alpha[y * width + x] = (sum_alpha / div_x); - auto leftmost_x_coord = max(x - (int)radius, 0); - auto rightmost_x_coord = min(x + (int)radius + 1, width - 1); + auto leftmost_x_coord = max(x - (int)radius_x, 0); + auto rightmost_x_coord = min(x + (int)radius_x + 1, width - 1); auto leftmost_x_color = get_pixel_function(leftmost_x_coord, y); auto rightmost_x_color = get_pixel_function(rightmost_x_coord, y); @@ -111,7 +117,7 @@ void FastBoxBlurFilter::apply_single_pass(size_t radius) size_t sum_alpha = 0; // Setup sliding window - for (int i = -(int)radius; i <= (int)radius; ++i) { + for (int i = -(int)radius_y; i <= (int)radius_y; ++i) { int offset = clamp(i, 0, height - 1) * width + x; sum_red += intermediate_red[offset]; sum_green += intermediate_green[offset]; @@ -121,15 +127,15 @@ void FastBoxBlurFilter::apply_single_pass(size_t radius) for (int y = 0; y < height; ++y) { auto color = Color( - sum_red / div, - sum_green / div, - sum_blue / div, - sum_alpha / div); + sum_red / div_y, + sum_green / div_y, + sum_blue / div_y, + sum_alpha / div_y); set_pixel_function(x, y, color); - auto topmost_y_coord = max(y - (int)radius, 0); - auto bottommost_y_coord = min(y + (int)radius + 1, height - 1); + auto topmost_y_coord = max(y - (int)radius_y, 0); + auto bottommost_y_coord = min(y + (int)radius_y + 1, height - 1); sum_red += intermediate_red[x + bottommost_y_coord * width]; sum_red -= intermediate_red[x + topmost_y_coord * width]; diff --git a/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.h b/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.h index 57a6fd9c78..3536776298 100644 --- a/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.h +++ b/Userland/Libraries/LibGfx/Filters/FastBoxBlurFilter.h @@ -15,6 +15,8 @@ public: FastBoxBlurFilter(Bitmap&); void apply_single_pass(size_t radius); + void apply_single_pass(size_t radius_x, size_t radius_y); + void apply_three_passes(size_t radius); private: