Boost GIL


premultiply.hpp
1 //
2 // Copyright 2014 Bill Gallafent
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #ifndef BOOST_GIL_PREMULTIPLY_HPP
9 #define BOOST_GIL_PREMULTIPLY_HPP
10 
11 #include <boost/gil/rgba.hpp>
12 
13 #include <boost/core/ignore_unused.hpp>
14 #include <boost/mpl/for_each.hpp>
15 #include <boost/mpl/remove.hpp>
16 
17 namespace boost { namespace gil {
18 
19 template <typename SrcP, typename DstP>
20 struct channel_premultiply
21 {
22  channel_premultiply(SrcP const & src, DstP & dst)
23  : src_(src), dst_(dst)
24  {}
25 
26  template <typename Channel>
27  void operator()(Channel /* channel */) const
28  {
29  // TODO: Explain why 'channel' input paramater is not used, or used as tag only.
30 
31  // @todo: need to do a "channel_convert" too, in case the channel types aren't the same?
32  get_color(dst_, Channel()) = channel_multiply(get_color(src_,Channel()), alpha_or_max(src_));
33  }
34  SrcP const & src_;
35  DstP & dst_;
36 };
37 
38 namespace detail
39 {
40  template <typename SrcP, typename DstP>
41  void assign_alpha_if(mpl::true_, SrcP const &src, DstP &dst)
42  {
43  get_color(dst,alpha_t()) = alpha_or_max(src);
44  }
45 
46  template <typename SrcP, typename DstP>
47  void assign_alpha_if(mpl::false_, SrcP const& src, DstP& dst)
48  {
49  // nothing to do
50  boost::ignore_unused(src);
51  boost::ignore_unused(dst);
52  }
53 }
54 
55 struct premultiply
56 {
57  template <typename SrcP, typename DstP>
58  void operator()(const SrcP& src, DstP& dst) const
59  {
60  using src_colour_space_t = typename color_space_type<SrcP>::type;
61  using dst_colour_space_t = typename color_space_type<DstP>::type;
62  using src_colour_channels = typename mpl::remove <src_colour_space_t, alpha_t>::type;
63 
64  using has_alpha_t = mpl::bool_<mpl::contains<dst_colour_space_t, alpha_t>::value>;
65  mpl::for_each<src_colour_channels>(channel_premultiply<SrcP, DstP>(src, dst));
66  detail::assign_alpha_if(has_alpha_t(), src, dst);
67  }
68 };
69 
70 template <typename SrcConstRefP, // const reference to the source pixel
71  typename DstP> // Destination pixel value (models PixelValueConcept)
72 class premultiply_deref_fn
73 {
74 public:
75  using const_t = premultiply_deref_fn<SrcConstRefP, DstP>;
76  using value_type = DstP;
77  using reference = value_type; // read-only dereferencing
78  using const_reference = const value_type &;
79  using argument_type = SrcConstRefP;
80  using result_type = reference;
81  static constexpr bool is_mutable = false;
82 
83  result_type operator()(argument_type srcP) const
84  {
85  result_type dstP;
86  premultiply()(srcP,dstP);
87  return dstP;
88  }
89 };
90 
91 template <typename SrcView, typename DstP>
92 struct premultiplied_view_type
93 {
94 private:
95  using src_pix_ref = typename SrcView::const_t::reference; // const reference to pixel in SrcView
96  using deref_t = premultiply_deref_fn<src_pix_ref, DstP>; // the dereference adaptor that performs color conversion
97  using add_ref_t = typename SrcView::template add_deref<deref_t>;
98 public:
99  using type = typename add_ref_t::type; // the color converted view type
100  static type make(const SrcView& sv) { return add_ref_t::make(sv, deref_t()); }
101 };
102 
103 template <typename DstP, typename View> inline
104 typename premultiplied_view_type<View,DstP>::type premultiply_view(const View& src)
105 {
106  return premultiplied_view_type<View,DstP>::make(src);
107 }
108 
109 }} // namespace boost::gil
110 
111 #endif
Definition: algorithm.hpp:30
channel_traits< Channel >::value_type channel_multiply(Channel a, Channel b)
A function multiplying two channels. result = a * b / max_value.
Definition: channel_algorithm.hpp:485
color_element_reference_type< ColorBase, Color >::type get_color(ColorBase &cb, Color=Color())
Mutable accessor to the element associated with a given color name.
Definition: color_base_algorithm.hpp:193