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