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    15 #ifdef BOOST_GIL_REDUCE_CODE_BLOAT    17 #include <boost/gil/extension/dynamic_image/dynamic_at_c.hpp>    19 #include <boost/gil/metafunctions.hpp>    20 #include <boost/gil/typedefs.hpp>    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>    32 #include <type_traits>    35 #define GIL_BINARY_REDUCE_LIMIT 226    37 namespace boost { 
namespace mpl {
    50 template <
typename SrcTypes, 
typename DstTypes>
    51 struct mapping_vector {};
    53 template <
typename SrcTypes, 
typename DstTypes, 
long K>
    54 struct at_c<mapping_vector<SrcTypes,DstTypes>, K>
    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>;
    60 template <
typename SrcTypes, 
typename DstTypes>
    61 struct size<mapping_vector<SrcTypes,DstTypes>>
    63     using type = 
typename size<SrcTypes>::type;
    64     static const std::size_t value=type::value;
    77     template <
typename SFirst, std::
size_t NLeft>
    78     struct copy_to_vector_impl {
    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;
    84         using type = 
typename push_front<rest, T>::type;
    87     template <
typename SFirst>
    88     struct copy_to_vector_impl<SFirst,1>
    90         using type = vector<typename deref<SFirst>::type>;
    94 template <
typename Src>
    97     using type = 
typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type;
   101 struct copy_to_vector<set<>>
   103     using type = vector0<>;
   108 namespace boost { 
namespace gil {
   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;
   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>
   142     using reduced_t = 
typename unary_reduce_impl<Types,Op>::reduced_t;
   143     using unique_t = 
typename unary_reduce_impl<Types,Op>::unique_t;
   145     static unsigned short inline map_index(std::size_t index)
   147         using indices_t = 
typename mpl::mapping_vector<reduced_t, unique_t>;
   148         return gil::at_c<indices_t, unsigned short>(index);
   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);
   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);
   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; }
   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));
   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));
   188     struct pair_generator {
   189         template <
typename Vec2> 
struct apply
   191             using type = std::pair<const typename mpl::at_c<Vec2,0>::type*, 
const typename mpl::at_c<Vec2,1>::type*>;
   196     template <
typename Unary1, 
typename Unary2, 
typename Op, 
bool IsComplex>
   197     struct binary_reduce_impl
   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;
   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>;
   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);
   212         using unique_t = 
typename bin_reduced_t::unique_t
   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);
   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);
   232 template <
typename Types1, 
typename Types2, 
typename Op>
   236     using unary1_t = unary_reduce<Types1,Op>;
   237     using unary2_t = unary_reduce<Types2,Op>;
   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;
   242     using impl = detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)>;
   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);
   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);
   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);
   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);
   265 #undef GIL_BINARY_REDUCE_LIMIT   270 namespace boost { 
namespace mpl {
   290 template <
typename VecOfVecs, 
typename TypeGen>
   291 struct cross_vector {};
   295 template <
typename VecOfVecs, 
typename TypeGen, std::
size_t K>
   296 struct cross_iterator
   298     using category = mpl::random_access_iterator_tag;
   310 template <
typename VecOfVecs, 
typename TypeGen, std::
size_t K>
   311 struct deref<cross_iterator<VecOfVecs,TypeGen,K>>
   314     using DerefTypes = 
typename detail::select_subvector_c<VecOfVecs, K>::type;
   316     using type = 
typename TypeGen::template apply<DerefTypes>::type;
   321 template <
typename VecOfVecs, 
typename TypeGen, std::
size_t K>
   322 struct next<cross_iterator<VecOfVecs,TypeGen,K>>
   324     using type = cross_iterator<VecOfVecs,TypeGen,K+1>;
   329 template <
typename VecOfVecs, 
typename TypeGen, std::
size_t K>
   330 struct prior<cross_iterator<VecOfVecs,TypeGen,K>>
   332     using type = cross_iterator<VecOfVecs,TypeGen,K-1>;
   337 template <
typename VecOfVecs, 
typename TypeGen, std::
size_t K, 
typename Distance>
   338 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance>
   340     using type = cross_iterator<VecOfVecs,TypeGen,K+Distance::value>;
   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>>
   349     using type = 
size_t<K2-K1>;
   357 template <
typename VecOfVecs, 
typename TypeGen>
   358 struct size<cross_vector<VecOfVecs,TypeGen>>
   360     using type = 
typename fold<VecOfVecs, size_t<1>, times<_1, size<_2>>>::type;
   361     static const std::size_t value=type::value;
   366 template <
typename VecOfVecs, 
typename TypeGen>
   367 struct empty<cross_vector<VecOfVecs,TypeGen>> {
   368     using type = 
typename empty<VecOfVecs>::type;
   373 template <
typename VecOfVecs, 
typename TypeGen, 
typename K>
   374 struct at<cross_vector<VecOfVecs,TypeGen>, K>
   377     using KthIterator = cross_iterator<VecOfVecs,TypeGen,K::value>;
   379     using type = 
typename deref<KthIterator>::type;
   384 template <
typename VecOfVecs, 
typename TypeGen>
   385 struct begin<cross_vector<VecOfVecs,TypeGen>>
   387     using type = cross_iterator<VecOfVecs,TypeGen,0>;
   392 template <
typename VecOfVecs, 
typename TypeGen>
   393 struct end<cross_vector<VecOfVecs,TypeGen>>
   396     using this_t = cross_vector<VecOfVecs,TypeGen>;
   398     using type = cross_iterator<VecOfVecs,TypeGen,size<this_t>::value>;
   403 template <
typename VecOfVecs, 
typename TypeGen>
   404 struct front<cross_vector<VecOfVecs,TypeGen>> {
   406     using this_t = cross_vector<VecOfVecs,TypeGen>;
   408     using type = 
typename deref<typename begin<this_t>::type>::type;
   413 template <
typename VecOfVecs, 
typename TypeGen>
   414 struct back<cross_vector<VecOfVecs,TypeGen>>
   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;
   421     using type = 
typename at<this_t, last_index>::type;
   426 template <
typename VecOfVecs, 
typename TypeGen, 
typename OPP>
   427 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP>
   429     using Op = 
typename lambda<OPP>::type;
   432         template <
typename Elements>
   435             using orig_t = 
typename TypeGen::template apply<Elements>::type;
   436             using type = 
typename Op::template apply<orig_t>::type;
   439     using type = cross_vector<VecOfVecs, adapter>;
   444 namespace boost { 
namespace gil {
   446 template <
typename Types, 
typename T> 
struct type_to_index;
   447 template <
typename V> 
struct view_is_basic;
   462     template <
typename Op, 
typename T>
   475     template <
typename Op, 
typename View, 
bool IsBasic>
   476     struct reduce_view_basic
   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> {};
   492     template <
typename Op, 
typename Img, 
bool IsBasic>
   493     struct reduce_image_basic
   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 > {};
   508     template <
typename Op, 
typename V1, 
typename V2, 
bool AreBasic>
   509     struct reduce_views_basic
   511         using type = std::pair<const V1*, const V2*>;
   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 >
   527     template <
typename CS>
   528     struct reduce_color_space
   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; };
   643     template <
typename SrcLayout, 
typename DstLayout>
   644     struct reduce_color_layouts
   646         using first_t = SrcLayout;
   647         using second_t = DstLayout;
   656     struct copy_pixels_fn;
   670     template <
typename V1, 
typename V2, 
bool Compatible>
   671     struct reduce_copy_pixop_compat
   673         using type = error_t;
   678     template <
typename V1, 
typename V2>
   679     struct reduce_copy_pixop_compat<V1,V2,true>
   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>;
   684         using L1 = 
typename reduce_color_layouts<layout1,layout2>::first_t;
   685         using L2 = 
typename reduce_color_layouts<layout1,layout2>::second_t;
   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;
   690         using type = std::pair<const DV1*, const DV2*>;
   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 > {
   705     struct destructor_op;
   706     template <
typename View>
   707     struct reduce_view_basic<destructor_op,View,true>
   709         using type = gray8_view_t;
   718     struct any_type_get_dimensions;
   720     template <
typename View>
   721     struct reduce_view_basic<any_type_get_dimensions,View,true>
   723         using type = gray8_view_t;
   726     template <
typename Img>
   727     struct reduce_image_basic<any_type_get_dimensions,Img,true>
   729         using type = gray8_image_t;
   738     struct any_type_get_num_channels;
   740     template <
typename View>
   741     struct reduce_view_basic<any_type_get_num_channels,View,true>
   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;
   747     template <
typename Img>
   748     struct reduce_image_basic<any_type_get_num_channels,Img,true>
   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;
   760     template <
typename Sampler, 
typename MapFn> 
struct resample_pixels_fn;
   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> {};
   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> {};
   776     template <
typename CC> 
class copy_and_convert_pixels_fn;
   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_> {
   786     template <
typename CC, 
typename V1, 
typename V2, 
bool AreBasic>
   787     struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic>
   789         using Same = std::is_same<typename V1::pixel_t, typename V2::pixel_t>;
   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;
   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;
   798         using type = std::pair<const DV1*, const DV2*>;
   832 #endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT) 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