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 #ifdef BOOST_GIL_REDUCE_CODE_BLOAT
16 
17 #include <boost/gil/extension/dynamic_image/dynamic_at_c.hpp>
18 
19 #include <boost/gil/metafunctions.hpp>
20 #include <boost/gil/typedefs.hpp>
21 
22 #include <boost/mpl/back.hpp>
23 #include <boost/mpl/insert.hpp>
24 #include <boost/mpl/insert_range.hpp>
25 #include <boost/mpl/long.hpp>
26 #include <boost/mpl/logical.hpp>
27 #include <boost/mpl/range_c.hpp>
28 #include <boost/mpl/vector.hpp>
29 #include <boost/mpl/vector_c.hpp>
30 #include <boost/mpl/transform.hpp>
31 
32 #include <type_traits>
33 
34 // Max number of cases in the cross-expension of binary operation for it to be reduced as unary
35 #define GIL_BINARY_REDUCE_LIMIT 226
36 
37 namespace boost { namespace mpl {
38 
39 // Constructs for static-to-dynamic integer convesion
40 
49 
50 template <typename SrcTypes, typename DstTypes>
51 struct mapping_vector {};
52 
53 template <typename SrcTypes, typename DstTypes, long K>
54 struct at_c<mapping_vector<SrcTypes,DstTypes>, K>
55 {
56  static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename gil::at_c<SrcTypes,K>::type>::value +1;
57  using type = size_t<value>;
58 };
59 
60 template <typename SrcTypes, typename DstTypes>
61 struct size<mapping_vector<SrcTypes,DstTypes>>
62 {
63  using type = typename size<SrcTypes>::type;
64  static const std::size_t value=type::value;
65 };
66 
75 
76 namespace detail {
77  template <typename SFirst, std::size_t NLeft>
78  struct copy_to_vector_impl {
79  private:
80  using T = typename deref<SFirst>::type;
81  using next = typename next<SFirst>::type;
82  using rest = typename copy_to_vector_impl<next, NLeft-1>::type;
83  public:
84  using type = typename push_front<rest, T>::type;
85  };
86 
87  template <typename SFirst>
88  struct copy_to_vector_impl<SFirst,1>
89  {
90  using type = vector<typename deref<SFirst>::type>;
91  };
92 }
93 
94 template <typename Src>
95 struct copy_to_vector
96 {
97  using type = typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type;
98 };
99 
100 template <>
101 struct copy_to_vector<set<>>
102 {
103  using type = vector0<>;
104 };
105 
106 } } // boost::mpl
107 
108 namespace boost { namespace gil {
109 
110 
118 
119 
120 
121 
131 
132 template <typename Types, typename Op>
133 struct unary_reduce_impl {
134  using reduced_t = typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type;
135  using unique_t = typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2>>>::type;
136  static const bool is_single=mpl::size<unique_t>::value==1;
137 };
138 
139 template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>
140 struct unary_reduce : public unary_reduce_impl<Types,Op>
141 {
142  using reduced_t = typename unary_reduce_impl<Types,Op>::reduced_t;
143  using unique_t = typename unary_reduce_impl<Types,Op>::unique_t;
144 
145  static unsigned short inline map_index(std::size_t index)
146  {
147  using indices_t = typename mpl::mapping_vector<reduced_t, unique_t>;
148  return gil::at_c<indices_t, unsigned short>(index);
149  }
150  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
151  return apply_operation_basec<unique_t>(bits,map_index(index),op);
152  }
153 
154  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
155  return apply_operation_base<unique_t>(bits,map_index(index),op);
156  }
157 };
158 
159 template <typename Types, typename Op>
160 struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {
161  using unique_t = typename unary_reduce_impl<Types,Op>::unique_t;
162  static unsigned short inline map_index(std::size_t index) { return 0; }
163 
164  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
165  return op(*gil_reinterpret_cast_c<const typename mpl::front<unique_t>::type*>(&bits));
166  }
167 
168  template <typename Bits> BOOST_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
169  return op(*gil_reinterpret_cast<typename mpl::front<unique_t>::type*>(&bits));
170  }
171 };
172 
173 
186 
187 namespace detail {
188  struct pair_generator {
189  template <typename Vec2> struct apply
190  {
191  using type = std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::type*>;
192  };
193  };
194 
195  // When the types are not too large, applies reduce on their cross product
196  template <typename Unary1, typename Unary2, typename Op, bool IsComplex>
197  struct binary_reduce_impl
198  {
199  //private:
200  using vec1_types = typename mpl::copy_to_vector<typename Unary1::unique_t>::type;
201  using vec2_types = typename mpl::copy_to_vector<typename Unary2::unique_t>::type;
202 
203  using BIN_TYPES = mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator>;
204  using bin_reduced_t = unary_reduce<BIN_TYPES,Op>;
205 
206  static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
207  unsigned short r1=Unary1::map_index(index1);
208  unsigned short r2=Unary2::map_index(index2);
209  return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);
210  }
211  public:
212  using unique_t = typename bin_reduced_t::unique_t
213 
214  template <typename Bits1, typename Bits2>
215  static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
216  std::pair<const void*,const void*> pr(&bits1, &bits2);
217  return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
218  }
219  };
220 
221  // When the types are large performs a double-dispatch. Binary reduction is not done.
222  template <typename Unary1, typename Unary2, typename Op>
223  struct binary_reduce_impl<Unary1,Unary2,Op,true> {
224  template <typename Bits1, typename Bits2>
225  static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
226  return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);
227  }
228  };
229 }
230 
231 
232 template <typename Types1, typename Types2, typename Op>
233 struct binary_reduce
234 {
235 //private:
236  using unary1_t = unary_reduce<Types1,Op>;
237  using unary2_t = unary_reduce<Types2,Op>;
238 
239  static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
240  mpl::size<typename unary2_t::unique_t>::value;
241 
242  using impl = detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)>;
243 public:
244  template <typename Bits1, typename Bits2>
245  static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
246  return impl::apply(bits1,index1,bits2,index2,op);
247  }
248 };
249 
250 template <typename Types, typename UnaryOp>
251 BOOST_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
252  return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);
253 }
254 
255 template <typename Types, typename UnaryOp>
256 BOOST_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant<Types>& arg, UnaryOp op) {
257  return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);
258 }
259 
260 template <typename Types1, typename Types2, typename BinaryOp>
261 BOOST_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {
262  return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
263 }
264 
265 #undef GIL_BINARY_REDUCE_LIMIT
266 
267 } } // namespace gil
268 
269 
270 namespace boost { namespace mpl {
289 
290 template <typename VecOfVecs, typename TypeGen>
291 struct cross_vector {};
292 
295 template <typename VecOfVecs, typename TypeGen, std::size_t K>
296 struct cross_iterator
297 {
298  using category = mpl::random_access_iterator_tag;
299 };
300 
304 
310 template <typename VecOfVecs, typename TypeGen, std::size_t K>
311 struct deref<cross_iterator<VecOfVecs,TypeGen,K>>
312 {
313 private:
314  using DerefTypes = typename detail::select_subvector_c<VecOfVecs, K>::type;
315 public:
316  using type = typename TypeGen::template apply<DerefTypes>::type;
317 };
318 
321 template <typename VecOfVecs, typename TypeGen, std::size_t K>
322 struct next<cross_iterator<VecOfVecs,TypeGen,K>>
323 {
324  using type = cross_iterator<VecOfVecs,TypeGen,K+1>;
325 };
326 
329 template <typename VecOfVecs, typename TypeGen, std::size_t K>
330 struct prior<cross_iterator<VecOfVecs,TypeGen,K>>
331 {
332  using type = cross_iterator<VecOfVecs,TypeGen,K-1>;
333 };
334 
337 template <typename VecOfVecs, typename TypeGen, std::size_t K, typename Distance>
338 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance>
339 {
340  using type = cross_iterator<VecOfVecs,TypeGen,K+Distance::value>;
341 };
342 
345 // (shortened the names of the template arguments - otherwise doxygen cannot parse this...)
346 template <typename VecOfVecs, typename TypeGen, std::size_t K1, std::size_t K2>
347 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2>>
348 {
349  using type = size_t<K2-K1>;
350 };
351 
357 template <typename VecOfVecs, typename TypeGen>
358 struct size<cross_vector<VecOfVecs,TypeGen>>
359 {
360  using type = typename fold<VecOfVecs, size_t<1>, times<_1, size<_2>>>::type;
361  static const std::size_t value=type::value;
362 };
363 
366 template <typename VecOfVecs, typename TypeGen>
367 struct empty<cross_vector<VecOfVecs,TypeGen>> {
368  using type = typename empty<VecOfVecs>::type;
369 };
370 
373 template <typename VecOfVecs, typename TypeGen, typename K>
374 struct at<cross_vector<VecOfVecs,TypeGen>, K>
375 {
376 private:
377  using KthIterator = cross_iterator<VecOfVecs,TypeGen,K::value>;
378 public:
379  using type = typename deref<KthIterator>::type;
380 };
381 
384 template <typename VecOfVecs, typename TypeGen>
385 struct begin<cross_vector<VecOfVecs,TypeGen>>
386 {
387  using type = cross_iterator<VecOfVecs,TypeGen,0>;
388 };
389 
392 template <typename VecOfVecs, typename TypeGen>
393 struct end<cross_vector<VecOfVecs,TypeGen>>
394 {
395 private:
396  using this_t = cross_vector<VecOfVecs,TypeGen>;
397 public:
398  using type = cross_iterator<VecOfVecs,TypeGen,size<this_t>::value>;
399 };
400 
403 template <typename VecOfVecs, typename TypeGen>
404 struct front<cross_vector<VecOfVecs,TypeGen>> {
405 private:
406  using this_t = cross_vector<VecOfVecs,TypeGen>;
407 public:
408  using type = typename deref<typename begin<this_t>::type>::type;
409 };
410 
413 template <typename VecOfVecs, typename TypeGen>
414 struct back<cross_vector<VecOfVecs,TypeGen>>
415 {
416 private:
417  using this_t = cross_vector<VecOfVecs,TypeGen>;
418  using size = typename size<this_t>::type;
419  using last_index = typename minus<size, size_t<1>>::type;
420 public:
421  using type = typename at<this_t, last_index>::type;
422 };
423 
426 template <typename VecOfVecs, typename TypeGen, typename OPP>
427 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP>
428 {
429  using Op = typename lambda<OPP>::type;
430  struct adapter
431  {
432  template <typename Elements>
433  struct apply
434  {
435  using orig_t = typename TypeGen::template apply<Elements>::type;
436  using type = typename Op::template apply<orig_t>::type;
437  };
438  };
439  using type = cross_vector<VecOfVecs, adapter>;
440 };
441 
442 } } // boost::mpl
443 
444 namespace boost { namespace gil {
445 
446 template <typename Types, typename T> struct type_to_index;
447 template <typename V> struct view_is_basic;
448 struct rgb_t;
449 struct lab_t;
450 struct hsb_t;
451 struct cmyk_t;
452 struct rgba_t;
453 struct error_t;
454 
455 
456 namespace detail {
462  template <typename Op, typename T>
463  struct reduce
464  {
465  using type = T;
466  };
467 
474 
475  template <typename Op, typename View, bool IsBasic>
476  struct reduce_view_basic
477  {
478  using type = View;
479  };
480 
481  template <typename Op, typename Loc>
482  struct reduce<Op, image_view<Loc>>
483  : public reduce_view_basic<Op,image_view<Loc>,view_is_basic<image_view<Loc>>::value> {};
484 
491 
492  template <typename Op, typename Img, bool IsBasic>
493  struct reduce_image_basic
494  {
495  using type = Img;
496  };
497 
498  template <typename Op, typename V, typename Alloc>
499  struct reduce<Op, image<V,Alloc>> : public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc>>::value > {};
500 
507 
508  template <typename Op, typename V1, typename V2, bool AreBasic>
509  struct reduce_views_basic
510  {
511  using type = std::pair<const V1*, const V2*>;
512  };
513 
514  template <typename Op, typename L1, typename L2>
515  struct reduce<Op, std::pair<const image_view<L1>*, const image_view<L2>*>>
516  : public reduce_views_basic<Op,image_view<L1>,image_view<L2>,
517  mpl::and_<view_is_basic<image_view<L1>>, view_is_basic<image_view<L2>>>::value >
518  {};
519 
520 
526 
527  template <typename CS>
528  struct reduce_color_space
529  {
530  using type = CS;
531  };
532 
533  template <> struct reduce_color_space<lab_t> { using type = rgb_t; };
534  template <> struct reduce_color_space<hsb_t> { using type = rgb_t; };
535  template <> struct reduce_color_space<cmyk_t> { using type = rgba_t; };
536 
537  /*
545 
546  template <typename Vec, int Basis, int VecSize>
547  struct type_vec_to_integer_impl {
548  using last = typename mpl::back<Vec>::type;
549  using rest = typename mpl::pop_back<Vec>::type;
550  static const int value = type_vec_to_integer_impl<rest, Basis, VecSize-1>::value * Basis + last::value;
551  };
552 
553  template <typename Vec, int Basis>
554  struct type_vec_to_integer_impl<Vec,Basis,0> {
555  static const int value=0;
556  };
557 
558  template <typename Vec, int Basis=10>
559  struct type_vec_to_integer {
560  static const int value = type_vec_to_integer_impl<Vec,Basis, mpl::size<Vec>::value>::value;
561  };
562 
563  // Given two color spaces and the mapping of the channels between them, returns the reduced pair of color spaces
564  // The default version performs no reduction
565  template <typename SrcColorSpace, typename DstColorSpace, int Mapping>
566  struct reduce_color_spaces_impl {
567  using first_t = SrcColorSpace;
568  using second_t = DstColorSpace;
569  };
570 
571  // 012: RGB-RGB, bgr-bgr, lab-lab, hsb-hsb
572  template <typename SrcColorSpace, typename DstColorSpace>
573  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,12> {
574  using first_t = rgb_t;
575  using second_t = rgb_t;
576  };
577 
578  // 210: RGB-bgr, bgr-RGB
579  template <typename SrcColorSpace, typename DstColorSpace>
580  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,210> {
581  using first_t = rgb_t;
582  using second_t = bgr_t;
583  };
584 
585  // 0123: RGBA-RGBA, bgra-bgra, argb-argb, abgr-abgr cmyk-cmyk
586  template <typename SrcColorSpace, typename DstColorSpace>
587  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,123> {
588  using first_t = rgba_t;
589  using second_t = rgba_t;
590  };
591 
592  // 3210: RGBA-abgr, bgra-argb, argb-bgra, abgr-RGBA
593  template <typename SrcColorSpace, typename DstColorSpace>
594  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3210> {
595  using first_t = rgba_t;
596  using second_t = abgr_t;
597  };
598 
599  // 1230: RGBA-argb, bgra-abgr
600  template <typename SrcColorSpace, typename DstColorSpace>
601  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,1230> {
602  using first_t = rgba_t;
603  using second_t = argb_t;
604  };
605 
606  // 2103: RGBA-bgra, bgra-RGBA (uses subclass to ensure that base color space is not reduced to derived)
607  template <typename SrcColorSpace, typename DstColorSpace>
608  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,2103> {
609  using first_t = rgba_t;
610  using second_t = bgra_t;
611  };
612 
613  // 3012: argb-RGBA, abgr-bgra
614  template <typename SrcColorSpace, typename DstColorSpace>
615  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3012> {
616  using first_t = argb_t;
617  using second_t = rgba_t;
618  };
619 
620  // 0321: argb-abgr, abgr-argb
621  template <typename SrcColorSpace, typename DstColorSpace>
622  struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,321> {
623  using first_t = argb_t;
624  using second_t = abgr_t;
625  };
626 
627  template <typename SrcColorSpace, typename DstColorSpace>
628  struct reduce_color_spaces {
629  using src_order_t = typename channel_order<SrcColorSpace>::type;
630  using dst_order_t = typename channel_order<DstColorSpace>::type;
631  using mapping = typename mpl::transform<src_order_t, type_to_index<dst_order_t,mpl::_1>>::type;
632  static const int mapping_val = type_vec_to_integer<mapping>::value;
633 
634  using _first_t = typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::first_t;
635  using _second_t = typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::second_t;
636  using swap_t = typename mpl::and_<color_space_is_base<DstColorSpace>, mpl::not_< color_space_is_base<_second_t>>>;
637  public:
638  using first_t = typename mpl::if_<swap_t, _second_t, _first_t>::type;
639  using second_t = typename mpl::if_<swap_t, _first_t, _second_t>::type;
640  };
641 */
642 // TODO: Use the old code for reduce_color_spaces above to do color layout reduction
643  template <typename SrcLayout, typename DstLayout>
644  struct reduce_color_layouts
645  {
646  using first_t = SrcLayout;
647  using second_t = DstLayout;
648  };
649 
655 
656  struct copy_pixels_fn;
657 
658  /*
659  // 1D reduce for copy_pixels reduces the channel to mutable and the color space to its base with same dimensions
660  template <typename View>
661  struct reduce_view_basic<copy_pixels_fn,View,true> {
662  private:
663  using color_space_t = typename reduce_color_space<typename View::color_space_t>::type color_space_t; // reduce the color space
664  using layout_t = layout<color_space_t, typename View::channel_mapping_t>;
665  public:
666  using type = typename derived_view_type<View, use_default, layout_t, use_default, use_default, mpl::true_>::type;
667  };
668 */
669  // Incompatible views cannot be used in copy_pixels - will throw std::bad_cast
670  template <typename V1, typename V2, bool Compatible>
671  struct reduce_copy_pixop_compat
672  {
673  using type = error_t;
674  };
675 
676  // For compatible basic views, reduce their color spaces based on their channel mapping.
677  // Make the source immutable and the destination mutable (they should already be that way)
678  template <typename V1, typename V2>
679  struct reduce_copy_pixop_compat<V1,V2,true>
680  {
681  using layout1 = layout<typename V1::color_space_t, typename V1::channel_mapping_t>;
682  using layout2 = layout<typename V2::color_space_t, typename V2::channel_mapping_t>;
683 
684  using L1 = typename reduce_color_layouts<layout1,layout2>::first_t;
685  using L2 = typename reduce_color_layouts<layout1,layout2>::second_t;
686 
687  using DV1 = typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type;
688  using DV2 = typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type;
689 
690  using type = std::pair<const DV1*, const DV2*>;
691  };
692 
693  // The general 2D version branches into compatible and incompatible views
694  template <typename V1, typename V2>
695  struct reduce_views_basic<copy_pixels_fn, V1, V2, true>
696  : public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2>>::value > {
697  };
698 
704 
705  struct destructor_op;
706  template <typename View>
707  struct reduce_view_basic<destructor_op,View,true>
708  {
709  using type = gray8_view_t;
710  };
711 
717 
718  struct any_type_get_dimensions;
719 
720  template <typename View>
721  struct reduce_view_basic<any_type_get_dimensions,View,true>
722  {
723  using type = gray8_view_t;
724  };
725 
726  template <typename Img>
727  struct reduce_image_basic<any_type_get_dimensions,Img,true>
728  {
729  using type = gray8_image_t;
730  };
731 
737 
738  struct any_type_get_num_channels;
739 
740  template <typename View>
741  struct reduce_view_basic<any_type_get_num_channels,View,true>
742  {
743  using color_space_t = typename View::color_space_t::base;
744  using type = typename view_type<uint8_t,typename reduce_color_space<color_space_t>::type>::type;
745  };
746 
747  template <typename Img>
748  struct reduce_image_basic<any_type_get_num_channels,Img,true>
749  {
750  using color_space_t = typename Img::color_space_t::base;
751  using type = typename image_type<uint8_t,typename reduce_color_space<color_space_t>::type>::type;
752  };
753 
759 
760  template <typename Sampler, typename MapFn> struct resample_pixels_fn;
761 
762  template <typename S, typename M, typename V, bool IsBasic>
763  struct reduce_view_basic<resample_pixels_fn<S,M>, V, IsBasic> : public reduce_view_basic<copy_pixels_fn, V, IsBasic> {};
764 
765  template <typename S, typename M, typename V1, typename V2, bool IsBasic>
766  struct reduce_views_basic<resample_pixels_fn<S,M>, V1, V2, IsBasic> : public reduce_views_basic<copy_pixels_fn, V1, V2, IsBasic> {};
767 
774 
775 
776  template <typename CC> class copy_and_convert_pixels_fn;
777 
778  // the only thing for 1D reduce is making them all mutable...
779  template <typename CC, typename View, bool IsBasic>
780  struct reduce_view_basic<copy_and_convert_pixels_fn<CC>, View, IsBasic>
781  : public derived_view_type<View, use_default, use_default, use_default, use_default, mpl::true_> {
782  };
783 
784  // For 2D reduce, if they have the same channels and color spaces (i.e. the same pixels) then copy_and_convert is just copy.
785  // In this case, reduce their common color space. In general make the first immutable and the second mutable
786  template <typename CC, typename V1, typename V2, bool AreBasic>
787  struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic>
788  {
789  using Same = std::is_same<typename V1::pixel_t, typename V2::pixel_t>;
790 
791  using CsR = reduce_color_space<typename V1::color_space_t::base>;
792  using Cs1 = typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type;
793  using Cs2 = typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type;
794 
795  using DV1 = typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type;
796  using DV2 = typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type;
797 
798  using type = std::pair<const DV1*, const DV2*>;
799  };
800 
801 
802  //integral_image_generator
803  //resize_clobber_image_fnobj
804  //image_default_construct_fnobj
805  //fill_converted_pixels_fn
806  //std::bind(gil::detail::copy_pixels_fn(), std::placeholders::_1, dst)
807  //std::bind(gil::detail::copy_pixels_fn(), src, std::placeholders::_1)
808 
809  //std::bind(detail::copy_and_convert_pixels_fn(), std::placeholders::_1, dst)
810  //std::bind(detail::copy_and_convert_pixels_fn(), src, std::placeholders::_1)
811  //gil::detail::fill_pixels_fn<Value>(val)
812 
813  //detail::copy_construct_in_place_fn<base_t>
814  //detail::equal_to_fn<typename variant<Types>::base_t>
815 
816  //detail::any_image_get_view<typename any_image<Types>::view_t>
817  //detail::any_image_get_const_view<typename any_image<Types>::view_t>
818  //detail::flipped_up_down_view_fn<any_image_view<ViewTypes>>
819  //detail::flipped_left_right_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
820  //detail::tranposed_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
821  //detail::rotated90cw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
822  //detail::rotated90ccw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
823  //detail::rotated180_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
824  //detail::subimage_view_fn<any_image_view<ViewTypes>>
825  //detail::subsampled_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
826  //detail::nth_channel_view_fn<typename nth_channel_view_type<any_image_view<ViewTypes>>
827  //detail::color_converted_view_fn<DstP,typename color_convert_view_type<any_image_view<ViewTypes>, DstP>::type >
828 }
829 
830 }} // namespace boost::gil
831 
832 #endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT)
833 
834 #endif
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