diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp index 3d10326e3..b7ed8a3c6 100644 --- a/include/mapnik/image_filter.hpp +++ b/include/mapnik/image_filter.hpp @@ -142,6 +142,26 @@ boost::gil::rgba8_view_t rgba8_view(Image & img) img.width() * sizeof(rgba8_pixel_t)); } +namespace detail { + +template +inline void premultiply_alpha( T & dst) +{ + auto alpha = dst[3]; + if (alpha < 255) + { + if (alpha == 0) + { + dst[0] = dst[1] = dst[2] = 0; + } + dst[0] = (dst[0] * alpha + 255) >> 8; + dst[1] = (dst[1] * alpha + 255) >> 8; + dst[2] = (dst[2] * alpha + 255) >> 8; + } +} + +} + template struct double_buffer { @@ -284,13 +304,13 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi p[8] = src_loc[loc22][i]; } - p[0] = p[6]; p[1] = p[7]; p[2] = p[8]; process_channel(p, (*dst_it)[i], filter); } + detail::premultiply_alpha(*dst_it); ++src_loc.x(); ++dst_it; } @@ -338,6 +358,8 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi } process_channel(p, (*dst_it)[i], filter); } + + detail::premultiply_alpha(*dst_it); ++dst_it; ++src_loc.x(); } @@ -383,9 +405,9 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi p[6] = p[0]; p[7] = p[1]; p[8] = p[2]; - process_channel(p, (*dst_it)[i], filter); } + detail::premultiply_alpha(*dst_it); ++src_loc.x(); ++dst_it; }