8 #ifndef BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_GIL_REDUCE_HPP 9 #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_GIL_REDUCE_HPP 11 #ifdef BOOST_GIL_DOXYGEN_ONLY 12 #undef BOOST_GIL_REDUCE_CODE_BLOAT 19 #ifdef BOOST_GIL_REDUCE_CODE_BLOAT 21 #include <boost/gil/extension/dynamic_image/dynamic_at_c.hpp> 23 #include <boost/gil/metafunctions.hpp> 24 #include <boost/gil/typedefs.hpp> 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> 36 #include <type_traits> 39 #define BOOST_GIL_BINARY_REDUCE_LIMIT 226 41 namespace boost {
namespace mpl {
54 template <
typename SrcTypes,
typename DstTypes>
55 struct mapping_vector {};
57 template <
typename SrcTypes,
typename DstTypes,
long K>
58 struct at_c<mapping_vector<SrcTypes,DstTypes>, K>
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>;
64 template <
typename SrcTypes,
typename DstTypes>
65 struct size<mapping_vector<SrcTypes,DstTypes>>
67 using type =
typename size<SrcTypes>::type;
68 static const std::size_t value=type::value;
81 template <
typename SFirst, std::
size_t NLeft>
82 struct copy_to_vector_impl {
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;
88 using type =
typename push_front<rest, T>::type;
91 template <
typename SFirst>
92 struct copy_to_vector_impl<SFirst,1>
94 using type = vector<typename deref<SFirst>::type>;
98 template <
typename Src>
101 using type =
typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type;
105 struct copy_to_vector<set<>>
107 using type = vector0<>;
112 namespace boost {
namespace gil {
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;
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>
146 using reduced_t =
typename unary_reduce_impl<Types,Op>::reduced_t;
147 using unique_t =
typename unary_reduce_impl<Types,Op>::unique_t;
149 static unsigned short inline map_index(std::size_t index)
151 using indices_t =
typename mpl::mapping_vector<reduced_t, unique_t>;
152 return gil::at_c<indices_t, unsigned short>(index);
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);
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);
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; }
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));
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));
192 struct pair_generator {
193 template <
typename Vec2>
struct apply
195 using type = std::pair<const typename mpl::at_c<Vec2,0>::type*,
const typename mpl::at_c<Vec2,1>::type*>;
200 template <
typename Unary1,
typename Unary2,
typename Op,
bool IsComplex>
201 struct binary_reduce_impl
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;
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>;
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);
216 using unique_t =
typename bin_reduced_t::unique_t
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);
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);
236 template <
typename Types1,
typename Types2,
typename Op>
240 using unary1_t = unary_reduce<Types1,Op>;
241 using unary2_t = unary_reduce<Types2,Op>;
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;
246 using impl = detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>BOOST_GIL_BINARY_REDUCE_LIMIT)>;
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);
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);
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);
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);
269 #undef BOOST_GIL_BINARY_REDUCE_LIMIT 274 namespace boost {
namespace mpl {
294 template <
typename VecOfVecs,
typename TypeGen>
295 struct cross_vector {};
299 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
300 struct cross_iterator
302 using category = mpl::random_access_iterator_tag;
314 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
315 struct deref<cross_iterator<VecOfVecs,TypeGen,K>>
318 using DerefTypes =
typename detail::select_subvector_c<VecOfVecs, K>::type;
320 using type =
typename TypeGen::template apply<DerefTypes>::type;
325 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
326 struct next<cross_iterator<VecOfVecs,TypeGen,K>>
328 using type = cross_iterator<VecOfVecs,TypeGen,K+1>;
333 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
334 struct prior<cross_iterator<VecOfVecs,TypeGen,K>>
336 using type = cross_iterator<VecOfVecs,TypeGen,K-1>;
341 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K,
typename Distance>
342 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance>
344 using type = cross_iterator<VecOfVecs,TypeGen,K+Distance::value>;
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>>
353 using type =
size_t<K2-K1>;
361 template <
typename VecOfVecs,
typename TypeGen>
362 struct size<cross_vector<VecOfVecs,TypeGen>>
364 using type =
typename fold<VecOfVecs, size_t<1>, times<_1, size<_2>>>::type;
365 static const std::size_t value=type::value;
370 template <
typename VecOfVecs,
typename TypeGen>
371 struct empty<cross_vector<VecOfVecs,TypeGen>> {
372 using type =
typename empty<VecOfVecs>::type;
377 template <
typename VecOfVecs,
typename TypeGen,
typename K>
378 struct at<cross_vector<VecOfVecs,TypeGen>, K>
381 using KthIterator = cross_iterator<VecOfVecs,TypeGen,K::value>;
383 using type =
typename deref<KthIterator>::type;
388 template <
typename VecOfVecs,
typename TypeGen>
389 struct begin<cross_vector<VecOfVecs,TypeGen>>
391 using type = cross_iterator<VecOfVecs,TypeGen,0>;
396 template <
typename VecOfVecs,
typename TypeGen>
397 struct end<cross_vector<VecOfVecs,TypeGen>>
400 using this_t = cross_vector<VecOfVecs,TypeGen>;
402 using type = cross_iterator<VecOfVecs,TypeGen,size<this_t>::value>;
407 template <
typename VecOfVecs,
typename TypeGen>
408 struct front<cross_vector<VecOfVecs,TypeGen>> {
410 using this_t = cross_vector<VecOfVecs,TypeGen>;
412 using type =
typename deref<typename begin<this_t>::type>::type;
417 template <
typename VecOfVecs,
typename TypeGen>
418 struct back<cross_vector<VecOfVecs,TypeGen>>
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;
425 using type =
typename at<this_t, last_index>::type;
430 template <
typename VecOfVecs,
typename TypeGen,
typename OPP>
431 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP>
433 using Op =
typename lambda<OPP>::type;
436 template <
typename Elements>
439 using orig_t =
typename TypeGen::template apply<Elements>::type;
440 using type =
typename Op::template apply<orig_t>::type;
443 using type = cross_vector<VecOfVecs, adapter>;
448 namespace boost {
namespace gil {
450 template <
typename Types,
typename T>
struct type_to_index;
451 template <
typename V>
struct view_is_basic;
466 template <
typename Op,
typename T>
479 template <
typename Op,
typename View,
bool IsBasic>
480 struct reduce_view_basic
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> {};
496 template <
typename Op,
typename Img,
bool IsBasic>
497 struct reduce_image_basic
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 > {};
512 template <
typename Op,
typename V1,
typename V2,
bool AreBasic>
513 struct reduce_views_basic
515 using type = std::pair<const V1*, const V2*>;
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 >
531 template <
typename CS>
532 struct reduce_color_space
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; };
647 template <
typename SrcLayout,
typename DstLayout>
648 struct reduce_color_layouts
650 using first_t = SrcLayout;
651 using second_t = DstLayout;
660 struct copy_pixels_fn;
674 template <
typename V1,
typename V2,
bool Compatible>
675 struct reduce_copy_pixop_compat
677 using type = error_t;
682 template <
typename V1,
typename V2>
683 struct reduce_copy_pixop_compat<V1,V2,true>
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>;
688 using L1 =
typename reduce_color_layouts<layout1,layout2>::first_t;
689 using L2 =
typename reduce_color_layouts<layout1,layout2>::second_t;
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;
694 using type = std::pair<const DV1*, const DV2*>;
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 > {
709 struct destructor_op;
710 template <
typename View>
711 struct reduce_view_basic<destructor_op,View,true>
713 using type = gray8_view_t;
722 struct any_type_get_dimensions;
724 template <
typename View>
725 struct reduce_view_basic<any_type_get_dimensions,View,true>
727 using type = gray8_view_t;
730 template <
typename Img>
731 struct reduce_image_basic<any_type_get_dimensions,Img,true>
733 using type = gray8_image_t;
742 struct any_type_get_num_channels;
744 template <
typename View>
745 struct reduce_view_basic<any_type_get_num_channels,View,true>
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;
751 template <
typename Img>
752 struct reduce_image_basic<any_type_get_num_channels,Img,true>
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;
764 template <
typename Sampler,
typename MapFn>
struct resample_pixels_fn;
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> {};
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> {};
780 template <
typename CC>
class copy_and_convert_pixels_fn;
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_> {
790 template <
typename CC,
typename V1,
typename V2,
bool AreBasic>
791 struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic>
793 using Same = std::is_same<typename V1::pixel_t, typename V2::pixel_t>;
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;
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;
802 using type = std::pair<const DV1*, const DV2*>;
836 #endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT) 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