Boost GIL


utilities.hpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
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_UTILITIES_HPP
9 #define BOOST_GIL_UTILITIES_HPP
10 
11 #include <boost/mpl/begin.hpp>
12 #include <boost/mpl/contains.hpp>
13 #include <boost/mpl/distance.hpp>
14 #include <boost/mpl/find.hpp>
15 #include <boost/mpl/range_c.hpp>
16 #include <boost/mpl/size.hpp>
17 #include <boost/iterator/iterator_adaptor.hpp>
18 #include <boost/iterator/iterator_facade.hpp>
19 #include <boost/type_traits.hpp>
20 
21 #include <algorithm>
22 #include <cmath>
23 #include <cstddef>
24 #include <functional>
25 #include <iterator>
26 #include <utility>
27 
28 namespace boost { namespace gil {
29 
32 
36 
37 inline std::ptrdiff_t iround(float x)
38 {
39  return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f));
40 }
41 
42 inline std::ptrdiff_t iround(double x)
43 {
44  return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5));
45 }
46 
47 inline std::ptrdiff_t ifloor(float x)
48 {
49  return static_cast<std::ptrdiff_t>(std::floor(x));
50 }
51 
52 inline std::ptrdiff_t ifloor(double x)
53 {
54  return static_cast<std::ptrdiff_t>(std::floor(x));
55 }
56 
57 inline std::ptrdiff_t iceil(float x)
58 {
59  return static_cast<std::ptrdiff_t>(std::ceil(x));
60 }
61 
62 inline std::ptrdiff_t iceil(double x)
63 {
64  return static_cast<std::ptrdiff_t>(std::ceil(x));
65 }
66 
70 
71 template <typename T>
72 inline T align(T val, std::size_t alignment)
73 {
74  return val+(alignment - val%alignment)%alignment;
75 }
76 
80 template
81 <
82  typename ConstT,
83  typename Value,
84  typename Reference,
85  typename ConstReference,
86  typename ArgType,
87  typename ResultType,
88  bool IsMutable
89 >
90 struct deref_base
91 {
92  using argument_type = ArgType;
93  using result_type = ResultType;
94  using const_t = ConstT;
95  using value_type = Value;
96  using reference = Reference;
97  using const_reference = ConstReference;
98  static constexpr bool is_mutable = IsMutable;
99 };
100 
104 template <typename D1, typename D2>
105 class deref_compose : public deref_base
106 <
107  deref_compose<typename D1::const_t, typename D2::const_t>,
108  typename D1::value_type,
109  typename D1::reference,
110  typename D1::const_reference,
111  typename D2::argument_type,
112  typename D1::result_type,
113  D1::is_mutable && D2::is_mutable
114 >
115 {
116 public:
117  D1 _fn1;
118  D2 _fn2;
119 
120  using argument_type = typename D2::argument_type;
121  using result_type = typename D1::result_type;
122 
123  deref_compose() = default;
124  deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}
125  deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
126 
127  template <typename _D1, typename _D2>
129  : _fn1(dc._fn1), _fn2(dc._fn2)
130  {}
131 
132  result_type operator()(argument_type x) const { return _fn1(_fn2(x)); }
133  result_type operator()(argument_type x) { return _fn1(_fn2(x)); }
134 };
135 
136 // reinterpret_cast is implementation-defined. Static cast is not.
137 template <typename OutPtr, typename In>
138 BOOST_FORCEINLINE
139 OutPtr gil_reinterpret_cast(In* p)
140 {
141  return static_cast<OutPtr>(static_cast<void*>(p));
142 }
143 
144 template <typename OutPtr, typename In> BOOST_FORCEINLINE
145 const OutPtr gil_reinterpret_cast_c(const In* p)
146 {
147  return static_cast<const OutPtr>(static_cast<const void*>(p));
148 }
149 
150 namespace detail {
151 
155 
156 template <class InputIter, class Size, class OutputIter>
157 std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
158  OutputIter result, std::input_iterator_tag)
159 {
160  for ( ; count > 0; --count)
161  {
162  *result = *first;
163  ++first;
164  ++result;
165  }
166  return std::pair<InputIter, OutputIter>(first, result);
167 }
168 
169 template <class RAIter, class Size, class OutputIter>
170 inline std::pair<RAIter, OutputIter>
171 _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag)
172 {
173  RAIter last = first + count;
174  return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
175 }
176 
177 template <class InputIter, class Size, class OutputIter>
178 inline std::pair<InputIter, OutputIter>
179 _copy_n(InputIter first, Size count, OutputIter result)
180 {
181  return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
182 }
183 
184 template <class InputIter, class Size, class OutputIter>
185 inline std::pair<InputIter, OutputIter>
186 copy_n(InputIter first, Size count, OutputIter result)
187 {
188  return detail::_copy_n(first, count, result);
189 }
190 
192 template <typename T>
193 struct identity
194 {
195  using argument_type = T;
196  using result_type = T;
197  const T& operator()(const T& val) const { return val; }
198 };
199 
201 template <typename T1, typename T2>
203  using first_argument_type = T1;
204  using second_argument_type = T2;
205  using result_type = T1;
206  T1 operator()(T1 f1, T2 f2) const
207  {
208  return f1+f2;
209  }
210 };
211 
213 template <typename T>
214 struct inc
215 {
216  using argument_type = T;
217  using result_type = T;
218  T operator()(T x) const { return ++x; }
219 };
220 
222 template <typename T>
223 struct dec
224 {
225  using argument_type = T;
226  using result_type = T;
227  T operator()(T x) const { return --x; }
228 };
229 
231 // a given MPL RandomAccessSequence (or size if the type is not present)
232 template <typename Types, typename T>
234  : public mpl::distance
235  <
236  typename mpl::begin<Types>::type,
237  typename mpl::find<Types,T>::type
238  >::type
239  {
240  static_assert(mpl::contains<Types, T>::value, "T should be element of Types");
241  };
242 } // namespace detail
243 
246 template <typename ColorSpace, typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value>>
247 struct layout
248 {
249  using color_space_t = ColorSpace;
250  using channel_mapping_t = ChannelMapping;
251 };
252 
254 template <typename Value, typename T1, typename T2> // where value_type<T1> == value_type<T2> == Value
255 void swap_proxy(T1& left, T2& right)
256 {
257  Value tmp = left;
258  left = right;
259  right = tmp;
260 }
261 
263 BOOST_FORCEINLINE bool little_endian()
264 {
265  short tester = 0x0001;
266  return *(char*)&tester!=0;
267 }
269 BOOST_FORCEINLINE bool big_endian()
270 {
271  return !little_endian();
272 }
273 
274 }} // namespace boost::gil
275 
276 #endif
plus function object whose arguments may be of different type.
Definition: utilities.hpp:202
BOOST_FORCEINLINE boost::gil::pixel< T, Cs > * copy(boost::gil::pixel< T, Cs > *first, boost::gil::pixel< T, Cs > *last, boost::gil::pixel< T, Cs > *dst)
Copy when both src and dst are interleaved and of the same type can be just memmove.
Definition: algorithm.hpp:132
Definition: algorithm.hpp:30
Helper base class for pixel dereference adaptors.
Definition: utilities.hpp:90
operator– wrapped in a function object
Definition: utilities.hpp:223
identity taken from SGI STL.
Definition: utilities.hpp:193
operator++ wrapped in a function object
Definition: utilities.hpp:214
Represents a color space and ordering of channels in memory.
Definition: utilities.hpp:247
Composes two dereference function objects. Similar to std::unary_compose but needs to pull some alias...
Definition: utilities.hpp:105
Returns the index corresponding to the first occurrance of a given given type in. ...
Definition: utilities.hpp:233