Blame view

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