annotate DEPENDENCIES/generic/include/boost/gil/extension/dynamic_image/reduce.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +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 #ifndef GIL_REDUCE_HPP
Chris@16 13 #define GIL_REDUCE_HPP
Chris@16 14
Chris@16 15 #include <boost/mpl/insert_range.hpp>
Chris@16 16 #include <boost/mpl/range_c.hpp>
Chris@16 17 #include <boost/mpl/vector_c.hpp>
Chris@16 18 #include <boost/mpl/back.hpp>
Chris@16 19 #include <boost/mpl/vector.hpp>
Chris@16 20 #include <boost/mpl/long.hpp>
Chris@16 21 #include <boost/mpl/logical.hpp>
Chris@16 22 #include <boost/mpl/transform.hpp>
Chris@16 23 #include <boost/mpl/insert.hpp>
Chris@16 24 #include <boost/mpl/transform.hpp>
Chris@16 25
Chris@16 26 #include "../../metafunctions.hpp"
Chris@16 27 #include "../../typedefs.hpp"
Chris@16 28 #include "dynamic_at_c.hpp"
Chris@16 29
Chris@16 30 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 31 /// \file
Chris@16 32 /// \brief Constructs for static-to-dynamic integer convesion
Chris@16 33 /// \author Lubomir Bourdev and Hailin Jin \n
Chris@16 34 /// Adobe Systems Incorporated
Chris@16 35 /// \date 2005-2007 \n Last updated on May 4, 2006
Chris@16 36 ///
Chris@16 37 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 38
Chris@16 39
Chris@16 40 #ifdef GIL_REDUCE_CODE_BLOAT
Chris@16 41
Chris@16 42
Chris@16 43 // Max number of cases in the cross-expension of binary operation for it to be reduced as unary
Chris@16 44 #define GIL_BINARY_REDUCE_LIMIT 226
Chris@16 45
Chris@16 46 namespace boost { namespace mpl {
Chris@16 47
Chris@16 48 ///////////////////////////////////////////////////////
Chris@16 49 /// Mapping vector - represents the mapping of one type vector to another
Chris@16 50 /// It is not a full-blown MPL Random Access Type sequence; just has at_c and size implemented
Chris@16 51 ///
Chris@16 52 /// SrcTypes, DstTypes: MPL Random Access Type Sequences
Chris@16 53 ///
Chris@16 54 /// Implements size and at_c to behave as if this is an MPL vector of integers
Chris@16 55 ///////////////////////////////////////////////////////
Chris@16 56
Chris@16 57 template <typename SrcTypes, typename DstTypes>
Chris@16 58 struct mapping_vector {};
Chris@16 59
Chris@16 60 template <typename SrcTypes, typename DstTypes, long K>
Chris@16 61 struct at_c<mapping_vector<SrcTypes,DstTypes>, K> {
Chris@16 62 static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename at_c<SrcTypes,K>::type>::type::value +1;
Chris@16 63 typedef size_t<value> type;
Chris@16 64 };
Chris@16 65
Chris@16 66 template <typename SrcTypes, typename DstTypes>
Chris@16 67 struct size<mapping_vector<SrcTypes,DstTypes> > {
Chris@16 68 typedef typename size<SrcTypes>::type type;
Chris@16 69 static const std::size_t value=type::value;
Chris@16 70 };
Chris@16 71
Chris@16 72 ///////////////////////////////////////////////////////
Chris@16 73 /// copy_to_vector - copies a sequence (mpl::set) to vector.
Chris@16 74 ///
Chris@16 75 /// Temporary solution because I couldn't get mpl::copy to do this.
Chris@16 76 /// This is what I tried:
Chris@16 77 /// mpl::copy<SET, mpl::back_inserter<mpl::vector<> > >::type;
Chris@16 78 /// It works when SET is mpl::vector, but not when SET is mpl::set...
Chris@16 79 ///////////////////////////////////////////////////////
Chris@16 80
Chris@16 81 namespace detail {
Chris@16 82 template <typename SFirst, std::size_t NLeft>
Chris@16 83 struct copy_to_vector_impl {
Chris@16 84 private:
Chris@16 85 typedef typename deref<SFirst>::type T;
Chris@16 86 typedef typename next<SFirst>::type next;
Chris@16 87 typedef typename copy_to_vector_impl<next, NLeft-1>::type rest;
Chris@16 88 public:
Chris@16 89 typedef typename push_front<rest, T>::type type;
Chris@16 90 };
Chris@16 91
Chris@16 92 template <typename SFirst>
Chris@16 93 struct copy_to_vector_impl<SFirst,1> {
Chris@16 94 typedef vector<typename deref<SFirst>::type> type;
Chris@16 95 };
Chris@16 96 }
Chris@16 97
Chris@16 98 template <typename Src>
Chris@16 99 struct copy_to_vector {
Chris@16 100 typedef typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type type;
Chris@16 101 };
Chris@16 102
Chris@16 103 template <>
Chris@16 104 struct copy_to_vector<set<> > {
Chris@16 105 typedef vector0<> type;
Chris@16 106 };
Chris@16 107
Chris@16 108 } } // boost::mpl
Chris@16 109
Chris@16 110 namespace boost { namespace gil {
Chris@16 111
Chris@16 112
Chris@16 113 ///////////////////////////////////////////////////////
Chris@16 114 ///
Chris@16 115 /// unary_reduce, binary_reduce - given an MPL Random Access Sequence,
Chris@16 116 /// dynamically specified index to that container, the bits of an instance of the corresponding type and
Chris@16 117 /// a generic operation, invokes the operation on the given type
Chris@16 118 ///
Chris@16 119 ///////////////////////////////////////////////////////
Chris@16 120
Chris@16 121
Chris@16 122
Chris@16 123
Chris@16 124 ///////////////////////////////////////////////////////
Chris@16 125 ///
Chris@16 126 /// \brief Unary reduce.
Chris@16 127 ///
Chris@16 128 /// Given a set of types and an operation, reduces each type in the set (to reduced_t), then removes duplicates (to unique_t)
Chris@16 129 /// To apply the operation, first constructs a lookup table that maps each element from Types to its place in unique_t and uses it to map
Chris@16 130 /// the index to anther index (in map_index). Then invokes apply_operation_base on the unique types with the new index.
Chris@16 131 ///
Chris@16 132 ///////////////////////////////////////////////////////
Chris@16 133
Chris@16 134 template <typename Types, typename Op>
Chris@16 135 struct unary_reduce_impl {
Chris@16 136 typedef typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type reduced_t;
Chris@16 137 typedef typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2> > >::type unique_t;
Chris@16 138 static const bool is_single=mpl::size<unique_t>::value==1;
Chris@16 139 };
Chris@16 140
Chris@16 141 template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>
Chris@16 142 struct unary_reduce : public unary_reduce_impl<Types,Op> {
Chris@16 143 typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t;
Chris@16 144 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
Chris@16 145
Chris@16 146 static unsigned short inline map_index(std::size_t index) {
Chris@16 147 typedef typename mpl::mapping_vector<reduced_t, unique_t> indices_t;
Chris@16 148 return gil::at_c<indices_t, unsigned short>(index);
Chris@16 149 }
Chris@16 150 template <typename Bits> GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
Chris@16 151 return apply_operation_basec<unique_t>(bits,map_index(index),op);
Chris@16 152 }
Chris@16 153
Chris@16 154 template <typename Bits> GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
Chris@16 155 return apply_operation_base<unique_t>(bits,map_index(index),op);
Chris@16 156 }
Chris@16 157 };
Chris@16 158
Chris@16 159 template <typename Types, typename Op>
Chris@16 160 struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {
Chris@16 161 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
Chris@16 162 static unsigned short inline map_index(std::size_t index) { return 0; }
Chris@16 163
Chris@16 164 template <typename Bits> GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
Chris@16 165 return op(*gil_reinterpret_cast_c<const typename mpl::front<unique_t>::type*>(&bits));
Chris@16 166 }
Chris@16 167
Chris@16 168 template <typename Bits> GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
Chris@16 169 return op(*gil_reinterpret_cast<typename mpl::front<unique_t>::type*>(&bits));
Chris@16 170 }
Chris@16 171 };
Chris@16 172
Chris@16 173
Chris@16 174 ///////////////////////////////////////////////////////
Chris@16 175 ///
Chris@16 176 /// \brief Binary reduce.
Chris@16 177 ///
Chris@16 178 /// Given two sets of types, Types1 and Types2, first performs unary reduction on each. Then checks if the product of their sizes is above
Chris@16 179 /// the GIL_BINARY_REDUCE_LIMIT limit. If so, the operation is too complex to be binary-reduced and uses a specialization of binary_reduce_impl
Chris@16 180 /// to simply call the binary apply_operation_base (which performs two nested 1D apply operations)
Chris@16 181 /// If the operation is not too complex, uses the other specialization of binary_reduce_impl to create a cross-product of the input types
Chris@16 182 /// and performs unary reduction on the result (bin_reduced_t). To apply the binary operation, it simply invokes a unary apply_operation_base
Chris@16 183 /// on the reduced cross-product types
Chris@16 184 ///
Chris@16 185 ///////////////////////////////////////////////////////
Chris@16 186
Chris@16 187 namespace detail {
Chris@16 188 struct pair_generator {
Chris@16 189 template <typename Vec2> struct apply {
Chris@16 190 typedef std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::type*> type;
Chris@16 191 };
Chris@16 192 };
Chris@16 193
Chris@16 194 // When the types are not too large, applies reduce on their cross product
Chris@16 195 template <typename Unary1, typename Unary2, typename Op, bool IsComplex>
Chris@16 196 struct binary_reduce_impl {
Chris@16 197 //private:
Chris@16 198 typedef typename mpl::copy_to_vector<typename Unary1::unique_t>::type vec1_types;
Chris@16 199 typedef typename mpl::copy_to_vector<typename Unary2::unique_t>::type vec2_types;
Chris@16 200
Chris@16 201 typedef mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;
Chris@16 202 typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t;
Chris@16 203
Chris@16 204 static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
Chris@16 205 unsigned short r1=Unary1::map_index(index1);
Chris@16 206 unsigned short r2=Unary2::map_index(index2);
Chris@16 207 return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);
Chris@16 208 }
Chris@16 209 public:
Chris@16 210 typedef typename bin_reduced_t::unique_t unique_t;
Chris@16 211
Chris@16 212 template <typename Bits1, typename Bits2>
Chris@16 213 static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
Chris@16 214 std::pair<const void*,const void*> pr(&bits1, &bits2);
Chris@16 215 return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
Chris@16 216 }
Chris@16 217 };
Chris@16 218
Chris@16 219 // When the types are large performs a double-dispatch. Binary reduction is not done.
Chris@16 220 template <typename Unary1, typename Unary2, typename Op>
Chris@16 221 struct binary_reduce_impl<Unary1,Unary2,Op,true> {
Chris@16 222 template <typename Bits1, typename Bits2>
Chris@16 223 static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
Chris@16 224 return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);
Chris@16 225 }
Chris@16 226 };
Chris@16 227 }
Chris@16 228
Chris@16 229
Chris@16 230 template <typename Types1, typename Types2, typename Op>
Chris@16 231 struct binary_reduce {
Chris@16 232 //private:
Chris@16 233 typedef unary_reduce<Types1,Op> unary1_t;
Chris@16 234 typedef unary_reduce<Types2,Op> unary2_t;
Chris@16 235
Chris@16 236 static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
Chris@16 237 mpl::size<typename unary2_t::unique_t>::value;
Chris@16 238
Chris@16 239 typedef detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)> impl;
Chris@16 240 public:
Chris@16 241 template <typename Bits1, typename Bits2>
Chris@16 242 static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
Chris@16 243 return impl::apply(bits1,index1,bits2,index2,op);
Chris@16 244 }
Chris@16 245 };
Chris@16 246
Chris@16 247 template <typename Types, typename UnaryOp>
Chris@16 248 GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
Chris@16 249 return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);
Chris@16 250 }
Chris@16 251
Chris@16 252 template <typename Types, typename UnaryOp>
Chris@16 253 GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant<Types>& arg, UnaryOp op) {
Chris@16 254 return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);
Chris@16 255 }
Chris@16 256
Chris@16 257 template <typename Types1, typename Types2, typename BinaryOp>
Chris@16 258 GIL_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {
Chris@16 259 return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
Chris@16 260 }
Chris@16 261
Chris@16 262 #undef GIL_BINARY_REDUCE_LIMIT
Chris@16 263
Chris@16 264 } } // namespace gil
Chris@16 265
Chris@16 266
Chris@16 267 namespace boost { namespace mpl {
Chris@16 268 ///////////////////////////////////////////////////////
Chris@16 269 /// \brief Represents the virtual cross-product of the types generated from VecOfVecs.
Chris@16 270 /// \ingroup CrossVector
Chris@16 271 /// INPUT:
Chris@16 272 /// VecOfVecs - a vector of vector types. For example [ [A1,A2,A3], [B1,B2], [C1,C2,C3,C4] ]
Chris@16 273 /// Each element must be a non-empty mpl vector
Chris@16 274 /// TypeGen - a metafunction that generates a type from a vector of types, each of which can be
Chris@16 275 /// selected from the corresponding vector in VecOfVecs. For example, [A1, B2, C4]
Chris@16 276 ///
Chris@16 277 /// Represents the virtual cross-product of the types generated from VecOfVecs.
Chris@16 278 /// For example, [ TypeGen[A1,B1,C1], TypeGen[A2,B1,C1], TypeGen[A3,B1,C1],
Chris@16 279 /// TypeGen[A1,B2,C1], TypeGen[A2,B2,C1], TypeGen[A3,B2,C1],
Chris@16 280 /// TypeGen[A1,B1,C2], TypeGen[A2,B1,C2], TypeGen[A3,B1,C2], ... ]
Chris@16 281 ///
Chris@16 282 /// Models an immutable MPL Random Access Sequence
Chris@16 283 /// Traversal, random-access, etc, is defined, but mutable operations,
Chris@16 284 /// such as push_back and pop_front are not supported
Chris@16 285 ///////////////////////////////////////////////////////
Chris@16 286
Chris@16 287 template <typename VecOfVecs, typename TypeGen>
Chris@16 288 struct cross_vector {};
Chris@16 289
Chris@16 290 /// \brief Iterator of cross_vector
Chris@16 291 /// \ingroup CrossVectorIterator
Chris@16 292 template <typename VecOfVecs, typename TypeGen, std::size_t K>
Chris@16 293 struct cross_iterator {
Chris@16 294 typedef mpl::random_access_iterator_tag category;
Chris@16 295 };
Chris@16 296
Chris@16 297 ///////////////////////////////////////////////////////
Chris@16 298 /// Implementation of the iterator functions of cross vector
Chris@16 299 ///////////////////////////////////////////////////////
Chris@16 300
Chris@16 301 /// \brief Dereferences a cross-vector iterator
Chris@16 302 /// \ingroup CrossVectorIterator
Chris@16 303 /// Creates a vector of the sizes of each type vector in VecOfVecs, then uses it as a basis
Chris@16 304 /// to represent the iterator's position K as a vector of indices. Extracts the corresponding type of
Chris@16 305 /// each input vector and passes the element types to the type generation function, which returns the dereferenced type
Chris@16 306 template <typename VecOfVecs, typename TypeGen, std::size_t K>
Chris@16 307 struct deref<cross_iterator<VecOfVecs,TypeGen,K> > {
Chris@16 308 private:
Chris@16 309 typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes;
Chris@16 310 public:
Chris@16 311 typedef typename TypeGen::template apply<DerefTypes>::type type;
Chris@16 312 };
Chris@16 313
Chris@16 314 /// \brief Increments a cross-vector iterator.
Chris@16 315 /// \ingroup CrossVectorIterator
Chris@16 316 template <typename VecOfVecs, typename TypeGen, std::size_t K>
Chris@16 317 struct next<cross_iterator<VecOfVecs,TypeGen,K> > {
Chris@16 318 typedef cross_iterator<VecOfVecs,TypeGen,K+1> type;
Chris@16 319 };
Chris@16 320
Chris@16 321 /// \brief Decrements a cross-vector iterator.
Chris@16 322 /// \ingroup CrossVectorIterator
Chris@16 323 template <typename VecOfVecs, typename TypeGen, std::size_t K>
Chris@16 324 struct prior<cross_iterator<VecOfVecs,TypeGen,K> > {
Chris@16 325 typedef cross_iterator<VecOfVecs,TypeGen,K-1> type;
Chris@16 326 };
Chris@16 327
Chris@16 328 /// \brief Advances a cross-vector iterator.
Chris@16 329 /// \ingroup CrossVectorIterator
Chris@16 330 template <typename VecOfVecs, typename TypeGen, std::size_t K, typename Distance>
Chris@16 331 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance > {
Chris@16 332 typedef cross_iterator<VecOfVecs,TypeGen,K+Distance::value> type;
Chris@16 333 };
Chris@16 334
Chris@16 335 /// \brief Computes the distance between two cross-vector iterator-s.
Chris@16 336 /// \ingroup CrossVectorIterator
Chris@16 337 // (shortened the names of the template arguments - otherwise doxygen cannot parse this...)
Chris@16 338 template <typename VecOfVecs, typename TypeGen, std::size_t K1, std::size_t K2>
Chris@16 339 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2> > {
Chris@16 340 typedef size_t<K2-K1> type;
Chris@16 341 };
Chris@16 342
Chris@16 343 ///////////////////////////////////////////////////////
Chris@16 344 /// Implementation of cross vector
Chris@16 345 ///////////////////////////////////////////////////////
Chris@16 346 /// \brief Computes the size of a cross vector as the product of the sizes of all vectors in VecOfVecs
Chris@16 347 /// \ingroup CrossVector
Chris@16 348 template <typename VecOfVecs, typename TypeGen>
Chris@16 349 struct size<cross_vector<VecOfVecs,TypeGen> > {
Chris@16 350 typedef typename fold<VecOfVecs, size_t<1>, times<_1, size<_2> > >::type type;
Chris@16 351 static const std::size_t value=type::value;
Chris@16 352 };
Chris@16 353
Chris@16 354 /// \brief Determines whether a cross vector is empty
Chris@16 355 /// \ingroup CrossVector
Chris@16 356 template <typename VecOfVecs, typename TypeGen>
Chris@16 357 struct empty<cross_vector<VecOfVecs,TypeGen> > {
Chris@16 358 typedef typename empty<VecOfVecs>::type type;
Chris@16 359 };
Chris@16 360
Chris@16 361 /// \brief Returns the K-th element of a cross vector
Chris@16 362 /// \ingroup CrossVector
Chris@16 363 template <typename VecOfVecs, typename TypeGen, typename K>
Chris@16 364 struct at<cross_vector<VecOfVecs,TypeGen>, K> {
Chris@16 365 private:
Chris@16 366 typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator;
Chris@16 367 public:
Chris@16 368 typedef typename deref<KthIterator>::type type;
Chris@16 369 };
Chris@16 370
Chris@16 371 /// \brief Returns an iterator to the first element of a cross vector
Chris@16 372 /// \ingroup CrossVector
Chris@16 373 template <typename VecOfVecs, typename TypeGen>
Chris@16 374 struct begin<cross_vector<VecOfVecs,TypeGen> > {
Chris@16 375 typedef cross_iterator<VecOfVecs,TypeGen,0> type;
Chris@16 376 };
Chris@16 377
Chris@16 378 /// \brief Returns an iterator to the last element of a cross vector
Chris@16 379 /// \ingroup CrossVector
Chris@16 380 template <typename VecOfVecs, typename TypeGen>
Chris@16 381 struct end<cross_vector<VecOfVecs,TypeGen> > {
Chris@16 382 private:
Chris@16 383 typedef cross_vector<VecOfVecs,TypeGen> this_t;
Chris@16 384 public:
Chris@16 385 typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type;
Chris@16 386 };
Chris@16 387
Chris@16 388 /// \brief Returns the first element of a cross vector
Chris@16 389 /// \ingroup CrossVector
Chris@16 390 template <typename VecOfVecs, typename TypeGen>
Chris@16 391 struct front<cross_vector<VecOfVecs,TypeGen> > {
Chris@16 392 private:
Chris@16 393 typedef cross_vector<VecOfVecs,TypeGen> this_t;
Chris@16 394 public:
Chris@16 395 typedef typename deref<typename begin<this_t>::type>::type type;
Chris@16 396 };
Chris@16 397
Chris@16 398 /// \brief Returns the last element of a cross vector
Chris@16 399 /// \ingroup CrossVector
Chris@16 400 template <typename VecOfVecs, typename TypeGen>
Chris@16 401 struct back<cross_vector<VecOfVecs,TypeGen> > {
Chris@16 402 private:
Chris@16 403 typedef cross_vector<VecOfVecs,TypeGen> this_t;
Chris@16 404 typedef typename size<this_t>::type size;
Chris@16 405 typedef typename minus<size, size_t<1> >::type last_index;
Chris@16 406 public:
Chris@16 407 typedef typename at<this_t, last_index>::type type;
Chris@16 408 };
Chris@16 409
Chris@16 410 /// \brief Transforms the elements of a cross vector
Chris@16 411 /// \ingroup CrossVector
Chris@16 412 template <typename VecOfVecs, typename TypeGen, typename OPP>
Chris@16 413 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP > {
Chris@16 414 typedef typename lambda<OPP>::type Op;
Chris@16 415 struct adapter {
Chris@16 416 template <typename Elements>
Chris@16 417 struct apply {
Chris@16 418 typedef typename TypeGen::template apply<Elements>::type orig_t;
Chris@16 419 typedef typename Op::template apply<orig_t>::type type;
Chris@16 420 };
Chris@16 421 };
Chris@16 422 typedef cross_vector<VecOfVecs, adapter > type;
Chris@16 423 };
Chris@16 424
Chris@16 425 } } // boost::mpl
Chris@16 426
Chris@16 427 namespace boost { namespace gil {
Chris@16 428
Chris@16 429 template <typename Types, typename T> struct type_to_index;
Chris@16 430 template <typename V> struct view_is_basic;
Chris@16 431 struct rgb_t;
Chris@16 432 struct lab_t;
Chris@16 433 struct hsb_t;
Chris@16 434 struct cmyk_t;
Chris@16 435 struct rgba_t;
Chris@16 436 struct error_t;
Chris@16 437
Chris@16 438
Chris@16 439 namespace detail {
Chris@16 440 ////////////////////////////////////////////////////////
Chris@16 441 ////
Chris@16 442 //// Generic reduce operation
Chris@16 443 ////
Chris@16 444 ////////////////////////////////////////////////////////
Chris@16 445 template <typename Op, typename T>
Chris@16 446 struct reduce {
Chris@16 447 typedef T type;
Chris@16 448 };
Chris@16 449
Chris@16 450 ////////////////////////////////////////////////////////
Chris@16 451 ////
Chris@16 452 //// Unary reduce_view operation. Splits into basic and non-basic views.
Chris@16 453 //// Algorithm-specific reduce should specialize for basic views
Chris@16 454 ////
Chris@16 455 ////////////////////////////////////////////////////////
Chris@16 456
Chris@16 457 template <typename Op, typename View, bool IsBasic>
Chris@16 458 struct reduce_view_basic {
Chris@16 459 typedef View type;
Chris@16 460 };
Chris@16 461
Chris@16 462 template <typename Op, typename Loc>
Chris@16 463 struct reduce<Op, image_view<Loc> >
Chris@16 464 : public reduce_view_basic<Op,image_view<Loc>,view_is_basic<image_view<Loc> >::value> {};
Chris@16 465
Chris@16 466 ////////////////////////////////////////////////////////
Chris@16 467 ////
Chris@16 468 //// Unary reduce_image operation. Splits into basic and non-basic images.
Chris@16 469 //// Algorithm-specific reduce should specialize for basic images
Chris@16 470 ////
Chris@16 471 ////////////////////////////////////////////////////////
Chris@16 472
Chris@16 473 template <typename Op, typename Img, bool IsBasic>
Chris@16 474 struct reduce_image_basic {
Chris@16 475 typedef Img type;
Chris@16 476 };
Chris@16 477
Chris@16 478 template <typename Op, typename V, typename Alloc>
Chris@16 479 struct reduce<Op, image<V,Alloc> > : public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc> >::value > {};
Chris@16 480
Chris@16 481 ////////////////////////////////////////////////////////
Chris@16 482 ////
Chris@16 483 //// Binary reduce_view operation. Splits into basic and non-basic views.
Chris@16 484 //// Algorithm-specific reduce should specialize for basic views
Chris@16 485 ////
Chris@16 486 ////////////////////////////////////////////////////////
Chris@16 487
Chris@16 488 template <typename Op, typename V1, typename V2, bool AreBasic>
Chris@16 489 struct reduce_views_basic {
Chris@16 490 typedef std::pair<const V1*, const V2*> type;
Chris@16 491 };
Chris@16 492
Chris@16 493 template <typename Op, typename L1, typename L2>
Chris@16 494 struct reduce<Op, std::pair<const image_view<L1>*, const image_view<L2>*> >
Chris@16 495 : public reduce_views_basic<Op,image_view<L1>,image_view<L2>,
Chris@16 496 mpl::and_<view_is_basic<image_view<L1> >, view_is_basic<image_view<L2> > >::value >
Chris@16 497 {};
Chris@16 498
Chris@16 499
Chris@16 500 ////////////////////////////////////////////////////////
Chris@16 501 ////
Chris@16 502 //// Color space unary reduce operation. Reduce a color space to a base with the same number of channels
Chris@16 503 ////
Chris@16 504 ////////////////////////////////////////////////////////
Chris@16 505
Chris@16 506 template <typename Cs>
Chris@16 507 struct reduce_color_space {
Chris@16 508 typedef Cs type;
Chris@16 509 };
Chris@16 510
Chris@16 511 template <> struct reduce_color_space<lab_t> { typedef rgb_t type; };
Chris@16 512 template <> struct reduce_color_space<hsb_t> { typedef rgb_t type; };
Chris@16 513 template <> struct reduce_color_space<cmyk_t> { typedef rgba_t type; };
Chris@16 514
Chris@16 515 /*
Chris@16 516 ////////////////////////////////////////////////////////
Chris@16 517 ////
Chris@16 518 //// Color space binary reduce operation. Given a source and destination color spaces,
Chris@16 519 //// returns a reduced source and destination color spaces that have the same mapping of channels
Chris@16 520 ////
Chris@16 521 //// Precondition: The two color spaces must be compatible (i.e. must have the same set of channels)
Chris@16 522 ////////////////////////////////////////////////////////
Chris@16 523
Chris@16 524 template <typename Vec, int Basis, int VecSize>
Chris@16 525 struct type_vec_to_integer_impl {
Chris@16 526 typedef typename mpl::back<Vec>::type last;
Chris@16 527 typedef typename mpl::pop_back<Vec>::type rest;
Chris@16 528 static const int value = type_vec_to_integer_impl<rest, Basis, VecSize-1>::value * Basis + last::value;
Chris@16 529 };
Chris@16 530
Chris@16 531 template <typename Vec, int Basis>
Chris@16 532 struct type_vec_to_integer_impl<Vec,Basis,0> {
Chris@16 533 static const int value=0;
Chris@16 534 };
Chris@16 535
Chris@16 536 template <typename Vec, int Basis=10>
Chris@16 537 struct type_vec_to_integer {
Chris@16 538 static const int value = type_vec_to_integer_impl<Vec,Basis, mpl::size<Vec>::value>::value;
Chris@16 539 };
Chris@16 540
Chris@16 541 // Given two color spaces and the mapping of the channels between them, returns the reduced pair of color spaces
Chris@16 542 // The default version performs no reduction
Chris@16 543 template <typename SrcColorSpace, typename DstColorSpace, int Mapping>
Chris@16 544 struct reduce_color_spaces_impl {
Chris@16 545 typedef SrcColorSpace first_t;
Chris@16 546 typedef DstColorSpace second_t;
Chris@16 547 };
Chris@16 548
Chris@16 549 // 012: RGB-RGB, bgr-bgr, lab-lab, hsb-hsb
Chris@16 550 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 551 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,12> {
Chris@16 552 typedef rgb_t first_t;
Chris@16 553 typedef rgb_t second_t;
Chris@16 554 };
Chris@16 555
Chris@16 556 // 210: RGB-bgr, bgr-RGB
Chris@16 557 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 558 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,210> {
Chris@16 559 typedef rgb_t first_t;
Chris@16 560 typedef bgr_t second_t;
Chris@16 561 };
Chris@16 562
Chris@16 563 // 0123: RGBA-RGBA, bgra-bgra, argb-argb, abgr-abgr cmyk-cmyk
Chris@16 564 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 565 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,123> {
Chris@16 566 typedef rgba_t first_t;
Chris@16 567 typedef rgba_t second_t;
Chris@16 568 };
Chris@16 569
Chris@16 570 // 3210: RGBA-abgr, bgra-argb, argb-bgra, abgr-RGBA
Chris@16 571 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 572 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3210> {
Chris@16 573 typedef rgba_t first_t;
Chris@16 574 typedef abgr_t second_t;
Chris@16 575 };
Chris@16 576
Chris@16 577 // 1230: RGBA-argb, bgra-abgr
Chris@16 578 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 579 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,1230> {
Chris@16 580 typedef rgba_t first_t;
Chris@16 581 typedef argb_t second_t;
Chris@16 582 };
Chris@16 583
Chris@16 584 // 2103: RGBA-bgra, bgra-RGBA (uses subclass to ensure that base color space is not reduced to derived)
Chris@16 585 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 586 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,2103> {
Chris@16 587 typedef rgba_t first_t;
Chris@16 588 typedef bgra_t second_t;
Chris@16 589 };
Chris@16 590
Chris@16 591 // 3012: argb-RGBA, abgr-bgra
Chris@16 592 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 593 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3012> {
Chris@16 594 typedef argb_t first_t;
Chris@16 595 typedef rgba_t second_t;
Chris@16 596 };
Chris@16 597
Chris@16 598 // 0321: argb-abgr, abgr-argb
Chris@16 599 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 600 struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,321> {
Chris@16 601 typedef argb_t first_t;
Chris@16 602 typedef abgr_t second_t;
Chris@16 603 };
Chris@16 604
Chris@16 605 template <typename SrcColorSpace, typename DstColorSpace>
Chris@16 606 struct reduce_color_spaces {
Chris@16 607 typedef typename channel_order<SrcColorSpace>::type src_order_t;
Chris@16 608 typedef typename channel_order<DstColorSpace>::type dst_order_t;
Chris@16 609 typedef typename mpl::transform<src_order_t, type_to_index<dst_order_t,mpl::_1> >::type mapping;
Chris@16 610 static const int mapping_val = type_vec_to_integer<mapping>::value;
Chris@16 611
Chris@16 612 typedef typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::first_t _first_t;
Chris@16 613 typedef typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::second_t _second_t;
Chris@16 614 typedef typename mpl::and_<color_space_is_base<DstColorSpace>, mpl::not_< color_space_is_base<_second_t> > > swap_t;
Chris@16 615 public:
Chris@16 616 typedef typename mpl::if_<swap_t, _second_t, _first_t>::type first_t;
Chris@16 617 typedef typename mpl::if_<swap_t, _first_t, _second_t>::type second_t;
Chris@16 618 };
Chris@16 619 */
Chris@16 620 // TODO: Use the old code for reduce_color_spaces above to do color layout reduction
Chris@16 621 template <typename SrcLayout, typename DstLayout>
Chris@16 622 struct reduce_color_layouts {
Chris@16 623 typedef SrcLayout first_t;
Chris@16 624 typedef DstLayout second_t;
Chris@16 625 };
Chris@16 626
Chris@16 627 ////////////////////////////////////////////////////////
Chris@16 628 ////
Chris@16 629 //// Reduce for copy_pixels
Chris@16 630 ////
Chris@16 631 ////////////////////////////////////////////////////////
Chris@16 632
Chris@16 633 struct copy_pixels_fn;
Chris@16 634
Chris@16 635 /*
Chris@16 636 // 1D reduce for copy_pixels reduces the channel to mutable and the color space to its base with same dimensions
Chris@16 637 template <typename View>
Chris@16 638 struct reduce_view_basic<copy_pixels_fn,View,true> {
Chris@16 639 private:
Chris@16 640 typedef typename reduce_color_space<typename View::color_space_t>::type Cs; // reduce the color space
Chris@16 641 typedef layout<Cs, typename View::channel_mapping_t> layout_t;
Chris@16 642 public:
Chris@16 643 typedef typename derived_view_type<View, use_default, layout_t, use_default, use_default, mpl::true_>::type type;
Chris@16 644 };
Chris@16 645 */
Chris@16 646 // Incompatible views cannot be used in copy_pixels - will throw std::bad_cast
Chris@16 647 template <typename V1, typename V2, bool Compatible>
Chris@16 648 struct reduce_copy_pixop_compat {
Chris@16 649 typedef error_t type;
Chris@16 650 };
Chris@16 651
Chris@16 652 // For compatible basic views, reduce their color spaces based on their channel mapping.
Chris@16 653 // Make the source immutable and the destination mutable (they should already be that way)
Chris@16 654 template <typename V1, typename V2>
Chris@16 655 struct reduce_copy_pixop_compat<V1,V2,true> {
Chris@16 656 typedef layout<typename V1::color_space_t, typename V1::channel_mapping_t> layout1;
Chris@16 657 typedef layout<typename V2::color_space_t, typename V2::channel_mapping_t> layout2;
Chris@16 658
Chris@16 659 typedef typename reduce_color_layouts<layout1,layout2>::first_t L1;
Chris@16 660 typedef typename reduce_color_layouts<layout1,layout2>::second_t L2;
Chris@16 661
Chris@16 662 typedef typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type DV1;
Chris@16 663 typedef typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type DV2;
Chris@16 664
Chris@16 665 typedef std::pair<const DV1*, const DV2*> type;
Chris@16 666 };
Chris@16 667
Chris@16 668 // The general 2D version branches into compatible and incompatible views
Chris@16 669 template <typename V1, typename V2>
Chris@16 670 struct reduce_views_basic<copy_pixels_fn, V1, V2, true>
Chris@16 671 : public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2> >::value > {
Chris@16 672 };
Chris@16 673
Chris@16 674 ////////////////////////////////////////////////////////
Chris@16 675 ////
Chris@16 676 //// Reduce for variant destructor (basic views have no destructor)
Chris@16 677 ////
Chris@16 678 ////////////////////////////////////////////////////////
Chris@16 679
Chris@16 680 struct destructor_op;
Chris@16 681 template <typename View> struct reduce_view_basic<destructor_op,View,true> { typedef gray8_view_t type; };
Chris@16 682
Chris@16 683 ////////////////////////////////////////////////////////
Chris@16 684 ////
Chris@16 685 //// Reduce for get_dimensions (basic views and images have the same structure and the dimensions are contained at the beginning)
Chris@16 686 ////
Chris@16 687 ////////////////////////////////////////////////////////
Chris@16 688
Chris@16 689 struct any_type_get_dimensions;
Chris@16 690 template <typename View> struct reduce_view_basic<any_type_get_dimensions,View,true> { typedef gray8_view_t type; };
Chris@16 691 template <typename Img> struct reduce_image_basic<any_type_get_dimensions,Img,true> { typedef gray8_image_t type; };
Chris@16 692
Chris@16 693 ////////////////////////////////////////////////////////
Chris@16 694 ////
Chris@16 695 //// Reduce for get_num_channels (only color space matters)
Chris@16 696 ////
Chris@16 697 ////////////////////////////////////////////////////////
Chris@16 698
Chris@16 699 struct any_type_get_num_channels;
Chris@16 700 template <typename View> struct reduce_view_basic<any_type_get_num_channels,View,true> {
Chris@16 701 typedef typename View::color_space_t::base Cs;
Chris@16 702 typedef typename view_type<bits8,typename reduce_color_space<Cs>::type>::type type;
Chris@16 703 };
Chris@16 704 template <typename Img> struct reduce_image_basic<any_type_get_num_channels,Img,true> {
Chris@16 705 typedef typename Img::color_space_t::base Cs;
Chris@16 706 typedef typename image_type<bits8,typename reduce_color_space<Cs>::type>::type type;
Chris@16 707 };
Chris@16 708
Chris@16 709 ////////////////////////////////////////////////////////
Chris@16 710 ////
Chris@16 711 //// Reduce for resample_pixels (same as copy_pixels)
Chris@16 712 ////
Chris@16 713 ////////////////////////////////////////////////////////
Chris@16 714
Chris@16 715 template <typename Sampler, typename MapFn> struct resample_pixels_fn;
Chris@16 716
Chris@16 717 template <typename S, typename M, typename V, bool IsBasic>
Chris@16 718 struct reduce_view_basic<resample_pixels_fn<S,M>, V, IsBasic> : public reduce_view_basic<copy_pixels_fn, V, IsBasic> {};
Chris@16 719
Chris@16 720 template <typename S, typename M, typename V1, typename V2, bool IsBasic>
Chris@16 721 struct reduce_views_basic<resample_pixels_fn<S,M>, V1, V2, IsBasic> : public reduce_views_basic<copy_pixels_fn, V1, V2, IsBasic> {};
Chris@16 722
Chris@16 723 ////////////////////////////////////////////////////////
Chris@16 724 ////
Chris@16 725 //// Reduce for copy_and_convert_pixels
Chris@16 726 //// (the only reduction could be made when views are compatible and have the same mapping, planarity and stepness)
Chris@16 727 ////
Chris@16 728 ////////////////////////////////////////////////////////
Chris@16 729
Chris@16 730
Chris@16 731 template <typename CC> class copy_and_convert_pixels_fn;
Chris@16 732
Chris@16 733 // the only thing for 1D reduce is making them all mutable...
Chris@16 734 template <typename CC, typename View, bool IsBasic>
Chris@16 735 struct reduce_view_basic<copy_and_convert_pixels_fn<CC>, View, IsBasic>
Chris@16 736 : public derived_view_type<View, use_default, use_default, use_default, use_default, mpl::true_> {
Chris@16 737 };
Chris@16 738
Chris@16 739 // For 2D reduce, if they have the same channels and color spaces (i.e. the same pixels) then copy_and_convert is just copy.
Chris@16 740 // In this case, reduce their common color space. In general make the first immutable and the second mutable
Chris@16 741 template <typename CC, typename V1, typename V2, bool AreBasic>
Chris@16 742 struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic> {
Chris@16 743 typedef is_same<typename V1::pixel_t, typename V2::pixel_t> Same;
Chris@16 744
Chris@16 745 typedef reduce_color_space<typename V1::color_space_t::base> CsR;
Chris@16 746 typedef typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type Cs1;
Chris@16 747 typedef typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type Cs2;
Chris@16 748
Chris@16 749 typedef typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type DV1;
Chris@16 750 typedef typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type DV2;
Chris@16 751
Chris@16 752 typedef std::pair<const DV1*, const DV2*> type;
Chris@16 753 };
Chris@16 754
Chris@16 755
Chris@16 756 //integral_image_generator
Chris@16 757 //resize_clobber_image_fnobj
Chris@16 758 //image_default_construct_fnobj
Chris@16 759 //fill_converted_pixels_fn
Chris@16 760 //bind(gil::detail::copy_pixels_fn(), _1, dst)
Chris@16 761 //bind(gil::detail::copy_pixels_fn(), src,_1)
Chris@16 762
Chris@16 763 //bind(detail::copy_and_convert_pixels_fn(), _1, dst)
Chris@16 764 //bind(detail::copy_and_convert_pixels_fn(), src, _1)
Chris@16 765 //gil::detail::fill_pixels_fn<Value>(val)
Chris@16 766
Chris@16 767 //detail::copy_construct_in_place_fn<base_t>
Chris@16 768 //detail::equal_to_fn<typename variant<Types>::base_t>
Chris@16 769
Chris@16 770 //detail::any_image_get_view<typename any_image<Types>::view_t>
Chris@16 771 //detail::any_image_get_const_view<typename any_image<Types>::view_t>
Chris@16 772 //detail::flipped_up_down_view_fn<any_image_view<ViewTypes> >
Chris@16 773 //detail::flipped_left_right_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
Chris@16 774 //detail::tranposed_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
Chris@16 775 //detail::rotated90cw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
Chris@16 776 //detail::rotated90ccw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
Chris@16 777 //detail::rotated180_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
Chris@16 778 //detail::subimage_view_fn<any_image_view<ViewTypes> >
Chris@16 779 //detail::subsampled_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
Chris@16 780 //detail::nth_channel_view_fn<typename nth_channel_view_type<any_image_view<ViewTypes> >
Chris@16 781 //detail::color_converted_view_fn<DstP,typename color_convert_view_type<any_image_view<ViewTypes>, DstP>::type >
Chris@16 782 }
Chris@16 783
Chris@16 784 } } // namespace boost::gil
Chris@16 785
Chris@16 786 #endif // GIL_REDUCE_CODE_BLOAT
Chris@16 787
Chris@16 788
Chris@16 789 #endif