From 86785a5923c93224fed90bd78c4d6568577962f5 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Wed, 23 Sep 2020 20:46:03 +0300 Subject: [PATCH] Improve color blur implementation --- libs/pcg/include/psemek/pcg/blur.hpp | 18 +++++++++++++++--- libs/pcg/source/blur.cpp | 16 ++++++++++------ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/libs/pcg/include/psemek/pcg/blur.hpp b/libs/pcg/include/psemek/pcg/blur.hpp index f27bc494..47fde7c6 100644 --- a/libs/pcg/include/psemek/pcg/blur.hpp +++ b/libs/pcg/include/psemek/pcg/blur.hpp @@ -2,8 +2,10 @@ #include #include +#include #include +#include namespace psemek::pcg { @@ -15,17 +17,20 @@ namespace psemek::pcg } - template - gfx::basic_pixmap blur(gfx::basic_pixmap const & p, int size, float sigma, seamless_tag) + template + gfx::basic_pixmap blur(gfx::basic_pixmap const & p, To && to, From && from, int size, float sigma, seamless_tag) { gfx::basic_pixmap res({p.width(), p.height()}, T{}); + using R = std::decay_t; + auto c = detail::gauss_coeffs(size, sigma); for (std::size_t y = 0; y < p.height(); ++y) { for (std::size_t x = 0; x < p.width(); ++x) { + auto v = R{}; for (int j = - size; j <= size; ++j) { for (int i = - size; i <= size; ++i) @@ -38,15 +43,22 @@ namespace psemek::pcg while (iy < 0) iy += p.height(); if (static_cast(iy) >= p.height()) iy = iy % p.height(); - res(x, y) += p(ix, iy) * c[i + size] * c[j + size]; + v += to(p(ix, iy)) * c[i + size] * c[j + size]; } } + res(x, y) = from(v); } } return res; } + template + gfx::basic_pixmap blur(gfx::basic_pixmap const & p, int size, float sigma, seamless_tag) + { + return blur(p, util::id, util::id, size, sigma, seamless); + } + gfx::pixmap_rgb blur(gfx::pixmap_rgb const & p, int size, float sigma, seamless_tag); gfx::pixmap_rgba blur(gfx::pixmap_rgba const & p, int size, float sigma, seamless_tag); diff --git a/libs/pcg/source/blur.cpp b/libs/pcg/source/blur.cpp index 56f59ca5..68858944 100644 --- a/libs/pcg/source/blur.cpp +++ b/libs/pcg/source/blur.cpp @@ -27,18 +27,22 @@ namespace psemek::pcg } + template + auto color_blur_impl(gfx::basic_pixmap const & p, int size, float sigma, seamless_tag) + { + auto to = [](auto const & c){ return gfx::to_colorf(c); }; + auto from = [](auto const & c){ return gfx::to_coloru8(c); }; + return blur(p, to, from, size, sigma, seamless); + } + gfx::pixmap_rgb blur(gfx::pixmap_rgb const & p, int size, float sigma, seamless_tag) { - auto converted = util::map([](gfx::color_rgb const & c){ return gfx::to_colorf(c); }, p); - converted = blur(converted, size, sigma, seamless); - return util::map([](geom::vector const & c){ return gfx::to_coloru8(c); }, converted); + return color_blur_impl(p, size, sigma, seamless); } gfx::pixmap_rgba blur(gfx::pixmap_rgba const & p, int size, float sigma, seamless_tag) { - auto converted = util::map([](gfx::color_rgba const & c){ return gfx::to_colorf(c); }, p); - converted = blur(converted, size, sigma, seamless); - return util::map([](geom::vector const & c){ return gfx::to_coloru8(c); }, converted); + return color_blur_impl(p, size, sigma, seamless); } }