Boost GIL


reduce.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_EXTENSION_DYNAMIC_IMAGE_GIL_REDUCE_HPP
9 #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_GIL_REDUCE_HPP
10 
11 #ifdef BOOST_GIL_DOXYGEN_ONLY
12 #undef BOOST_GIL_REDUCE_CODE_BLOAT
13 #endif
14 
15 // The techniques implemented here are discussed in the paper
16 // "Efficient Run-Time Dispatching in Generic Programming with Minimal Code Bloat"
17 // by Lubomir Bourdev, Jaakko Jarvi
18 // http://lubomir.org/academic/MinimizingCodeBloat.pdf
19 #ifdef BOOST_GIL_REDUCE_CODE_BLOAT
20 
21 #include <boost/gil/extension/dynamic_image/dynamic_at_c.hpp>
22 
23 #include <boost/gil/metafunctions.hpp>
24 #include <boost/gil/typedefs.hpp>
25 
26 #include <boost/mpl/back.hpp>
27 #include <boost/mpl/insert.hpp>
28 #include <boost/mpl/insert_range.hpp>
29 #include <boost/mpl/long.hpp>
30 #include <boost/mpl/logical.hpp>
31 #include <boost/mpl/range_c.hpp>
32 #include <boost/mpl/vector.hpp>
33 #include <boost/mpl/vector_c.hpp>
34 #include <boost/mpl/transform.hpp>
35 
36 #include <type_traits>
37 
38 // Max number of cases in the cross-expension of binary operation for it to be reduced as unary
39 #define BOOST_GIL_BINARY_REDUCE_LIMIT 226
40 
41 namespace boost { namespace mpl {
42 
43 // Constructs for static-to-dynamic integer convesion
44 
53 
54 template <typename SrcTypes, typename DstTypes>
55 struct mapping_vector {};
56 
57 template <typename SrcTypes, typename DstTypes, long K>
58 struct at_c<mapping_vector<SrcTypes,DstTypes>, K>
59 {
60  static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename gil::at_c<SrcTypes,K>::type>::value +1;
61  using type = size_t<value>;
62 };
63 
64 template <typename SrcTypes, typename DstTypes>
65 struct size<mapping_vector<SrcTypes,DstTypes>>
66 {
67  using type = typename size<SrcTypes>::type;
68  static const std::size_t value=type::value;
69 };
70 
79 
80 namespace detail {
81  template <typename SFirst, std::size_t NLeft>
82  struct copy_to_vector_impl {
83  private:
84  using T = typename deref<SFirst>::type;
85  using next = typename next<SFirst>::type;
86  using rest = typename copy_to_vector_impl<next, NLeft-1>::type;
87  public:
88  using type = typename push_front<rest, T>::type;
89  };
90 
91  template <typename SFirst>
92  struct copy_to_vector_impl<SFirst,1>
93  {
94  using type = vector<typename deref<SFirst>::type>;
95  };
96 }
97 
98 template <typename Src>
99 struct copy_to_vector
100 {
101  using type = typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type;
102 };
103 
104 template <>
105 struct copy_to_vector<set<>>
106 {
107  using type = vector0<>;
108 };
109 
110 } } // boost::mpl
111 
112 namespace boost { namespace gil {
113 
114 
122 
123 
124 
125 
135 
136 template <typename Types, typename Op>
137 struct unary_reduce_impl {
138  using reduced_t = typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type;
139  using unique_t = typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2>>>::type;
140  static const bool is_single=mpl::size<unique_t>::value==1;
141 };
142 
143 template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>
144 struct unary_reduce : public unary_reduce_impl<Types,Op>
145 {
146  using reduced_t = typename unary_reduce_impl<Types,Op>::reduced_t;
147  using unique_t = typename unary_reduce_impl<Types,Op>::unique_t;
148 
149  static unsigned short inline map_index(std::size_t index)
150  {
151  using indices_t = typename mpl::mapping_vector<reduced_t, unique_t>;
152  return gil::at_c<indices_t, unsigned short>(index);
153  }
154  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
155  return apply_operation_basec<unique_t>(bits,map_index(index),op);
156  }
157 
158  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
159  return apply_operation_base<unique_t>(bits,map_index(index),op);
160  }
161 };
162 
163 template <typename Types, typename Op>
164 struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {
165  using unique_t = typename unary_reduce_impl<Types,Op>::unique_t;
166  static unsigned short inline map_index(std::size_t index) { return 0; }
167 
168  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
169  return op(*gil_reinterpret_cast_c<const typename mpl::front<unique_t>::type*>(&bits));
170  }
171 
172  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
173  return op(*gil_reinterpret_cast<typename mpl::front<unique_t>::type*>(&bits));
174  }
175 };
176 
177 
190 
191 namespace detail {
192  struct pair_generator {
193  template <typename Vec2> struct apply
194  {
195  using type = std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::type*>;
196  };
197  };
198 
199  // When the types are not too large, applies reduce on their cross product
200  template <typename Unary1, typename Unary2, typename Op, bool IsComplex>
201  struct binary_reduce_impl
202  {
203  //private:
204  using vec1_types = typename mpl::copy_to_vector<typename Unary1::unique_t>::type;
205  using vec2_types = typename mpl::copy_to_vector<typename Unary2::unique_t>::type;
206 
207  using BIN_TYPES = mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator>;
208  using bin_reduced_t = unary_reduce<BIN_TYPES,Op>;
209 
210  static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
211  unsigned short r1=Unary1::map_index(index1);
212  unsigned short r2=Unary2::map_index(index2);
213  return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);
214  }
215  public:
216  using unique_t = typename bin_reduced_t::unique_t
217 
218  template <typename Bits1, typename Bits2>
219  static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
220  std::pair<const void*,const void*> pr(&bits1, &bits2);
221  return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
222  }
223  };
224 
225  // When the types are large performs a double-dispatch. Binary reduction is not done.
226  template <typename Unary1, typename Unary2, typename Op>
227  struct binary_reduce_impl<Unary1,Unary2,Op,true> {
228  template <typename Bits1, typename Bits2>
229  static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
230  return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);
231  }
232  };
233 }
234 
235 
236 template <typename Types1, typename Types2, typename Op>
237 struct binary_reduce
238 {
239 //private:
240  using unary1_t = unary_reduce<Types1,Op>;
241  using unary2_t = unary_reduce<Types2,Op>;
242 
243  static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
244  mpl::size<typename unary2_t::unique_t>::value;
245 
246  using impl = detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>BOOST_GIL_BINARY_REDUCE_LIMIT)>;
247 public:
248  template <typename Bits1, typename Bits2>
249  static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
250  return impl::apply(bits1,index1,bits2,index2,op);
251  }
252 };
253 
254 template <typename Types, typename UnaryOp>
255 BOOST_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
256  return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);
257 }
258 
259 template <typename Types, typename UnaryOp>
260 BOOST_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant<Types>& arg, UnaryOp op) {
261  return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);
262 }
263 
264 template <typename Types1, typename Types2, typename BinaryOp>
265 BOOST_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {
266  return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
267 }
268 
269 #undef BOOST_GIL_BINARY_REDUCE_LIMIT
270 
271 } } // namespace gil
272 
273 
274 namespace boost { namespace mpl {
293 
294 template <typename VecOfVecs, typename TypeGen>
295 struct cross_vector {};
296 
299 template <typename VecOfVecs, typename TypeGen, std::size_t K>
300 struct cross_iterator
301 {
302  using category = mpl::random_access_iterator_tag;
303 };
304 
308 
314 template <typename VecOfVecs, typename TypeGen, std::size_t K>
315 struct deref<cross_iterator<VecOfVecs,TypeGen,K>>
316 {
317 private:
318  using DerefTypes = typename detail::select_subvector_c<VecOfVecs, K>::type;
319 public:
320  using type = typename TypeGen::template apply<DerefTypes>::type;
321 };
322 
325 template <typename VecOfVecs, typename TypeGen, std::size_t K>
326 struct next<cross_iterator<VecOfVecs,TypeGen,K>>
327 {
328  using type = cross_iterator<VecOfVecs,TypeGen,K+1>;
329 };
330 
333 template <typename VecOfVecs, typename TypeGen, std::size_t K>
334 struct prior<cross_iterator<VecOfVecs,TypeGen,K>>
335 {
336  using type = cross_iterator<VecOfVecs,TypeGen,K-1>;
337 };
338 
341 template <typename VecOfVecs, typename TypeGen, std::size_t K, typename Distance>
342 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance>
343 {
344  using type = cross_iterator<VecOfVecs,TypeGen,K+Distance::value>;
345 };
346 
349 // (shortened the names of the template arguments - otherwise doxygen cannot parse this...)
350 template <typename VecOfVecs, typename TypeGen, std::size_t K1, std::size_t K2>
351 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2>>
352 {
353  using type = size_t<K2-K1>;
354 };
355 
361 template <typename VecOfVecs, typename TypeGen>
362 struct size<cross_vector<VecOfVecs,TypeGen>>
363 {
364  using type = typename fold<VecOfVecs, size_t<1>, times<_1, size<_2>>>::type;
365  static const std::size_t value=type::value;
366 };
367 
370 template <typename VecOfVecs, typename TypeGen>
371 struct empty<cross_vector<VecOfVecs,TypeGen>> {
372  using type = typename empty<VecOfVecs>::type;
373 };
374 
377 template <typename VecOfVecs, typename TypeGen, typename K>
378 struct at<cross_vector<VecOfVecs,TypeGen>, K>
379 {
380 private:
381  using KthIterator = cross_iterator<VecOfVecs,TypeGen,K::value>;
382 public:
383  using type = typename deref<KthIterator>::type;
384 };
385 
388 template <typename VecOfVecs, typename TypeGen>
389 struct begin<cross_vector<VecOfVecs,TypeGen>>
390 {
391  using type = cross_iterator<VecOfVecs,TypeGen,0>;
392 };
393 
396 template <typename VecOfVecs, typename TypeGen>
397 struct end<cross_vector<VecOfVecs,TypeGen>>
398 {
399 private:
400  using this_t = cross_vector<VecOfVecs,TypeGen>;
401 public:
402  using type = cross_iterator<VecOfVecs,TypeGen,size<this_t>::value>;
403 };
404 
407 template <typename VecOfVecs, typename TypeGen>
408 struct front<cross_vector<VecOfVecs,TypeGen>> {
409 private:
410  using this_t = cross_vector<VecOfVecs,TypeGen>;
411 public:
412  using type = typename deref<typename begin<this_t>::type>::type;
413 };
414 
417 template <typename VecOfVecs, typename TypeGen>
418 struct back<cross_vector<VecOfVecs,TypeGen>>
419 {
420 private:
421  using this_t = cross_vector<VecOfVecs,TypeGen>;
422  using size = typename size<this_t>::type;
423  using last_index = typename minus<size, size_t<1>>::type;
424 public:
425  using type = typename at<this_t, last_index>::type;
426 };
427 
430 template <typename VecOfVecs, typename TypeGen, typename OPP>
431 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP>
432 {
433  using Op = typename lambda<OPP>::type;
434  struct adapter
435  {
436  template <typename Elements>
437  struct apply
438  {
439  using orig_t = typename TypeGen::template apply<Elements>::type;
440  using type = typename Op::template apply<orig_t>::type;
441  };
442  };
443  using type = cross_vector<VecOfVecs, adapter>;
444 };
445 
446 } } // boost::mpl
447 
448 namespace boost { namespace gil {
449 
450 template <typename Types, typename T> struct type_to_index;
451 template <typename V> struct view_is_basic;
452 struct rgb_t;
453 struct lab_t;
454 struct hsb_t;
455 struct cmyk_t;
456 struct rgba_t;
457 struct error_t;
458 
459 
460 namespace detail {
466  template <typename Op, typename T>
467  struct reduce
468  {
469  using type = T;
470  };
471 
478 
479  template <typename Op, typename View, bool IsBasic>
480  struct reduce_view_basic
481  {
482  using type = View;
483  };
484 
485  template <typename Op, typename Loc>
486  struct reduce<Op, image_view<Loc>>
487  : public reduce_view_basic<Op,image_view<Loc>,view_is_basic<image_view<Loc>>::value> {};
488 
495 
496  template <typename Op, typename Img, bool IsBasic>
497  struct reduce_image_basic
498  {
499  using type = Img;
500  };
501 
502  template <typename Op, typename V, typename Alloc>
503  struct reduce<Op, image<V,Alloc>> : public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc>>::value > {};
504 
511 
512  template <typename Op, typename V1, typename V2, bool AreBasic>
513  struct reduce_views_basic
514  {
515  using type = std::pair<const V1*, const V2*>;
516  };
517 
518  template <typename Op, typename L1, typename L2>
519  struct reduce<Op, std::pair<const image_view<L1>*, const image_view<L2>*>>
520  : public reduce_views_basic<Op,image_view<L1>,image_view<L2>,
521  mpl::and_<view_is_basic<image_view<L1>>, view_is_basic<image_view<L2>>>::value >
522  {};
523 
524 
530 
531  template <typename CS>
532  struct reduce_color_space
533  {
534  using type = CS;
535  };
536 
537  template <> struct reduce_color_space<lab_t> { using type = rgb_t; };
538  template <> struct reduce_color_space<hsb_t> { using type = rgb_t; };
539  template <> struct reduce_color_space<cmyk_t> { using type = rgba_t; };
540 
541  /*
549 
550  template <typename Vec, int Basis, int VecSize>
551  struct type_vec_to_integer_impl {
552  using last = typename mpl::back<Vec>::type;
553  using rest = typename mpl::pop_back<Vec>::type;
554  static const int value = type_vec_to_integer_impl<rest, Basis, VecSize-1>::value * Basis + last::value;
555  };
556 
557  template <typename Vec, int Basis>
558  struct type_vec_to_integer_impl<Vec,Basis,0> {
559  static const int value=0;
560  };
561 
562  template <typename Vec, int Basis=10>
563  struct type_vec_to_integer {
564  static const int value = type_vec_to_integer_impl<Vec,Basis, mpl::size<Vec>::value>::value;
565  };
566 
567  // Given two color spaces and the mapping of the channels between them, returns the reduced pair of color spaces
568  // The default version performs no reduction
569  template <typename SrcColorSpace, typename DstColorSpace, int Mapping>
570  struct reduce_color_spaces_impl {
571  using first_t = SrcColorSpace;
572  using second_t = DstColorSpace;
573  };
574 
575  // 012: RGB-RGB, bgr-bgr, lab-lab, hsb-hsb
576  template <typename SrcColorSpace, typename DstColorSpace>
577  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,12> {
578  using first_t = rgb_t;
579  using second_t = rgb_t;
580  };
581 
582  // 210: RGB-bgr, bgr-RGB
583  template <typename SrcColorSpace, typename DstColorSpace>
584  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,210> {
585  using first_t = rgb_t;
586  using second_t = bgr_t;
587  };
588 
589  // 0123: RGBA-RGBA, bgra-bgra, argb-argb, abgr-abgr cmyk-cmyk
590  template <typename SrcColorSpace, typename DstColorSpace>
591  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,123> {
592  using first_t = rgba_t;
593  using second_t = rgba_t;
594  };
595 
596  // 3210: RGBA-abgr, bgra-argb, argb-bgra, abgr-RGBA
597  template <typename SrcColorSpace, typename DstColorSpace>
598  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3210> {
599  using first_t = rgba_t;
600  using second_t = abgr_t;
601  };
602 
603  // 1230: RGBA-argb, bgra-abgr
604  template <typename SrcColorSpace, typename DstColorSpace>
605  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,1230> {
606  using first_t = rgba_t;
607  using second_t = argb_t;
608  };
609 
610  // 2103: RGBA-bgra, bgra-RGBA (uses subclass to ensure that base color space is not reduced to derived)
611  template <typename SrcColorSpace, typename DstColorSpace>
612  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,2103> {
613  using first_t = rgba_t;
614  using second_t = bgra_t;
615  };
616 
617  // 3012: argb-RGBA, abgr-bgra
618  template <typename SrcColorSpace, typename DstColorSpace>
619  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3012> {
620  using first_t = argb_t;
621  using second_t = rgba_t;
622  };
623 
624  // 0321: argb-abgr, abgr-argb
625  template <typename SrcColorSpace, typename DstColorSpace>
626  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,321> {
627  using first_t = argb_t;
628  using second_t = abgr_t;
629  };
630 
631  template <typename SrcColorSpace, typename DstColorSpace>
632  struct reduce_color_spaces {
633  using src_order_t = typename channel_order<SrcColorSpace>::type;
634  using dst_order_t = typename channel_order<DstColorSpace>::type;
635  using mapping = typename mpl::transform<src_order_t, type_to_index<dst_order_t,mpl::_1>>::type;
636  static const int mapping_val = type_vec_to_integer<mapping>::value;
637 
638  using _first_t = typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::first_t;
639  using _second_t = typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::second_t;
640  using swap_t = typename mpl::and_<color_space_is_base<DstColorSpace>, mpl::not_< color_space_is_base<_second_t>>>;
641  public:
642  using first_t = typename mpl::if_<swap_t, _second_t, _first_t>::type;
643  using second_t = typename mpl::if_<swap_t, _first_t, _second_t>::type;
644  };
645 */
646 // TODO: Use the old code for reduce_color_spaces above to do color layout reduction
647  template <typename SrcLayout, typename DstLayout>
648  struct reduce_color_layouts
649  {
650  using first_t = SrcLayout;
651  using second_t = DstLayout;
652  };
653 
659 
660  struct copy_pixels_fn;
661 
662  /*
663  // 1D reduce for copy_pixels reduces the channel to mutable and the color space to its base with same dimensions
664  template <typename View>
665  struct reduce_view_basic<copy_pixels_fn,View,true> {
666  private:
667  using color_space_t = typename reduce_color_space<typename View::color_space_t>::type color_space_t; // reduce the color space
668  using layout_t = layout<color_space_t, typename View::channel_mapping_t>;
669  public:
670  using type = typename derived_view_type<View, use_default, layout_t, use_default, use_default, mpl::true_>::type;
671  };
672 */
673  // Incompatible views cannot be used in copy_pixels - will throw std::bad_cast
674  template <typename V1, typename V2, bool Compatible>
675  struct reduce_copy_pixop_compat
676  {
677  using type = error_t;
678  };
679 
680  // For compatible basic views, reduce their color spaces based on their channel mapping.
681  // Make the source immutable and the destination mutable (they should already be that way)
682  template <typename V1, typename V2>
683  struct reduce_copy_pixop_compat<V1,V2,true>
684  {
685  using layout1 = layout<typename V1::color_space_t, typename V1::channel_mapping_t>;
686  using layout2 = layout<typename V2::color_space_t, typename V2::channel_mapping_t>;
687 
688  using L1 = typename reduce_color_layouts<layout1,layout2>::first_t;
689  using L2 = typename reduce_color_layouts<layout1,layout2>::second_t;
690 
691  using DV1 = typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type;
692  using DV2 = typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type;
693 
694  using type = std::pair<const DV1*, const DV2*>;
695  };
696 
697  // The general 2D version branches into compatible and incompatible views
698  template <typename V1, typename V2>
699  struct reduce_views_basic<copy_pixels_fn, V1, V2, true>
700  : public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2>>::value > {
701  };
702 
708 
709  struct destructor_op;
710  template <typename View>
711  struct reduce_view_basic<destructor_op,View,true>
712  {
713  using type = gray8_view_t;
714  };
715 
721 
722  struct any_type_get_dimensions;
723 
724  template <typename View>
725  struct reduce_view_basic<any_type_get_dimensions,View,true>
726  {
727  using type = gray8_view_t;
728  };
729 
730  template <typename Img>
731  struct reduce_image_basic<any_type_get_dimensions,Img,true>
732  {
733  using type = gray8_image_t;
734  };
735 
741 
742  struct any_type_get_num_channels;
743 
744  template <typename View>
745  struct reduce_view_basic<any_type_get_num_channels,View,true>
746  {
747  using color_space_t = typename View::color_space_t::base;
748  using type = typename view_type<uint8_t,typename reduce_color_space<color_space_t>::type>::type;
749  };
750 
751  template <typename Img>
752  struct reduce_image_basic<any_type_get_num_channels,Img,true>
753  {
754  using color_space_t = typename Img::color_space_t::base;
755  using type = typename image_type<uint8_t,typename reduce_color_space<color_space_t>::type>::type;
756  };
757 
763 
764  template <typename Sampler, typename MapFn> struct resample_pixels_fn;
765 
766  template <typename S, typename M, typename V, bool IsBasic>
767  struct reduce_view_basic<resample_pixels_fn<S,M>, V, IsBasic> : public reduce_view_basic<copy_pixels_fn, V, IsBasic> {};
768 
769  template <typename S, typename M, typename V1, typename V2, bool IsBasic>
770  struct reduce_views_basic<resample_pixels_fn<S,M>, V1, V2, IsBasic> : public reduce_views_basic<copy_pixels_fn, V1, V2, IsBasic> {};
771 
778 
779 
780  template <typename CC> class copy_and_convert_pixels_fn;
781 
782  // the only thing for 1D reduce is making them all mutable...
783  template <typename CC, typename View, bool IsBasic>
784  struct reduce_view_basic<copy_and_convert_pixels_fn<CC>, View, IsBasic>
785  : public derived_view_type<View, use_default, use_default, use_default, use_default, mpl::true_> {
786  };
787 
788  // For 2D reduce, if they have the same channels and color spaces (i.e. the same pixels) then copy_and_convert is just copy.
789  // In this case, reduce their common color space. In general make the first immutable and the second mutable
790  template <typename CC, typename V1, typename V2, bool AreBasic>
791  struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic>
792  {
793  using Same = std::is_same<typename V1::pixel_t, typename V2::pixel_t>;
794 
795  using CsR = reduce_color_space<typename V1::color_space_t::base>;
796  using Cs1 = typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type;
797  using Cs2 = typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type;
798 
799  using DV1 = typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type;
800  using DV2 = typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type;
801 
802  using type = std::pair<const DV1*, const DV2*>;
803  };
804 
805 
806  //integral_image_generator
807  //resize_clobber_image_fnobj
808  //image_default_construct_fnobj
809  //fill_converted_pixels_fn
810  //std::bind(gil::detail::copy_pixels_fn(), std::placeholders::_1, dst)
811  //std::bind(gil::detail::copy_pixels_fn(), src, std::placeholders::_1)
812 
813  //std::bind(detail::copy_and_convert_pixels_fn(), std::placeholders::_1, dst)
814  //std::bind(detail::copy_and_convert_pixels_fn(), src, std::placeholders::_1)
815  //gil::detail::fill_pixels_fn<Value>(val)
816 
817  //detail::copy_construct_in_place_fn<base_t>
818  //detail::equal_to_fn<typename variant<Types>::base_t>
819 
820  //detail::any_image_get_view<typename any_image<Types>::view_t>
821  //detail::any_image_get_const_view<typename any_image<Types>::view_t>
822  //detail::flipped_up_down_view_fn<any_image_view<ViewTypes>>
823  //detail::flipped_left_right_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
824  //detail::tranposed_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
825  //detail::rotated90cw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
826  //detail::rotated90ccw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
827  //detail::rotated180_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
828  //detail::subimage_view_fn<any_image_view<ViewTypes>>
829  //detail::subsampled_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
830  //detail::nth_channel_view_fn<typename nth_channel_view_type<any_image_view<ViewTypes>>
831  //detail::color_converted_view_fn<DstP,typename color_convert_view_type<any_image_view<ViewTypes>, DstP>::type >
832 }
833 
834 }} // namespace boost::gil
835 
836 #endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT)
837 
838 #endif
Definition: algorithm.hpp:30
Definition: algorithm.hpp:133
BOOST_FORCEINLINE auto apply_operation(variant< Types > &arg, UnaryOp op)
Invokes a generic mutable operation (represented as a unary function object) on a variant...
Definition: apply_operation.hpp:33
auto at_c(detail::homogeneous_color_base< E, L, N > &p) -> typename std::add_lvalue_reference< E >::type
Provides mutable access to the K-th element, in physical order.
Definition: color_base.hpp:597