premultiply.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. Copyright 2014
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. /*************************************************************************************************/
  8. #ifndef BOOST_GIL_PREMULTIPLY_HPP
  9. #define BOOST_GIL_PREMULTIPLY_HPP
  10. #include <iostream>
  11. #include <boost/gil/rgba.hpp>
  12. #include <boost/mpl/remove.hpp>
  13. namespace boost { namespace gil {
  14. template <typename SrcP, typename DstP>
  15. struct channel_premultiply {
  16. channel_premultiply (SrcP const & src, DstP & dst)
  17. : src_ (src), dst_ (dst)
  18. {}
  19. template <typename Channel>
  20. void operator () (Channel c) const {
  21. // @todo: need to do a “channel_convert” too, in case the channel types aren't the same?
  22. get_color (dst_, Channel()) = channel_multiply(get_color(src_,Channel()), alpha_or_max(src_));
  23. }
  24. SrcP const & src_;
  25. DstP & dst_;
  26. };
  27. namespace detail
  28. {
  29. template <typename SrcP, typename DstP>
  30. void assign_alpha_if(mpl::true_, SrcP const &src, DstP &dst)
  31. {
  32. get_color (dst,alpha_t()) = alpha_or_max (src);
  33. };
  34. template <typename SrcP, typename DstP>
  35. void assign_alpha_if(mpl::false_, SrcP const &src, DstP &dst)
  36. {
  37. // nothing to do
  38. };
  39. }
  40. struct premultiply {
  41. template <typename SrcP, typename DstP>
  42. void operator()(const SrcP& src, DstP& dst) const {
  43. typedef typename color_space_type<SrcP>::type src_colour_space_t;
  44. typedef typename color_space_type<DstP>::type dst_colour_space_t;
  45. typedef typename mpl:: remove <src_colour_space_t, alpha_t>:: type src_colour_channels;
  46. typedef mpl::bool_<mpl::contains<dst_colour_space_t, alpha_t>::value> has_alpha_t;
  47. mpl:: for_each <src_colour_channels> ( channel_premultiply <SrcP, DstP> (src, dst) );
  48. detail::assign_alpha_if(has_alpha_t(), src, dst);
  49. }
  50. };
  51. template <typename SrcConstRefP, // const reference to the source pixel
  52. typename DstP> // Destination pixel value (models PixelValueConcept)
  53. class premultiply_deref_fn {
  54. public:
  55. typedef premultiply_deref_fn const_t;
  56. typedef DstP value_type;
  57. typedef value_type reference; // read-only dereferencing
  58. typedef const value_type& const_reference;
  59. typedef SrcConstRefP argument_type;
  60. typedef reference result_type;
  61. BOOST_STATIC_CONSTANT(bool, is_mutable=false);
  62. result_type operator()(argument_type srcP) const {
  63. result_type dstP;
  64. premultiply () (srcP,dstP);
  65. return dstP;
  66. }
  67. };
  68. template <typename SrcView, typename DstP>
  69. struct premultiplied_view_type {
  70. private:
  71. typedef typename SrcView::const_t::reference src_pix_ref; // const reference to pixel in SrcView
  72. typedef premultiply_deref_fn<src_pix_ref, DstP> deref_t; // the dereference adaptor that performs color conversion
  73. typedef typename SrcView::template add_deref<deref_t> add_ref_t;
  74. public:
  75. typedef typename add_ref_t::type type; // the color converted view type
  76. static type make(const SrcView& sv) { return add_ref_t::make(sv, deref_t()); }
  77. };
  78. template <typename DstP, typename View> inline
  79. typename premultiplied_view_type<View,DstP>::type premultiply_view(const View& src) {
  80. return premultiplied_view_type<View,DstP>::make(src);
  81. }
  82. }
  83. }
  84. #endif // BOOST_GIL_PREMULTIPLY_HPP