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>
33 #define GIL_BINARY_REDUCE_LIMIT 226
35 namespace boost {
namespace mpl {
48 template <
typename SrcTypes,
typename DstTypes>
49 struct mapping_vector {};
51 template <
typename SrcTypes,
typename DstTypes,
long K>
52 struct at_c<mapping_vector<SrcTypes,DstTypes>, K> {
53 static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename gil::at_c<SrcTypes,K>::type>::type::value +1;
54 typedef size_t<value> type;
57 template <
typename SrcTypes,
typename DstTypes>
58 struct size<mapping_vector<SrcTypes,DstTypes> > {
59 typedef typename size<SrcTypes>::type type;
60 static const std::size_t value=type::value;
73 template <
typename SFirst, std::
size_t NLeft>
74 struct copy_to_vector_impl {
76 typedef typename deref<SFirst>::type T;
77 typedef typename next<SFirst>::type next;
78 typedef typename copy_to_vector_impl<next, NLeft-1>::type rest;
80 typedef typename push_front<rest, T>::type type;
83 template <
typename SFirst>
84 struct copy_to_vector_impl<SFirst,1> {
85 typedef vector<typename deref<SFirst>::type> type;
89 template <
typename Src>
90 struct copy_to_vector {
91 typedef typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type type;
95 struct copy_to_vector<set<> > {
96 typedef vector0<> type;
101 namespace boost {
namespace gil {
125 template <
typename Types,
typename Op>
126 struct unary_reduce_impl {
127 typedef typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type reduced_t;
128 typedef typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2> > >::type unique_t;
129 static const bool is_single=mpl::size<unique_t>::value==1;
132 template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>
133 struct unary_reduce :
public unary_reduce_impl<Types,Op> {
134 typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t;
135 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
137 static unsigned short inline map_index(std::size_t index) {
138 typedef typename mpl::mapping_vector<reduced_t, unique_t> indices_t;
139 return gil::at_c<indices_t, unsigned short>(index);
141 template <
typename Bits> BOOST_FORCEINLINE
static typename Op::result_type applyc(
const Bits& bits, std::size_t index, Op op) {
142 return apply_operation_basec<unique_t>(bits,map_index(index),op);
145 template <
typename Bits> BOOST_FORCEINLINE
static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
146 return apply_operation_base<unique_t>(bits,map_index(index),op);
150 template <
typename Types,
typename Op>
151 struct unary_reduce<Types,Op,true> :
public unary_reduce_impl<Types,Op> {
152 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
153 static unsigned short inline map_index(std::size_t index) {
return 0; }
155 template <
typename Bits> BOOST_FORCEINLINE
static typename Op::result_type applyc(
const Bits& bits, std::size_t index, Op op) {
156 return op(*gil_reinterpret_cast_c<
const typename mpl::front<unique_t>::type*>(&bits));
159 template <
typename Bits> BOOST_FORCEINLINE
static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
160 return op(*gil_reinterpret_cast<
typename mpl::front<unique_t>::type*>(&bits));
179 struct pair_generator {
180 template <
typename Vec2>
struct apply {
181 typedef std::pair<const typename mpl::at_c<Vec2,0>::type*,
const typename mpl::at_c<Vec2,1>::type*> type;
186 template <
typename Unary1,
typename Unary2,
typename Op,
bool IsComplex>
187 struct binary_reduce_impl {
189 typedef typename mpl::copy_to_vector<typename Unary1::unique_t>::type vec1_types;
190 typedef typename mpl::copy_to_vector<typename Unary2::unique_t>::type vec2_types;
192 typedef mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;
193 typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t;
195 static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
196 unsigned short r1=Unary1::map_index(index1);
197 unsigned short r2=Unary2::map_index(index2);
198 return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);
201 typedef typename bin_reduced_t::unique_t unique_t;
203 template <
typename Bits1,
typename Bits2>
204 static typename Op::result_type
inline apply(
const Bits1& bits1, std::size_t index1,
const Bits2& bits2, std::size_t index2, Op op) {
205 std::pair<const void*,const void*> pr(&bits1, &bits2);
206 return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
211 template <
typename Unary1,
typename Unary2,
typename Op>
212 struct binary_reduce_impl<Unary1,Unary2,Op,true> {
213 template <
typename Bits1,
typename Bits2>
214 static typename Op::result_type
inline apply(
const Bits1& bits1, std::size_t index1,
const Bits2& bits2, std::size_t index2, Op op) {
215 return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);
221 template <
typename Types1,
typename Types2,
typename Op>
222 struct binary_reduce {
224 typedef unary_reduce<Types1,Op> unary1_t;
225 typedef unary_reduce<Types2,Op> unary2_t;
227 static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
228 mpl::size<typename unary2_t::unique_t>::value;
230 typedef detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)> impl;
232 template <
typename Bits1,
typename Bits2>
233 static typename Op::result_type
inline apply(
const Bits1& bits1, std::size_t index1,
const Bits2& bits2, std::size_t index2, Op op) {
234 return impl::apply(bits1,index1,bits2,index2,op);
238 template <
typename Types,
typename UnaryOp>
239 BOOST_FORCEINLINE
typename UnaryOp::result_type
apply_operation(variant<Types>& arg, UnaryOp op) {
240 return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);
243 template <
typename Types,
typename UnaryOp>
244 BOOST_FORCEINLINE
typename UnaryOp::result_type
apply_operation(
const variant<Types>& arg, UnaryOp op) {
245 return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);
248 template <
typename Types1,
typename Types2,
typename BinaryOp>
249 BOOST_FORCEINLINE
typename BinaryOp::result_type
apply_operation(
const variant<Types1>& arg1,
const variant<Types2>& arg2, BinaryOp op) {
250 return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
253 #undef GIL_BINARY_REDUCE_LIMIT
258 namespace boost {
namespace mpl {
278 template <
typename VecOfVecs,
typename TypeGen>
279 struct cross_vector {};
283 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
284 struct cross_iterator {
285 typedef mpl::random_access_iterator_tag category;
297 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
298 struct deref<cross_iterator<VecOfVecs,TypeGen,K> > {
300 typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes;
302 typedef typename TypeGen::template apply<DerefTypes>::type type;
307 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
308 struct next<cross_iterator<VecOfVecs,TypeGen,K> > {
309 typedef cross_iterator<VecOfVecs,TypeGen,K+1> type;
314 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K>
315 struct prior<cross_iterator<VecOfVecs,TypeGen,K> > {
316 typedef cross_iterator<VecOfVecs,TypeGen,K-1> type;
321 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K,
typename Distance>
322 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance > {
323 typedef cross_iterator<VecOfVecs,TypeGen,K+Distance::value> type;
329 template <
typename VecOfVecs,
typename TypeGen, std::
size_t K1, std::
size_t K2>
330 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2> > {
331 typedef size_t<K2-K1> type;
339 template <
typename VecOfVecs,
typename TypeGen>
340 struct size<cross_vector<VecOfVecs,TypeGen> > {
341 typedef typename fold<VecOfVecs, size_t<1>, times<_1, size<_2> > >::type type;
342 static const std::size_t value=type::value;
347 template <
typename VecOfVecs,
typename TypeGen>
348 struct empty<cross_vector<VecOfVecs,TypeGen> > {
349 typedef typename empty<VecOfVecs>::type type;
354 template <
typename VecOfVecs,
typename TypeGen,
typename K>
355 struct at<cross_vector<VecOfVecs,TypeGen>, K> {
357 typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator;
359 typedef typename deref<KthIterator>::type type;
364 template <
typename VecOfVecs,
typename TypeGen>
365 struct begin<cross_vector<VecOfVecs,TypeGen> > {
366 typedef cross_iterator<VecOfVecs,TypeGen,0> type;
371 template <
typename VecOfVecs,
typename TypeGen>
372 struct end<cross_vector<VecOfVecs,TypeGen> > {
374 typedef cross_vector<VecOfVecs,TypeGen> this_t;
376 typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type;
381 template <
typename VecOfVecs,
typename TypeGen>
382 struct front<cross_vector<VecOfVecs,TypeGen> > {
384 typedef cross_vector<VecOfVecs,TypeGen> this_t;
386 typedef typename deref<typename begin<this_t>::type>::type type;
391 template <
typename VecOfVecs,
typename TypeGen>
392 struct back<cross_vector<VecOfVecs,TypeGen> > {
394 typedef cross_vector<VecOfVecs,TypeGen> this_t;
395 typedef typename size<this_t>::type size;
396 typedef typename minus<size, size_t<1> >::type last_index;
398 typedef typename at<this_t, last_index>::type type;
403 template <
typename VecOfVecs,
typename TypeGen,
typename OPP>
404 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP > {
405 typedef typename lambda<OPP>::type Op;
407 template <
typename Elements>
409 typedef typename TypeGen::template apply<Elements>::type orig_t;
410 typedef typename Op::template apply<orig_t>::type type;
413 typedef cross_vector<VecOfVecs, adapter > type;
418 namespace boost {
namespace gil {
420 template <
typename Types,
typename T>
struct type_to_index;
421 template <
typename V>
struct view_is_basic;
436 template <
typename Op,
typename T>
448 template <
typename Op,
typename View,
bool IsBasic>
449 struct reduce_view_basic {
453 template <
typename Op,
typename Loc>
454 struct reduce<Op, image_view<Loc> >
455 :
public reduce_view_basic<Op,image_view<Loc>,view_is_basic<image_view<Loc> >::value> {};
464 template <
typename Op,
typename Img,
bool IsBasic>
465 struct reduce_image_basic {
469 template <
typename Op,
typename V,
typename Alloc>
470 struct reduce<Op, image<V,Alloc> > :
public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc> >::value > {};
479 template <
typename Op,
typename V1,
typename V2,
bool AreBasic>
480 struct reduce_views_basic {
481 typedef std::pair<const V1*, const V2*> type;
484 template <
typename Op,
typename L1,
typename L2>
485 struct reduce<Op, std::pair<const image_view<L1>*, const image_view<L2>*> >
486 :
public reduce_views_basic<Op,image_view<L1>,image_view<L2>,
487 mpl::and_<view_is_basic<image_view<L1> >, view_is_basic<image_view<L2> > >::value >
497 template <
typename Cs>
498 struct reduce_color_space {
502 template <>
struct reduce_color_space<lab_t> {
typedef rgb_t type; };
503 template <>
struct reduce_color_space<hsb_t> {
typedef rgb_t type; };
504 template <>
struct reduce_color_space<cmyk_t> {
typedef rgba_t type; };
612 template <
typename SrcLayout,
typename DstLayout>
613 struct reduce_color_layouts {
614 typedef SrcLayout first_t;
615 typedef DstLayout second_t;
624 struct copy_pixels_fn;
638 template <
typename V1,
typename V2,
bool Compatible>
639 struct reduce_copy_pixop_compat {
640 typedef error_t type;
645 template <
typename V1,
typename V2>
646 struct reduce_copy_pixop_compat<V1,V2,true> {
647 typedef layout<typename V1::color_space_t, typename V1::channel_mapping_t> layout1;
648 typedef layout<typename V2::color_space_t, typename V2::channel_mapping_t> layout2;
650 typedef typename reduce_color_layouts<layout1,layout2>::first_t L1;
651 typedef typename reduce_color_layouts<layout1,layout2>::second_t L2;
653 typedef typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type DV1;
654 typedef typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type DV2;
656 typedef std::pair<const DV1*, const DV2*> type;
660 template <
typename V1,
typename V2>
661 struct reduce_views_basic<copy_pixels_fn, V1, V2, true>
662 :
public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2> >::value > {
671 struct destructor_op;
672 template <
typename View>
struct reduce_view_basic<destructor_op,View,true> {
typedef gray8_view_t type; };
680 struct any_type_get_dimensions;
681 template <
typename View>
struct reduce_view_basic<any_type_get_dimensions,View,true> {
typedef gray8_view_t type; };
682 template <
typename Img>
struct reduce_image_basic<any_type_get_dimensions,Img,true> {
typedef gray8_image_t type; };
690 struct any_type_get_num_channels;
691 template <
typename View>
struct reduce_view_basic<any_type_get_num_channels,View,true> {
692 typedef typename View::color_space_t::base Cs;
693 typedef typename view_type<uint8_t,typename reduce_color_space<Cs>::type>::type type;
695 template <
typename Img>
struct reduce_image_basic<any_type_get_num_channels,Img,true> {
696 typedef typename Img::color_space_t::base Cs;
697 typedef typename image_type<uint8_t,typename reduce_color_space<Cs>::type>::type type;
706 template <
typename Sampler,
typename MapFn>
struct resample_pixels_fn;
708 template <
typename S,
typename M,
typename V,
bool IsBasic>
709 struct reduce_view_basic<resample_pixels_fn<S,M>, V, IsBasic> :
public reduce_view_basic<copy_pixels_fn, V, IsBasic> {};
711 template <
typename S,
typename M,
typename V1,
typename V2,
bool IsBasic>
712 struct reduce_views_basic<resample_pixels_fn<S,M>, V1, V2, IsBasic> :
public reduce_views_basic<copy_pixels_fn, V1, V2, IsBasic> {};
722 template <
typename CC>
class copy_and_convert_pixels_fn;
725 template <
typename CC,
typename View,
bool IsBasic>
726 struct reduce_view_basic<copy_and_convert_pixels_fn<CC>, View, IsBasic>
727 :
public derived_view_type<View, use_default, use_default, use_default, use_default, mpl::true_> {
732 template <
typename CC,
typename V1,
typename V2,
bool AreBasic>
733 struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic> {
734 typedef is_same<typename V1::pixel_t, typename V2::pixel_t> Same;
736 typedef reduce_color_space<typename V1::color_space_t::base> CsR;
737 typedef typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type Cs1;
738 typedef typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type Cs2;
740 typedef typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type DV1;
741 typedef typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type DV2;
743 typedef std::pair<const DV1*, const DV2*> type;
777 #endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT)
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:381
BOOST_FORCEINLINE UnaryOp::result_type 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