Boost GIL


utility.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3 
4  Use, modification and distribution are subject to the Boost Software License,
5  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6  http://www.boost.org/LICENSE_1_0.txt).
7 
8  See http://opensource.adobe.com/gil for most recent version including documentation.
9 */
10 
11 /*************************************************************************************************/
12 
13 #ifndef BOOST_GIL_UTILITY_HPP
14 #define BOOST_GIL_UTILITY_HPP
15 
16 #include <boost/gil/config.hpp>
17 #include <boost/gil/channel.hpp>
18 #include <boost/gil/pixel.hpp>
19 
20 #include <boost/config/no_tr1/cmath.hpp>
21 #include <boost/iterator/iterator_adaptor.hpp>
22 #include <boost/iterator/iterator_facade.hpp>
23 #include <boost/mpl/begin.hpp>
24 #include <boost/mpl/distance.hpp>
25 #include <boost/mpl/find.hpp>
26 #include <boost/mpl/range_c.hpp>
27 #include <boost/mpl/size.hpp>
28 #include <boost/static_assert.hpp>
29 #include <boost/type_traits.hpp>
30 
31 #include <cstddef>
32 #include <algorithm>
33 #include <functional>
34 #include <iterator>
35 #include <utility>
36 
46 
47 namespace boost { namespace gil {
48 
61 // CLASS point2
69 
70 template <typename T>
71 class point2 {
72 public:
73  typedef T value_type;
74  template <std::size_t D> struct axis { typedef value_type coord_t; };
75  static const std::size_t num_dimensions=2;
76 
77  point2() : x(0), y(0) {}
78  point2(T newX, T newY) : x(newX), y(newY) {}
79  point2(const point2& p) : x(p.x), y(p.y) {}
80  ~point2() {}
81 
82  point2& operator=(const point2& p) { x=p.x; y=p.y; return *this; }
83 
84  point2 operator<<(std::ptrdiff_t shift) const { return point2(x<<shift,y<<shift); }
85  point2 operator>>(std::ptrdiff_t shift) const { return point2(x>>shift,y>>shift); }
86  point2& operator+=(const point2& p) { x+=p.x; y+=p.y; return *this; }
87  point2& operator-=(const point2& p) { x-=p.x; y-=p.y; return *this; }
88  point2& operator/=(double t) { if (t<0 || 0<t) { x/=t; y/=t; } return *this; }
89 
90  const T& operator[](std::size_t i) const { return this->*mem_array[i]; }
91  T& operator[](std::size_t i) { return this->*mem_array[i]; }
92 
93  T x,y;
94 private:
95  // this static array of pointers to member variables makes operator[] safe and doesn't seem to exhibit any performance penalty
96  static T point2<T>::* const mem_array[num_dimensions];
97 };
98 
99 template <typename T>
100 T point2<T>::* const point2<T>::mem_array[point2<T>::num_dimensions] = { &point2<T>::x, &point2<T>::y };
101 
103 template <typename T> BOOST_FORCEINLINE
104 bool operator==(const point2<T>& p1, const point2<T>& p2) { return (p1.x==p2.x && p1.y==p2.y); }
106 template <typename T> BOOST_FORCEINLINE
107 bool operator!=(const point2<T>& p1, const point2<T>& p2) { return p1.x!=p2.x || p1.y!=p2.y; }
109 template <typename T> BOOST_FORCEINLINE
110 point2<T> operator+(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x+p2.x,p1.y+p2.y); }
112 template <typename T> BOOST_FORCEINLINE
113 point2<T> operator-(const point2<T>& p) { return point2<T>(-p.x,-p.y); }
115 template <typename T> BOOST_FORCEINLINE
116 point2<T> operator-(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x-p2.x,p1.y-p2.y); }
118 template <typename T> BOOST_FORCEINLINE
119 point2<double> operator/(const point2<T>& p, double t) { return (t<0 || 0<t) ? point2<double>(p.x/t,p.y/t) : point2<double>(0,0); }
121 template <typename T> BOOST_FORCEINLINE
122 point2<T> operator*(const point2<T>& p, std::ptrdiff_t t) { return point2<T>(p.x*t,p.y*t); }
124 template <typename T> BOOST_FORCEINLINE
125 point2<T> operator*(std::ptrdiff_t t, const point2<T>& p) { return point2<T>(p.x*t,p.y*t); }
126 
128 template <std::size_t K, typename T> BOOST_FORCEINLINE
129 const T& axis_value(const point2<T>& p) { return p[K]; }
130 
132 template <std::size_t K, typename T> BOOST_FORCEINLINE
133  T& axis_value( point2<T>& p) { return p[K]; }
134 
140 
141 inline std::ptrdiff_t iround(float x ) { return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f)); }
142 inline std::ptrdiff_t iround(double x) { return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5)); }
143 inline std::ptrdiff_t ifloor(float x ) { return static_cast<std::ptrdiff_t>(std::floor(x)); }
144 inline std::ptrdiff_t ifloor(double x) { return static_cast<std::ptrdiff_t>(std::floor(x)); }
145 inline std::ptrdiff_t iceil(float x ) { return static_cast<std::ptrdiff_t>(std::ceil(x)); }
146 inline std::ptrdiff_t iceil(double x) { return static_cast<std::ptrdiff_t>(std::ceil(x)); }
147 
157 inline point2<std::ptrdiff_t> iround(const point2<float >& p) { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); }
160 inline point2<std::ptrdiff_t> iround(const point2<double>& p) { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); }
162 inline point2<std::ptrdiff_t> ifloor(const point2<float >& p) { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); }
164 inline point2<std::ptrdiff_t> ifloor(const point2<double>& p) { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); }
166 inline point2<std::ptrdiff_t> iceil (const point2<float >& p) { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); }
168 inline point2<std::ptrdiff_t> iceil (const point2<double>& p) { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); }
169 
175 
176 template <typename T>
177 inline T align(T val, std::size_t alignment) {
178  return val+(alignment - val%alignment)%alignment;
179 }
180 
184 template <typename ConstT, typename Value, typename Reference, typename ConstReference,
185  typename ArgType, typename ResultType, bool IsMutable>
186 struct deref_base {
187  typedef ArgType argument_type;
188  typedef ResultType result_type;
189  typedef ConstT const_t;
190  typedef Value value_type;
191  typedef Reference reference;
192  typedef ConstReference const_reference;
193  BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable);
194 };
195 
199 template <typename D1, typename D2>
200 class deref_compose : public deref_base<
201  deref_compose<typename D1::const_t, typename D2::const_t>,
202  typename D1::value_type, typename D1::reference, typename D1::const_reference,
203  typename D2::argument_type, typename D1::result_type, D1::is_mutable && D2::is_mutable>
204 {
205 public:
206  D1 _fn1;
207  D2 _fn2;
208 
209  typedef typename D2::argument_type argument_type;
210  typedef typename D1::result_type result_type;
211 
212  deref_compose() {}
213  deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}
214  deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
215  template <typename _D1, typename _D2> deref_compose(const deref_compose<_D1,_D2>& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
216 
217  result_type operator()(argument_type x) const { return _fn1(_fn2(x)); }
218  result_type operator()(argument_type x) { return _fn1(_fn2(x)); }
219 };
220 
221 // reinterpret_cast is implementation-defined. Static cast is not.
222 template <typename OutPtr, typename In> BOOST_FORCEINLINE
223  OutPtr gil_reinterpret_cast( In* p) { return static_cast<OutPtr>(static_cast<void*>(p)); }
224 
225 template <typename OutPtr, typename In> BOOST_FORCEINLINE
226 const OutPtr gil_reinterpret_cast_c(const In* p) { return static_cast<const OutPtr>(static_cast<const void*>(p)); }
227 
228 namespace detail {
229 
235 
236 template <class InputIter, class Size, class OutputIter>
237 std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
238  OutputIter result,
239  std::input_iterator_tag) {
240  for ( ; count > 0; --count) {
241  *result = *first;
242  ++first;
243  ++result;
244  }
245  return std::pair<InputIter, OutputIter>(first, result);
246 }
247 
248 template <class RAIter, class Size, class OutputIter>
249 inline std::pair<RAIter, OutputIter>
250 _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag) {
251  RAIter last = first + count;
252  return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
253 }
254 
255 template <class InputIter, class Size, class OutputIter>
256 inline std::pair<InputIter, OutputIter>
257 _copy_n(InputIter first, Size count, OutputIter result) {
258  return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
259 }
260 
261 template <class InputIter, class Size, class OutputIter>
262 inline std::pair<InputIter, OutputIter>
263 copy_n(InputIter first, Size count, OutputIter result) {
264  return detail::_copy_n(first, count, result);
265 }
266 
268 template <typename T>
269 struct identity {
270  typedef T argument_type;
271  typedef T result_type;
272  const T& operator()(const T& val) const { return val; }
273 };
274 
275 /*************************************************************************************************/
276 
278 template <typename T1, typename T2>
280  typedef T1 first_argument_type;
281  typedef T2 second_argument_type;
282  typedef T1 result_type;
283  T1 operator()(T1 f1, T2 f2) const {
284  return f1+f2;
285  }
286 };
287 
288 /*************************************************************************************************/
289 
291 template <typename T>
292 struct inc {
293  typedef T argument_type;
294  typedef T result_type;
295  T operator()(T x) const { return ++x; }
296 };
297 
298 /*************************************************************************************************/
299 
301 template <typename T>
302 struct dec {
303  typedef T argument_type;
304  typedef T result_type;
305  T operator()(T x) const { return --x; }
306 };
307 
309 // a given MPL RandomAccessSequence (or size if the type is not present)
310 template <typename Types, typename T>
312  : public mpl::distance<typename mpl::begin<Types>::type,
313  typename mpl::find<Types,T>::type>::type {};
314 } // namespace detail
315 
316 
317 
320 template <typename ColorSpace, typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value> >
321 struct layout {
322  typedef ColorSpace color_space_t;
323  typedef ChannelMapping channel_mapping_t;
324 };
325 
327 template <typename Value, typename T1, typename T2> // where value_type<T1> == value_type<T2> == Value
328 void swap_proxy(T1& left, T2& right) {
329  Value tmp = left;
330  left = right;
331  right = tmp;
332 }
333 
335 inline bool little_endian() {
336  short tester = 0x0001;
337  return *(char*)&tester!=0;
338 }
340 inline bool big_endian() {
341  return !little_endian();
342 }
343 
344 } } // namespace boost::gil
345 
346 #endif
plus function object whose arguments may be of different type.
Definition: utility.hpp:279
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:150
Channel utilities.
Helper base class for pixel dereference adaptors.
Definition: utility.hpp:186
operator– wrapped in a function object
Definition: utility.hpp:302
GIL configuration file.
identity taken from SGI STL.
Definition: utility.hpp:269
operator++ wrapped in a function object
Definition: utility.hpp:292
Represents a color space and ordering of channels in memory.
Definition: utility.hpp:321
Composes two dereference function objects. Similar to std::unary_compose but needs to pull some typed...
Definition: utility.hpp:200
pixel class and related utilities
Returns the index corresponding to the first occurrance of a given given type in. ...
Definition: utility.hpp:311