annotate DEPENDENCIES/generic/include/boost/gil/utilities.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*
Chris@16 2 Copyright 2005-2007 Adobe Systems Incorporated
Chris@16 3
Chris@16 4 Use, modification and distribution are subject to the Boost Software License,
Chris@16 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt).
Chris@16 7
Chris@16 8 See http://opensource.adobe.com/gil for most recent version including documentation.
Chris@16 9 */
Chris@16 10
Chris@16 11 /*************************************************************************************************/
Chris@16 12
Chris@16 13 #ifndef GIL_UTILITIES_H
Chris@16 14 #define GIL_UTILITIES_H
Chris@16 15
Chris@16 16 #include "gil_config.hpp"
Chris@16 17 #include <functional>
Chris@16 18 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 19 #include <cstddef>
Chris@16 20 #include <algorithm>
Chris@16 21 #include <utility>
Chris@16 22 #include <iterator>
Chris@16 23 #include <boost/static_assert.hpp>
Chris@16 24 #include <boost/type_traits.hpp>
Chris@16 25 #include <boost/mpl/size.hpp>
Chris@16 26 #include <boost/mpl/distance.hpp>
Chris@16 27 #include <boost/mpl/begin.hpp>
Chris@16 28 #include <boost/mpl/find.hpp>
Chris@16 29 #include <boost/mpl/range_c.hpp>
Chris@16 30 #include <boost/iterator/iterator_adaptor.hpp>
Chris@16 31 #include <boost/iterator/iterator_facade.hpp>
Chris@16 32
Chris@16 33 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 34 /// \file
Chris@16 35 /// \brief Various utilities not specific to the image library. Some are non-standard STL extensions or generic iterator adaptors
Chris@16 36 /// \author Lubomir Bourdev and Hailin Jin \n
Chris@16 37 /// Adobe Systems Incorporated
Chris@16 38 /// \date 2005-2007 \n Last updated on September 18, 2007
Chris@16 39 ///
Chris@16 40 ///
Chris@16 41 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 42
Chris@16 43 namespace boost { namespace gil {
Chris@16 44
Chris@16 45 /**
Chris@16 46 \addtogroup PointModel
Chris@16 47
Chris@16 48 Example:
Chris@16 49 \code
Chris@16 50 point2<std::ptrdiff_t> p(3,2);
Chris@16 51 assert((p[0] == p.x) && (p[1] == p.y));
Chris@16 52 assert(axis_value<0>(p) == 3);
Chris@16 53 assert(axis_value<1>(p) == 2);
Chris@16 54 \endcode
Chris@16 55 */
Chris@16 56
Chris@16 57 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 58 // CLASS point2
Chris@16 59 ///
Chris@16 60 /// \brief 2D point both axes of which have the same dimension type
Chris@16 61 /// \ingroup PointModel
Chris@16 62 /// Models: Point2DConcept
Chris@16 63 ///
Chris@16 64 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 65
Chris@16 66 template <typename T>
Chris@16 67 class point2 {
Chris@16 68 public:
Chris@16 69 typedef T value_type;
Chris@16 70 template <std::size_t D> struct axis { typedef value_type coord_t; };
Chris@16 71 static const std::size_t num_dimensions=2;
Chris@16 72
Chris@16 73 point2() : x(0), y(0) {}
Chris@16 74 point2(T newX, T newY) : x(newX), y(newY) {}
Chris@16 75 point2(const point2& p) : x(p.x), y(p.y) {}
Chris@16 76 ~point2() {}
Chris@16 77
Chris@16 78 point2& operator=(const point2& p) { x=p.x; y=p.y; return *this; }
Chris@16 79
Chris@16 80 point2 operator<<(std::ptrdiff_t shift) const { return point2(x<<shift,y<<shift); }
Chris@16 81 point2 operator>>(std::ptrdiff_t shift) const { return point2(x>>shift,y>>shift); }
Chris@16 82 point2& operator+=(const point2& p) { x+=p.x; y+=p.y; return *this; }
Chris@16 83 point2& operator-=(const point2& p) { x-=p.x; y-=p.y; return *this; }
Chris@16 84 point2& operator/=(double t) { x/=t; y/=t; return *this; }
Chris@16 85
Chris@16 86 const T& operator[](std::size_t i) const { return this->*mem_array[i]; }
Chris@16 87 T& operator[](std::size_t i) { return this->*mem_array[i]; }
Chris@16 88
Chris@16 89 T x,y;
Chris@16 90 private:
Chris@16 91 // this static array of pointers to member variables makes operator[] safe and doesn't seem to exhibit any performance penalty
Chris@16 92 static T point2<T>::* const mem_array[num_dimensions];
Chris@16 93 };
Chris@16 94
Chris@16 95 template <typename T>
Chris@16 96 T point2<T>::* const point2<T>::mem_array[point2<T>::num_dimensions] = { &point2<T>::x, &point2<T>::y };
Chris@16 97
Chris@16 98 /// \ingroup PointModel
Chris@16 99 template <typename T> GIL_FORCEINLINE
Chris@16 100 bool operator==(const point2<T>& p1, const point2<T>& p2) { return (p1.x==p2.x && p1.y==p2.y); }
Chris@16 101 /// \ingroup PointModel
Chris@16 102 template <typename T> GIL_FORCEINLINE
Chris@16 103 bool operator!=(const point2<T>& p1, const point2<T>& p2) { return p1.x!=p2.x || p1.y!=p2.y; }
Chris@16 104 /// \ingroup PointModel
Chris@16 105 template <typename T> GIL_FORCEINLINE
Chris@16 106 point2<T> operator+(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x+p2.x,p1.y+p2.y); }
Chris@16 107 /// \ingroup PointModel
Chris@16 108 template <typename T> GIL_FORCEINLINE
Chris@16 109 point2<T> operator-(const point2<T>& p) { return point2<T>(-p.x,-p.y); }
Chris@16 110 /// \ingroup PointModel
Chris@16 111 template <typename T> GIL_FORCEINLINE
Chris@16 112 point2<T> operator-(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x-p2.x,p1.y-p2.y); }
Chris@16 113 /// \ingroup PointModel
Chris@16 114 template <typename T> GIL_FORCEINLINE
Chris@16 115 point2<double> operator/(const point2<T>& p, double t) { return t==0 ? point2<double>(0,0):point2<double>(p.x/t,p.y/t); }
Chris@16 116 /// \ingroup PointModel
Chris@16 117 template <typename T> GIL_FORCEINLINE
Chris@16 118 point2<T> operator*(const point2<T>& p, std::ptrdiff_t t) { return point2<T>(p.x*t,p.y*t); }
Chris@16 119 /// \ingroup PointModel
Chris@16 120 template <typename T> GIL_FORCEINLINE
Chris@16 121 point2<T> operator*(std::ptrdiff_t t, const point2<T>& p) { return point2<T>(p.x*t,p.y*t); }
Chris@16 122
Chris@16 123 /// \ingroup PointModel
Chris@16 124 template <std::size_t K, typename T> GIL_FORCEINLINE
Chris@16 125 const T& axis_value(const point2<T>& p) { return p[K]; }
Chris@16 126
Chris@16 127 /// \ingroup PointModel
Chris@16 128 template <std::size_t K, typename T> GIL_FORCEINLINE
Chris@16 129 T& axis_value( point2<T>& p) { return p[K]; }
Chris@16 130
Chris@16 131 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 132 ///
Chris@16 133 /// Rounding of real numbers / points to integers / integer points
Chris@16 134 ///
Chris@16 135 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 136
Chris@16 137 inline std::ptrdiff_t iround(float x ) { return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f)); }
Chris@16 138 inline std::ptrdiff_t iround(double x) { return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5)); }
Chris@16 139 inline std::ptrdiff_t ifloor(float x ) { return static_cast<std::ptrdiff_t>(std::floor(x)); }
Chris@16 140 inline std::ptrdiff_t ifloor(double x) { return static_cast<std::ptrdiff_t>(std::floor(x)); }
Chris@16 141 inline std::ptrdiff_t iceil(float x ) { return static_cast<std::ptrdiff_t>(std::ceil(x)); }
Chris@16 142 inline std::ptrdiff_t iceil(double x) { return static_cast<std::ptrdiff_t>(std::ceil(x)); }
Chris@16 143
Chris@16 144 /**
Chris@16 145 \addtogroup PointAlgorithm
Chris@16 146
Chris@16 147 Example:
Chris@16 148 \code
Chris@16 149 assert(iround(point2<double>(3.1, 3.9)) == point2<std::ptrdiff_t>(3,4));
Chris@16 150 \endcode
Chris@16 151 */
Chris@16 152
Chris@16 153 /// \ingroup PointAlgorithm
Chris@16 154 inline point2<std::ptrdiff_t> iround(const point2<float >& p) { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); }
Chris@16 155 /// \ingroup PointAlgorithm
Chris@16 156 inline point2<std::ptrdiff_t> iround(const point2<double>& p) { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); }
Chris@16 157 /// \ingroup PointAlgorithm
Chris@16 158 inline point2<std::ptrdiff_t> ifloor(const point2<float >& p) { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); }
Chris@16 159 /// \ingroup PointAlgorithm
Chris@16 160 inline point2<std::ptrdiff_t> ifloor(const point2<double>& p) { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); }
Chris@16 161 /// \ingroup PointAlgorithm
Chris@16 162 inline point2<std::ptrdiff_t> iceil (const point2<float >& p) { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); }
Chris@16 163 /// \ingroup PointAlgorithm
Chris@16 164 inline point2<std::ptrdiff_t> iceil (const point2<double>& p) { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); }
Chris@16 165
Chris@16 166 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 167 ///
Chris@16 168 /// computing size with alignment
Chris@16 169 ///
Chris@16 170 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 171
Chris@16 172 template <typename T>
Chris@16 173 inline T align(T val, std::size_t alignment) {
Chris@16 174 return val+(alignment - val%alignment)%alignment;
Chris@16 175 }
Chris@16 176
Chris@16 177 /// \brief Helper base class for pixel dereference adaptors.
Chris@16 178 /// \ingroup PixelDereferenceAdaptorModel
Chris@16 179 ///
Chris@16 180 template <typename ConstT, typename Value, typename Reference, typename ConstReference,
Chris@16 181 typename ArgType, typename ResultType, bool IsMutable>
Chris@16 182 struct deref_base : public std::unary_function<ArgType, ResultType> {
Chris@16 183 typedef ConstT const_t;
Chris@16 184 typedef Value value_type;
Chris@16 185 typedef Reference reference;
Chris@16 186 typedef ConstReference const_reference;
Chris@16 187 BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable);
Chris@16 188 };
Chris@16 189
Chris@16 190 /// \brief Composes two dereference function objects. Similar to std::unary_compose but needs to pull some typedefs from the component types. Models: PixelDereferenceAdaptorConcept
Chris@16 191 /// \ingroup PixelDereferenceAdaptorModel
Chris@16 192 ///
Chris@16 193 template <typename D1, typename D2>
Chris@16 194 class deref_compose : public deref_base<
Chris@16 195 deref_compose<typename D1::const_t, typename D2::const_t>,
Chris@16 196 typename D1::value_type, typename D1::reference, typename D1::const_reference,
Chris@16 197 typename D2::argument_type, typename D1::result_type, D1::is_mutable && D2::is_mutable>
Chris@16 198 {
Chris@16 199 public:
Chris@16 200 D1 _fn1;
Chris@16 201 D2 _fn2;
Chris@16 202
Chris@16 203 typedef typename D2::argument_type argument_type;
Chris@16 204 typedef typename D1::result_type result_type;
Chris@16 205
Chris@16 206 deref_compose() {}
Chris@16 207 deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}
Chris@16 208 deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
Chris@16 209 template <typename _D1, typename _D2> deref_compose(const deref_compose<_D1,_D2>& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
Chris@16 210
Chris@16 211 result_type operator()(argument_type x) const { return _fn1(_fn2(x)); }
Chris@16 212 result_type operator()(argument_type x) { return _fn1(_fn2(x)); }
Chris@16 213 };
Chris@16 214
Chris@16 215 // reinterpret_cast is implementation-defined. Static cast is not.
Chris@16 216 template <typename OutPtr, typename In> GIL_FORCEINLINE
Chris@16 217 OutPtr gil_reinterpret_cast( In* p) { return static_cast<OutPtr>(static_cast<void*>(p)); }
Chris@16 218
Chris@16 219 template <typename OutPtr, typename In> GIL_FORCEINLINE
Chris@16 220 const OutPtr gil_reinterpret_cast_c(const In* p) { return static_cast<const OutPtr>(static_cast<const void*>(p)); }
Chris@16 221
Chris@16 222 namespace detail {
Chris@16 223
Chris@16 224 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 225 ///
Chris@16 226 /// \brief copy_n taken from SGI STL.
Chris@16 227 ///
Chris@16 228 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 229
Chris@16 230 template <class InputIter, class Size, class OutputIter>
Chris@16 231 std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
Chris@16 232 OutputIter result,
Chris@16 233 std::input_iterator_tag) {
Chris@16 234 for ( ; count > 0; --count) {
Chris@16 235 *result = *first;
Chris@16 236 ++first;
Chris@16 237 ++result;
Chris@16 238 }
Chris@16 239 return std::pair<InputIter, OutputIter>(first, result);
Chris@16 240 }
Chris@16 241
Chris@16 242 template <class RAIter, class Size, class OutputIter>
Chris@16 243 inline std::pair<RAIter, OutputIter>
Chris@16 244 _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag) {
Chris@16 245 RAIter last = first + count;
Chris@16 246 return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
Chris@16 247 }
Chris@16 248
Chris@16 249 template <class InputIter, class Size, class OutputIter>
Chris@16 250 inline std::pair<InputIter, OutputIter>
Chris@16 251 _copy_n(InputIter first, Size count, OutputIter result) {
Chris@16 252 return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
Chris@16 253 }
Chris@16 254
Chris@16 255 template <class InputIter, class Size, class OutputIter>
Chris@16 256 inline std::pair<InputIter, OutputIter>
Chris@16 257 copy_n(InputIter first, Size count, OutputIter result) {
Chris@16 258 return detail::_copy_n(first, count, result);
Chris@16 259 }
Chris@16 260
Chris@16 261 /// \brief identity taken from SGI STL.
Chris@16 262 template <typename T>
Chris@16 263 struct identity : public std::unary_function<T,T> {
Chris@16 264 const T& operator()(const T& val) const { return val; }
Chris@16 265 };
Chris@16 266
Chris@16 267 /*************************************************************************************************/
Chris@16 268
Chris@16 269 /// \brief plus function object whose arguments may be of different type.
Chris@16 270 template <typename T1, typename T2>
Chris@16 271 struct plus_asymmetric : public std::binary_function<T1,T2,T1> {
Chris@16 272 T1 operator()(T1 f1, T2 f2) const {
Chris@16 273 return f1+f2;
Chris@16 274 }
Chris@16 275 };
Chris@16 276
Chris@16 277 /*************************************************************************************************/
Chris@16 278
Chris@16 279 /// \brief operator++ wrapped in a function object
Chris@16 280 template <typename T>
Chris@16 281 struct inc : public std::unary_function<T,T> {
Chris@16 282 T operator()(T x) const { return ++x; }
Chris@16 283 };
Chris@16 284
Chris@16 285 /*************************************************************************************************/
Chris@16 286
Chris@16 287 /// \brief operator-- wrapped in a function object
Chris@16 288 template <typename T>
Chris@16 289 struct dec : public std::unary_function<T,T> {
Chris@16 290 T operator()(T x) const { return --x; }
Chris@16 291 };
Chris@16 292
Chris@16 293 /// \brief Returns the index corresponding to the first occurrance of a given given type in
Chris@16 294 // a given MPL RandomAccessSequence (or size if the type is not present)
Chris@16 295 template <typename Types, typename T>
Chris@16 296 struct type_to_index
Chris@16 297 : public mpl::distance<typename mpl::begin<Types>::type,
Chris@16 298 typename mpl::find<Types,T>::type>::type {};
Chris@16 299 } // namespace detail
Chris@16 300
Chris@16 301
Chris@16 302
Chris@16 303 /// \ingroup ColorSpaceAndLayoutModel
Chris@16 304 /// \brief Represents a color space and ordering of channels in memory
Chris@16 305 template <typename ColorSpace, typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value> >
Chris@16 306 struct layout {
Chris@16 307 typedef ColorSpace color_space_t;
Chris@16 308 typedef ChannelMapping channel_mapping_t;
Chris@16 309 };
Chris@16 310
Chris@16 311 /// \brief A version of swap that also works with reference proxy objects
Chris@16 312 template <typename Value, typename T1, typename T2> // where value_type<T1> == value_type<T2> == Value
Chris@16 313 void swap_proxy(T1& left, T2& right) {
Chris@16 314 Value tmp = left;
Chris@16 315 left = right;
Chris@16 316 right = tmp;
Chris@16 317 }
Chris@16 318
Chris@16 319 /// \brief Run-time detection of whether the underlying architecture is little endian
Chris@16 320 inline bool little_endian() {
Chris@16 321 short tester = 0x0001;
Chris@16 322 return *(char*)&tester!=0;
Chris@16 323 }
Chris@16 324 /// \brief Run-time detection of whether the underlying architecture is big endian
Chris@16 325 inline bool big_endian() {
Chris@16 326 return !little_endian();
Chris@16 327 }
Chris@16 328
Chris@16 329 } } // namespace boost::gil
Chris@16 330
Chris@16 331 #endif