premultiply R,G,B channels after applying filters

This commit is contained in:
artemp 2014-06-18 19:06:53 +01:00
parent 666a926864
commit 2f15631182

View file

@ -142,6 +142,26 @@ boost::gil::rgba8_view_t rgba8_view(Image & img)
img.width() * sizeof(rgba8_pixel_t)); img.width() * sizeof(rgba8_pixel_t));
} }
namespace detail {
template <typename T>
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 <typename Image> template <typename Image>
struct double_buffer 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[8] = src_loc[loc22][i];
} }
p[0] = p[6]; p[0] = p[6];
p[1] = p[7]; p[1] = p[7];
p[2] = p[8]; p[2] = p[8];
process_channel(p, (*dst_it)[i], filter); process_channel(p, (*dst_it)[i], filter);
} }
detail::premultiply_alpha(*dst_it);
++src_loc.x(); ++src_loc.x();
++dst_it; ++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); process_channel(p, (*dst_it)[i], filter);
} }
detail::premultiply_alpha(*dst_it);
++dst_it; ++dst_it;
++src_loc.x(); ++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[6] = p[0];
p[7] = p[1]; p[7] = p[1];
p[8] = p[2]; p[8] = p[2];
process_channel(p, (*dst_it)[i], filter); process_channel(p, (*dst_it)[i], filter);
} }
detail::premultiply_alpha(*dst_it);
++src_loc.x(); ++src_loc.x();
++dst_it; ++dst_it;
} }