From 8af02fc8b3d51e2e095eeaea6f38cab0858d2a66 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 2 Oct 2020 16:16:18 -0600 Subject: [PATCH] LibGfx: Move filters from PixelPaint into LibGfx This allows re-using the same filters outside of PixelPaint. --- Applications/PixelPaint/CMakeLists.txt | 6 - .../PixelPaint/Filters/BoxBlurFilter.cpp | 48 -------- Applications/PixelPaint/Filters/Filter.cpp | 39 ------- .../Filters/GenericConvolutionFilter.cpp | 103 ------------------ .../PixelPaint/Filters/LaplacianFilter.cpp | 39 ------- .../PixelPaint/Filters/SharpenFilter.cpp | 40 ------- .../Filters/SpatialGaussianBlurFilter.cpp | 44 -------- Applications/PixelPaint/main.cpp | 32 +++--- .../LibGfx}/Filters/BoxBlurFilter.h | 6 +- .../LibGfx}/Filters/Filter.h | 21 ++-- .../Filters/GenericConvolutionFilter.h | 63 ++++++++++- .../LibGfx}/Filters/LaplacianFilter.h | 6 +- .../LibGfx}/Filters/SharpenFilter.h | 6 +- .../Filters/SpatialGaussianBlurFilter.h | 6 +- 14 files changed, 96 insertions(+), 363 deletions(-) delete mode 100644 Applications/PixelPaint/Filters/BoxBlurFilter.cpp delete mode 100644 Applications/PixelPaint/Filters/Filter.cpp delete mode 100644 Applications/PixelPaint/Filters/GenericConvolutionFilter.cpp delete mode 100644 Applications/PixelPaint/Filters/LaplacianFilter.cpp delete mode 100644 Applications/PixelPaint/Filters/SharpenFilter.cpp delete mode 100644 Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.cpp rename {Applications/PixelPaint => Libraries/LibGfx}/Filters/BoxBlurFilter.h (95%) rename {Applications/PixelPaint => Libraries/LibGfx}/Filters/Filter.h (81%) rename {Applications/PixelPaint => Libraries/LibGfx}/Filters/GenericConvolutionFilter.h (53%) rename {Applications/PixelPaint => Libraries/LibGfx}/Filters/LaplacianFilter.h (95%) rename {Applications/PixelPaint => Libraries/LibGfx}/Filters/SharpenFilter.h (95%) rename {Applications/PixelPaint => Libraries/LibGfx}/Filters/SpatialGaussianBlurFilter.h (94%) diff --git a/Applications/PixelPaint/CMakeLists.txt b/Applications/PixelPaint/CMakeLists.txt index 3fb7752ca8..52c55e48b0 100644 --- a/Applications/PixelPaint/CMakeLists.txt +++ b/Applications/PixelPaint/CMakeLists.txt @@ -3,12 +3,6 @@ set(SOURCES CreateNewLayerDialog.cpp EllipseTool.cpp EraseTool.cpp - Filters/BoxBlurFilter.cpp - Filters/Filter.cpp - Filters/GenericConvolutionFilter.cpp - Filters/LaplacianFilter.cpp - Filters/SharpenFilter.cpp - Filters/SpatialGaussianBlurFilter.cpp Image.cpp ImageEditor.cpp Layer.cpp diff --git a/Applications/PixelPaint/Filters/BoxBlurFilter.cpp b/Applications/PixelPaint/Filters/BoxBlurFilter.cpp deleted file mode 100644 index ad86dd91b6..0000000000 --- a/Applications/PixelPaint/Filters/BoxBlurFilter.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "BoxBlurFilter.h" -#include -#include -#include -#include - -namespace PixelPaint { - -template -BoxBlurFilter::BoxBlurFilter() -{ -} - -template -BoxBlurFilter::~BoxBlurFilter() -{ -} - -} - -template class PixelPaint::BoxBlurFilter<3>; -template class PixelPaint::BoxBlurFilter<5>; diff --git a/Applications/PixelPaint/Filters/Filter.cpp b/Applications/PixelPaint/Filters/Filter.cpp deleted file mode 100644 index cd21c604e4..0000000000 --- a/Applications/PixelPaint/Filters/Filter.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "Filter.h" - -namespace PixelPaint { - -Filter::Filter() -{ -} - -Filter::~Filter() -{ -} - -} diff --git a/Applications/PixelPaint/Filters/GenericConvolutionFilter.cpp b/Applications/PixelPaint/Filters/GenericConvolutionFilter.cpp deleted file mode 100644 index af5a2bf299..0000000000 --- a/Applications/PixelPaint/Filters/GenericConvolutionFilter.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "GenericConvolutionFilter.h" -#include -#include - -namespace PixelPaint { - -template -GenericConvolutionFilter::GenericConvolutionFilter() -{ -} - -template -GenericConvolutionFilter::~GenericConvolutionFilter() -{ -} - -template -void GenericConvolutionFilter::apply(const Filter::Parameters& parameters) -{ - ASSERT(parameters.is_generic_convolution_filter()); - - auto& gcf_params = static_cast(parameters); - - auto& source = gcf_params.bitmap(); - const auto& source_rect = gcf_params.rect(); - auto target = Gfx::Bitmap::create(source.format(), parameters.rect().size()); - - // FIXME: Help! I am naive! - for (auto i_ = 0; i_ < source_rect.width(); ++i_) { - auto i = i_ + source_rect.x(); - for (auto j_ = 0; j_ < source_rect.height(); ++j_) { - auto j = j_ + source_rect.y(); - FloatVector3 value(0, 0, 0); - for (auto k = 0; k < 4; ++k) { - auto ki = i + k - 2; - if (ki < 0 || ki >= source.size().width()) { - if (gcf_params.should_wrap()) - ki = (ki + source.size().width()) % source.size().width(); - else - continue; - } - - for (auto l = 0; l < 4; ++l) { - auto lj = j + l - 2; - if (lj < 0 || lj >= source.size().height()) { - if (gcf_params.should_wrap()) - lj = (lj + source.size().height()) % source.size().height(); - else - continue; - } - - auto pixel = source.get_pixel(ki, lj); - FloatVector3 pixel_value(pixel.red(), pixel.green(), pixel.blue()); - - value = value + pixel_value * gcf_params.kernel().elements()[k][l]; - } - } - - // The float->u8 overflow is intentional. - target->set_pixel(i_, j_, Color(value.x(), value.y(), value.z(), source.get_pixel(i, j).alpha())); - } - } - - // FIXME: Substitute for some sort of faster "blit" method. - for (auto i_ = 0; i_ < source_rect.width(); ++i_) { - auto i = i_ + source_rect.x(); - for (auto j_ = 0; j_ < source_rect.height(); ++j_) { - auto j = j_ + source_rect.y(); - source.set_pixel(i, j, target->get_pixel(i_, j_)); - } - } -} - -} - -template class PixelPaint::GenericConvolutionFilter<3>; -template class PixelPaint::GenericConvolutionFilter<5>; diff --git a/Applications/PixelPaint/Filters/LaplacianFilter.cpp b/Applications/PixelPaint/Filters/LaplacianFilter.cpp deleted file mode 100644 index 6a1af5c768..0000000000 --- a/Applications/PixelPaint/Filters/LaplacianFilter.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "LaplacianFilter.h" - -namespace PixelPaint { - -LaplacianFilter::LaplacianFilter() -{ -} - -LaplacianFilter::~LaplacianFilter() -{ -} - -} diff --git a/Applications/PixelPaint/Filters/SharpenFilter.cpp b/Applications/PixelPaint/Filters/SharpenFilter.cpp deleted file mode 100644 index 7ee17b1cd3..0000000000 --- a/Applications/PixelPaint/Filters/SharpenFilter.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SharpenFilter.h" -#include "../ImageEditor.h" - -namespace PixelPaint { - -SharpenFilter::SharpenFilter() -{ -} - -SharpenFilter::~SharpenFilter() -{ -} - -} diff --git a/Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.cpp b/Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.cpp deleted file mode 100644 index b4743951aa..0000000000 --- a/Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SpatialGaussianBlurFilter.h" - -namespace PixelPaint { - -template -SpatialGaussianBlurFilter::SpatialGaussianBlurFilter() -{ -} - -template -SpatialGaussianBlurFilter::~SpatialGaussianBlurFilter() -{ -} - -} - -template class PixelPaint::SpatialGaussianBlurFilter<3>; -template class PixelPaint::SpatialGaussianBlurFilter<5>; diff --git a/Applications/PixelPaint/main.cpp b/Applications/PixelPaint/main.cpp index 15b1227c27..217cde513e 100644 --- a/Applications/PixelPaint/main.cpp +++ b/Applications/PixelPaint/main.cpp @@ -218,51 +218,51 @@ int main(int argc, char** argv) auto& edge_detect_submenu = spatial_filters_menu.add_submenu("Edge Detect"); edge_detect_submenu.add_action(GUI::Action::create("Laplacian (cardinal)", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::LaplacianFilter filter; - if (auto parameters = PixelPaint::FilterParameters::get(layer->bitmap(), layer->rect(), false)) + Gfx::LaplacianFilter filter; + if (auto parameters = PixelPaint::FilterParameters::get(layer->bitmap(), layer->rect(), false)) filter.apply(*parameters); } })); edge_detect_submenu.add_action(GUI::Action::create("Laplacian (diagonal)", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::LaplacianFilter filter; - if (auto parameters = PixelPaint::FilterParameters::get(layer->bitmap(), layer->rect(), true)) + Gfx::LaplacianFilter filter; + if (auto parameters = PixelPaint::FilterParameters::get(layer->bitmap(), layer->rect(), true)) filter.apply(*parameters); } })); auto& blur_submenu = spatial_filters_menu.add_submenu("Blur and Sharpen"); blur_submenu.add_action(GUI::Action::create("Gaussian Blur (3x3)", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::SpatialGaussianBlurFilter<3> filter; - if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) + Gfx::SpatialGaussianBlurFilter<3> filter; + if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) filter.apply(*parameters); } })); blur_submenu.add_action(GUI::Action::create("Gaussian Blur (5x5)", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::SpatialGaussianBlurFilter<5> filter; - if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) + Gfx::SpatialGaussianBlurFilter<5> filter; + if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) filter.apply(*parameters); } })); blur_submenu.add_action(GUI::Action::create("Box Blur (3x3)", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::BoxBlurFilter<3> filter; - if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) + Gfx::BoxBlurFilter<3> filter; + if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) filter.apply(*parameters); } })); blur_submenu.add_action(GUI::Action::create("Box Blur (5x5)", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::BoxBlurFilter<5> filter; - if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) + Gfx::BoxBlurFilter<5> filter; + if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect())) filter.apply(*parameters); } })); blur_submenu.add_action(GUI::Action::create("Sharpen", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::SharpenFilter filter; - if (auto parameters = PixelPaint::FilterParameters::get(layer->bitmap(), layer->rect())) + Gfx::SharpenFilter filter; + if (auto parameters = PixelPaint::FilterParameters::get(layer->bitmap(), layer->rect())) filter.apply(*parameters); } })); @@ -270,8 +270,8 @@ int main(int argc, char** argv) spatial_filters_menu.add_separator(); spatial_filters_menu.add_action(GUI::Action::create("Generic 5x5 Convolution", [&](auto&) { if (auto* layer = image_editor.active_layer()) { - PixelPaint::GenericConvolutionFilter<5> filter; - if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect(), window)) + Gfx::GenericConvolutionFilter<5> filter; + if (auto parameters = PixelPaint::FilterParameters>::get(layer->bitmap(), layer->rect(), window)) filter.apply(*parameters); } })); diff --git a/Applications/PixelPaint/Filters/BoxBlurFilter.h b/Libraries/LibGfx/Filters/BoxBlurFilter.h similarity index 95% rename from Applications/PixelPaint/Filters/BoxBlurFilter.h rename to Libraries/LibGfx/Filters/BoxBlurFilter.h index 9e243c3ef8..8be43befe1 100644 --- a/Applications/PixelPaint/Filters/BoxBlurFilter.h +++ b/Libraries/LibGfx/Filters/BoxBlurFilter.h @@ -28,13 +28,13 @@ #include "GenericConvolutionFilter.h" -namespace PixelPaint { +namespace Gfx { template class BoxBlurFilter : public GenericConvolutionFilter { public: - BoxBlurFilter(); - virtual ~BoxBlurFilter(); + BoxBlurFilter() { } + virtual ~BoxBlurFilter() { } virtual const char* class_name() const override { return "BoxBlurFilter"; } }; diff --git a/Applications/PixelPaint/Filters/Filter.h b/Libraries/LibGfx/Filters/Filter.h similarity index 81% rename from Applications/PixelPaint/Filters/Filter.h rename to Libraries/LibGfx/Filters/Filter.h index b780751545..617ac6877f 100644 --- a/Applications/PixelPaint/Filters/Filter.h +++ b/Libraries/LibGfx/Filters/Filter.h @@ -26,41 +26,40 @@ #pragma once -#include -#include -#include +#include +#include -namespace PixelPaint { +namespace Gfx { class Filter { public: class Parameters { public: - Parameters(Gfx::Bitmap& bitmap, const Gfx::IntRect& rect) + Parameters(Bitmap& bitmap, const IntRect& rect) : m_target_bitmap(bitmap) , m_target_rect(rect) { } - Gfx::Bitmap& bitmap() const { return m_target_bitmap; } - const Gfx::IntRect& rect() const { return m_target_rect; } + Bitmap& bitmap() const { return m_target_bitmap; } + const IntRect& rect() const { return m_target_rect; } virtual bool is_generic_convolution_filter() const { return false; } virtual ~Parameters() { } private: - Gfx::Bitmap& m_target_bitmap; - Gfx::IntRect m_target_rect; + Bitmap& m_target_bitmap; + IntRect m_target_rect; }; - virtual ~Filter(); + virtual ~Filter() { } virtual const char* class_name() const = 0; virtual void apply(const Parameters&) = 0; protected: - Filter(); + Filter() { } }; } diff --git a/Applications/PixelPaint/Filters/GenericConvolutionFilter.h b/Libraries/LibGfx/Filters/GenericConvolutionFilter.h similarity index 53% rename from Applications/PixelPaint/Filters/GenericConvolutionFilter.h rename to Libraries/LibGfx/Filters/GenericConvolutionFilter.h index bd538f7d43..831773da14 100644 --- a/Applications/PixelPaint/Filters/GenericConvolutionFilter.h +++ b/Libraries/LibGfx/Filters/GenericConvolutionFilter.h @@ -27,11 +27,10 @@ #pragma once #include "Filter.h" -#include #include #include -namespace PixelPaint { +namespace Gfx { template inline static constexpr void normalize(Matrix& matrix) @@ -72,12 +71,66 @@ public: bool m_should_wrap { false }; }; - GenericConvolutionFilter(); - virtual ~GenericConvolutionFilter(); + GenericConvolutionFilter() { } + virtual ~GenericConvolutionFilter() { } virtual const char* class_name() const override { return "GenericConvolutionFilter"; } - virtual void apply(const Filter::Parameters&) override; + virtual void apply(const Filter::Parameters& parameters) + { + ASSERT(parameters.is_generic_convolution_filter()); + + auto& gcf_params = static_cast(parameters); + + auto& source = gcf_params.bitmap(); + const auto& source_rect = gcf_params.rect(); + auto target = Gfx::Bitmap::create(source.format(), parameters.rect().size()); + + // FIXME: Help! I am naive! + for (auto i_ = 0; i_ < source_rect.width(); ++i_) { + auto i = i_ + source_rect.x(); + for (auto j_ = 0; j_ < source_rect.height(); ++j_) { + auto j = j_ + source_rect.y(); + FloatVector3 value(0, 0, 0); + for (auto k = 0; k < 4; ++k) { + auto ki = i + k - 2; + if (ki < 0 || ki >= source.size().width()) { + if (gcf_params.should_wrap()) + ki = (ki + source.size().width()) % source.size().width(); + else + continue; + } + + for (auto l = 0; l < 4; ++l) { + auto lj = j + l - 2; + if (lj < 0 || lj >= source.size().height()) { + if (gcf_params.should_wrap()) + lj = (lj + source.size().height()) % source.size().height(); + else + continue; + } + + auto pixel = source.get_pixel(ki, lj); + FloatVector3 pixel_value(pixel.red(), pixel.green(), pixel.blue()); + + value = value + pixel_value * gcf_params.kernel().elements()[k][l]; + } + } + + // The float->u8 overflow is intentional. + target->set_pixel(i_, j_, Color(value.x(), value.y(), value.z(), source.get_pixel(i, j).alpha())); + } + } + + // FIXME: Substitute for some sort of faster "blit" method. + for (auto i_ = 0; i_ < source_rect.width(); ++i_) { + auto i = i_ + source_rect.x(); + for (auto j_ = 0; j_ < source_rect.height(); ++j_) { + auto j = j_ + source_rect.y(); + source.set_pixel(i, j, target->get_pixel(i_, j_)); + } + } + } }; } diff --git a/Applications/PixelPaint/Filters/LaplacianFilter.h b/Libraries/LibGfx/Filters/LaplacianFilter.h similarity index 95% rename from Applications/PixelPaint/Filters/LaplacianFilter.h rename to Libraries/LibGfx/Filters/LaplacianFilter.h index b0d838caeb..fe1c247582 100644 --- a/Applications/PixelPaint/Filters/LaplacianFilter.h +++ b/Libraries/LibGfx/Filters/LaplacianFilter.h @@ -28,12 +28,12 @@ #include "GenericConvolutionFilter.h" -namespace PixelPaint { +namespace Gfx { class LaplacianFilter : public GenericConvolutionFilter<3> { public: - LaplacianFilter(); - virtual ~LaplacianFilter(); + LaplacianFilter() { } + virtual ~LaplacianFilter() { } virtual const char* class_name() const override { return "LaplacianFilter"; } }; diff --git a/Applications/PixelPaint/Filters/SharpenFilter.h b/Libraries/LibGfx/Filters/SharpenFilter.h similarity index 95% rename from Applications/PixelPaint/Filters/SharpenFilter.h rename to Libraries/LibGfx/Filters/SharpenFilter.h index 7581e4c2ee..25456aa691 100644 --- a/Applications/PixelPaint/Filters/SharpenFilter.h +++ b/Libraries/LibGfx/Filters/SharpenFilter.h @@ -28,12 +28,12 @@ #include "GenericConvolutionFilter.h" -namespace PixelPaint { +namespace Gfx { class SharpenFilter : public GenericConvolutionFilter<3> { public: - SharpenFilter(); - virtual ~SharpenFilter(); + SharpenFilter() { } + virtual ~SharpenFilter() { } virtual const char* class_name() const override { return "SharpenFilter"; } }; diff --git a/Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.h b/Libraries/LibGfx/Filters/SpatialGaussianBlurFilter.h similarity index 94% rename from Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.h rename to Libraries/LibGfx/Filters/SpatialGaussianBlurFilter.h index bb774cc75e..8bf8d414ca 100644 --- a/Applications/PixelPaint/Filters/SpatialGaussianBlurFilter.h +++ b/Libraries/LibGfx/Filters/SpatialGaussianBlurFilter.h @@ -29,13 +29,13 @@ #include "GenericConvolutionFilter.h" #include -namespace PixelPaint { +namespace Gfx { template::Type> class SpatialGaussianBlurFilter : public GenericConvolutionFilter { public: - SpatialGaussianBlurFilter(); - virtual ~SpatialGaussianBlurFilter(); + SpatialGaussianBlurFilter() { } + virtual ~SpatialGaussianBlurFilter() { } virtual const char* class_name() const override { return "SpatialGaussianBlurFilter"; } };