Chris@16: /* Chris@16: Copyright 2005-2007 Adobe Systems Incorporated Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: See http://opensource.adobe.com/gil for most recent version including documentation. Chris@16: */ Chris@16: /*************************************************************************************************/ Chris@16: Chris@16: #ifndef GIL_REDUCE_HPP Chris@16: #define GIL_REDUCE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include "../../metafunctions.hpp" Chris@16: #include "../../typedefs.hpp" Chris@16: #include "dynamic_at_c.hpp" Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file Chris@16: /// \brief Constructs for static-to-dynamic integer convesion Chris@16: /// \author Lubomir Bourdev and Hailin Jin \n Chris@16: /// Adobe Systems Incorporated Chris@16: /// \date 2005-2007 \n Last updated on May 4, 2006 Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: Chris@16: #ifdef GIL_REDUCE_CODE_BLOAT Chris@16: Chris@16: Chris@16: // Max number of cases in the cross-expension of binary operation for it to be reduced as unary Chris@16: #define GIL_BINARY_REDUCE_LIMIT 226 Chris@16: Chris@16: namespace boost { namespace mpl { Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// Mapping vector - represents the mapping of one type vector to another Chris@16: /// It is not a full-blown MPL Random Access Type sequence; just has at_c and size implemented Chris@16: /// Chris@16: /// SrcTypes, DstTypes: MPL Random Access Type Sequences Chris@16: /// Chris@16: /// Implements size and at_c to behave as if this is an MPL vector of integers Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct mapping_vector {}; Chris@16: Chris@16: template Chris@16: struct at_c, K> { Chris@16: static const std::size_t value=size::value - order::type>::type::value +1; Chris@16: typedef size_t type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct size > { Chris@16: typedef typename size::type type; Chris@16: static const std::size_t value=type::value; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// copy_to_vector - copies a sequence (mpl::set) to vector. Chris@16: /// Chris@16: /// Temporary solution because I couldn't get mpl::copy to do this. Chris@16: /// This is what I tried: Chris@16: /// mpl::copy > >::type; Chris@16: /// It works when SET is mpl::vector, but not when SET is mpl::set... Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: namespace detail { Chris@16: template Chris@16: struct copy_to_vector_impl { Chris@16: private: Chris@16: typedef typename deref::type T; Chris@16: typedef typename next::type next; Chris@16: typedef typename copy_to_vector_impl::type rest; Chris@16: public: Chris@16: typedef typename push_front::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct copy_to_vector_impl { Chris@16: typedef vector::type> type; Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: struct copy_to_vector { Chris@16: typedef typename detail::copy_to_vector_impl::type, size::value>::type type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct copy_to_vector > { Chris@16: typedef vector0<> type; Chris@16: }; Chris@16: Chris@16: } } // boost::mpl Chris@16: Chris@16: namespace boost { namespace gil { Chris@16: Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// unary_reduce, binary_reduce - given an MPL Random Access Sequence, Chris@16: /// dynamically specified index to that container, the bits of an instance of the corresponding type and Chris@16: /// a generic operation, invokes the operation on the given type Chris@16: /// Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// \brief Unary reduce. Chris@16: /// Chris@16: /// Given a set of types and an operation, reduces each type in the set (to reduced_t), then removes duplicates (to unique_t) Chris@16: /// To apply the operation, first constructs a lookup table that maps each element from Types to its place in unique_t and uses it to map Chris@16: /// the index to anther index (in map_index). Then invokes apply_operation_base on the unique types with the new index. Chris@16: /// Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct unary_reduce_impl { Chris@16: typedef typename mpl::transform >::type reduced_t; Chris@16: typedef typename mpl::copy, mpl::insert > >::type unique_t; Chris@16: static const bool is_single=mpl::size::value==1; Chris@16: }; Chris@16: Chris@16: template ::is_single> Chris@16: struct unary_reduce : public unary_reduce_impl { Chris@16: typedef typename unary_reduce_impl::reduced_t reduced_t; Chris@16: typedef typename unary_reduce_impl::unique_t unique_t; Chris@16: Chris@16: static unsigned short inline map_index(std::size_t index) { Chris@16: typedef typename mpl::mapping_vector indices_t; Chris@16: return gil::at_c(index); Chris@16: } Chris@16: template GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) { Chris@16: return apply_operation_basec(bits,map_index(index),op); Chris@16: } Chris@16: Chris@16: template GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) { Chris@16: return apply_operation_base(bits,map_index(index),op); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct unary_reduce : public unary_reduce_impl { Chris@16: typedef typename unary_reduce_impl::unique_t unique_t; Chris@16: static unsigned short inline map_index(std::size_t index) { return 0; } Chris@16: Chris@16: template GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) { Chris@16: return op(*gil_reinterpret_cast_c::type*>(&bits)); Chris@16: } Chris@16: Chris@16: template GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) { Chris@16: return op(*gil_reinterpret_cast::type*>(&bits)); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// \brief Binary reduce. Chris@16: /// Chris@16: /// Given two sets of types, Types1 and Types2, first performs unary reduction on each. Then checks if the product of their sizes is above Chris@16: /// the GIL_BINARY_REDUCE_LIMIT limit. If so, the operation is too complex to be binary-reduced and uses a specialization of binary_reduce_impl Chris@16: /// to simply call the binary apply_operation_base (which performs two nested 1D apply operations) Chris@16: /// If the operation is not too complex, uses the other specialization of binary_reduce_impl to create a cross-product of the input types Chris@16: /// and performs unary reduction on the result (bin_reduced_t). To apply the binary operation, it simply invokes a unary apply_operation_base Chris@16: /// on the reduced cross-product types Chris@16: /// Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: namespace detail { Chris@16: struct pair_generator { Chris@16: template struct apply { Chris@16: typedef std::pair::type*, const typename mpl::at_c::type*> type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: // When the types are not too large, applies reduce on their cross product Chris@16: template Chris@16: struct binary_reduce_impl { Chris@16: //private: Chris@16: typedef typename mpl::copy_to_vector::type vec1_types; Chris@16: typedef typename mpl::copy_to_vector::type vec2_types; Chris@16: Chris@16: typedef mpl::cross_vector, pair_generator> BIN_TYPES; Chris@16: typedef unary_reduce bin_reduced_t; Chris@16: Chris@16: static unsigned short inline map_index(std::size_t index1, std::size_t index2) { Chris@16: unsigned short r1=Unary1::map_index(index1); Chris@16: unsigned short r2=Unary2::map_index(index2); Chris@16: return bin_reduced_t::map_index(r2*mpl::size::value + r1); Chris@16: } Chris@16: public: Chris@16: typedef typename bin_reduced_t::unique_t unique_t; Chris@16: Chris@16: template Chris@16: static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { Chris@16: std::pair pr(&bits1, &bits2); Chris@16: return apply_operation_basec(pr, map_index(index1,index2),op); Chris@16: } Chris@16: }; Chris@16: Chris@16: // When the types are large performs a double-dispatch. Binary reduction is not done. Chris@16: template Chris@16: struct binary_reduce_impl { Chris@16: template Chris@16: static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { Chris@16: return apply_operation_base(bits1, index1, bits2, index2, op); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: struct binary_reduce { Chris@16: //private: Chris@16: typedef unary_reduce unary1_t; Chris@16: typedef unary_reduce unary2_t; Chris@16: Chris@16: static const std::size_t CROSS_SIZE = mpl::size::value * Chris@16: mpl::size::value; Chris@16: Chris@16: typedef detail::binary_reduce_implGIL_BINARY_REDUCE_LIMIT)> impl; Chris@16: public: Chris@16: template Chris@16: static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { Chris@16: return impl::apply(bits1,index1,bits2,index2,op); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(variant& arg, UnaryOp op) { Chris@16: return unary_reduce::template apply(arg._bits, arg._index ,op); Chris@16: } Chris@16: Chris@16: template Chris@16: GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant& arg, UnaryOp op) { Chris@16: return unary_reduce::template applyc(arg._bits, arg._index ,op); Chris@16: } Chris@16: Chris@16: template Chris@16: GIL_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant& arg1, const variant& arg2, BinaryOp op) { Chris@16: return binary_reduce::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op); Chris@16: } Chris@16: Chris@16: #undef GIL_BINARY_REDUCE_LIMIT Chris@16: Chris@16: } } // namespace gil Chris@16: Chris@16: Chris@16: namespace boost { namespace mpl { Chris@16: /////////////////////////////////////////////////////// Chris@16: /// \brief Represents the virtual cross-product of the types generated from VecOfVecs. Chris@16: /// \ingroup CrossVector Chris@16: /// INPUT: Chris@16: /// VecOfVecs - a vector of vector types. For example [ [A1,A2,A3], [B1,B2], [C1,C2,C3,C4] ] Chris@16: /// Each element must be a non-empty mpl vector Chris@16: /// TypeGen - a metafunction that generates a type from a vector of types, each of which can be Chris@16: /// selected from the corresponding vector in VecOfVecs. For example, [A1, B2, C4] Chris@16: /// Chris@16: /// Represents the virtual cross-product of the types generated from VecOfVecs. Chris@16: /// For example, [ TypeGen[A1,B1,C1], TypeGen[A2,B1,C1], TypeGen[A3,B1,C1], Chris@16: /// TypeGen[A1,B2,C1], TypeGen[A2,B2,C1], TypeGen[A3,B2,C1], Chris@16: /// TypeGen[A1,B1,C2], TypeGen[A2,B1,C2], TypeGen[A3,B1,C2], ... ] Chris@16: /// Chris@16: /// Models an immutable MPL Random Access Sequence Chris@16: /// Traversal, random-access, etc, is defined, but mutable operations, Chris@16: /// such as push_back and pop_front are not supported Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct cross_vector {}; Chris@16: Chris@16: /// \brief Iterator of cross_vector Chris@16: /// \ingroup CrossVectorIterator Chris@16: template Chris@16: struct cross_iterator { Chris@16: typedef mpl::random_access_iterator_tag category; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// Implementation of the iterator functions of cross vector Chris@16: /////////////////////////////////////////////////////// Chris@16: Chris@16: /// \brief Dereferences a cross-vector iterator Chris@16: /// \ingroup CrossVectorIterator Chris@16: /// Creates a vector of the sizes of each type vector in VecOfVecs, then uses it as a basis Chris@16: /// to represent the iterator's position K as a vector of indices. Extracts the corresponding type of Chris@16: /// each input vector and passes the element types to the type generation function, which returns the dereferenced type Chris@16: template Chris@16: struct deref > { Chris@16: private: Chris@16: typedef typename detail::select_subvector_c::type DerefTypes; Chris@16: public: Chris@16: typedef typename TypeGen::template apply::type type; Chris@16: }; Chris@16: Chris@16: /// \brief Increments a cross-vector iterator. Chris@16: /// \ingroup CrossVectorIterator Chris@16: template Chris@16: struct next > { Chris@16: typedef cross_iterator type; Chris@16: }; Chris@16: Chris@16: /// \brief Decrements a cross-vector iterator. Chris@16: /// \ingroup CrossVectorIterator Chris@16: template Chris@16: struct prior > { Chris@16: typedef cross_iterator type; Chris@16: }; Chris@16: Chris@16: /// \brief Advances a cross-vector iterator. Chris@16: /// \ingroup CrossVectorIterator Chris@16: template Chris@16: struct advance, Distance > { Chris@16: typedef cross_iterator type; Chris@16: }; Chris@16: Chris@16: /// \brief Computes the distance between two cross-vector iterator-s. Chris@16: /// \ingroup CrossVectorIterator Chris@16: // (shortened the names of the template arguments - otherwise doxygen cannot parse this...) Chris@16: template Chris@16: struct distance, cross_iterator > { Chris@16: typedef size_t type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////// Chris@16: /// Implementation of cross vector Chris@16: /////////////////////////////////////////////////////// Chris@16: /// \brief Computes the size of a cross vector as the product of the sizes of all vectors in VecOfVecs Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct size > { Chris@16: typedef typename fold, times<_1, size<_2> > >::type type; Chris@16: static const std::size_t value=type::value; Chris@16: }; Chris@16: Chris@16: /// \brief Determines whether a cross vector is empty Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct empty > { Chris@16: typedef typename empty::type type; Chris@16: }; Chris@16: Chris@16: /// \brief Returns the K-th element of a cross vector Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct at, K> { Chris@16: private: Chris@16: typedef cross_iterator KthIterator; Chris@16: public: Chris@16: typedef typename deref::type type; Chris@16: }; Chris@16: Chris@16: /// \brief Returns an iterator to the first element of a cross vector Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct begin > { Chris@16: typedef cross_iterator type; Chris@16: }; Chris@16: Chris@16: /// \brief Returns an iterator to the last element of a cross vector Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct end > { Chris@16: private: Chris@16: typedef cross_vector this_t; Chris@16: public: Chris@16: typedef cross_iterator::value> type; Chris@16: }; Chris@16: Chris@16: /// \brief Returns the first element of a cross vector Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct front > { Chris@16: private: Chris@16: typedef cross_vector this_t; Chris@16: public: Chris@16: typedef typename deref::type>::type type; Chris@16: }; Chris@16: Chris@16: /// \brief Returns the last element of a cross vector Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct back > { Chris@16: private: Chris@16: typedef cross_vector this_t; Chris@16: typedef typename size::type size; Chris@16: typedef typename minus >::type last_index; Chris@16: public: Chris@16: typedef typename at::type type; Chris@16: }; Chris@16: Chris@16: /// \brief Transforms the elements of a cross vector Chris@16: /// \ingroup CrossVector Chris@16: template Chris@16: struct transform, OPP > { Chris@16: typedef typename lambda::type Op; Chris@16: struct adapter { Chris@16: template Chris@16: struct apply { Chris@16: typedef typename TypeGen::template apply::type orig_t; Chris@16: typedef typename Op::template apply::type type; Chris@16: }; Chris@16: }; Chris@16: typedef cross_vector type; Chris@16: }; Chris@16: Chris@16: } } // boost::mpl Chris@16: Chris@16: namespace boost { namespace gil { Chris@16: Chris@16: template struct type_to_index; Chris@16: template struct view_is_basic; Chris@16: struct rgb_t; Chris@16: struct lab_t; Chris@16: struct hsb_t; Chris@16: struct cmyk_t; Chris@16: struct rgba_t; Chris@16: struct error_t; Chris@16: Chris@16: Chris@16: namespace detail { Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Generic reduce operation Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: template Chris@16: struct reduce { Chris@16: typedef T type; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Unary reduce_view operation. Splits into basic and non-basic views. Chris@16: //// Algorithm-specific reduce should specialize for basic views Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct reduce_view_basic { Chris@16: typedef View type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct reduce > Chris@16: : public reduce_view_basic,view_is_basic >::value> {}; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Unary reduce_image operation. Splits into basic and non-basic images. Chris@16: //// Algorithm-specific reduce should specialize for basic images Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct reduce_image_basic { Chris@16: typedef Img type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct reduce > : public reduce_image_basic,image_is_basic >::value > {}; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Binary reduce_view operation. Splits into basic and non-basic views. Chris@16: //// Algorithm-specific reduce should specialize for basic views Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct reduce_views_basic { Chris@16: typedef std::pair type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct reduce*, const image_view*> > Chris@16: : public reduce_views_basic,image_view, Chris@16: mpl::and_ >, view_is_basic > >::value > Chris@16: {}; Chris@16: Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Color space unary reduce operation. Reduce a color space to a base with the same number of channels Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct reduce_color_space { Chris@16: typedef Cs type; Chris@16: }; Chris@16: Chris@16: template <> struct reduce_color_space { typedef rgb_t type; }; Chris@16: template <> struct reduce_color_space { typedef rgb_t type; }; Chris@16: template <> struct reduce_color_space { typedef rgba_t type; }; Chris@16: Chris@16: /* Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Color space binary reduce operation. Given a source and destination color spaces, Chris@16: //// returns a reduced source and destination color spaces that have the same mapping of channels Chris@16: //// Chris@16: //// Precondition: The two color spaces must be compatible (i.e. must have the same set of channels) Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct type_vec_to_integer_impl { Chris@16: typedef typename mpl::back::type last; Chris@16: typedef typename mpl::pop_back::type rest; Chris@16: static const int value = type_vec_to_integer_impl::value * Basis + last::value; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct type_vec_to_integer_impl { Chris@16: static const int value=0; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct type_vec_to_integer { Chris@16: static const int value = type_vec_to_integer_impl::value>::value; Chris@16: }; Chris@16: Chris@16: // Given two color spaces and the mapping of the channels between them, returns the reduced pair of color spaces Chris@16: // The default version performs no reduction Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef SrcColorSpace first_t; Chris@16: typedef DstColorSpace second_t; Chris@16: }; Chris@16: Chris@16: // 012: RGB-RGB, bgr-bgr, lab-lab, hsb-hsb Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef rgb_t first_t; Chris@16: typedef rgb_t second_t; Chris@16: }; Chris@16: Chris@16: // 210: RGB-bgr, bgr-RGB Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef rgb_t first_t; Chris@16: typedef bgr_t second_t; Chris@16: }; Chris@16: Chris@16: // 0123: RGBA-RGBA, bgra-bgra, argb-argb, abgr-abgr cmyk-cmyk Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef rgba_t first_t; Chris@16: typedef rgba_t second_t; Chris@16: }; Chris@16: Chris@16: // 3210: RGBA-abgr, bgra-argb, argb-bgra, abgr-RGBA Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef rgba_t first_t; Chris@16: typedef abgr_t second_t; Chris@16: }; Chris@16: Chris@16: // 1230: RGBA-argb, bgra-abgr Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef rgba_t first_t; Chris@16: typedef argb_t second_t; Chris@16: }; Chris@16: Chris@16: // 2103: RGBA-bgra, bgra-RGBA (uses subclass to ensure that base color space is not reduced to derived) Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef rgba_t first_t; Chris@16: typedef bgra_t second_t; Chris@16: }; Chris@16: Chris@16: // 3012: argb-RGBA, abgr-bgra Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef argb_t first_t; Chris@16: typedef rgba_t second_t; Chris@16: }; Chris@16: Chris@16: // 0321: argb-abgr, abgr-argb Chris@16: template Chris@16: struct reduce_color_spaces_impl { Chris@16: typedef argb_t first_t; Chris@16: typedef abgr_t second_t; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct reduce_color_spaces { Chris@16: typedef typename channel_order::type src_order_t; Chris@16: typedef typename channel_order::type dst_order_t; Chris@16: typedef typename mpl::transform >::type mapping; Chris@16: static const int mapping_val = type_vec_to_integer::value; Chris@16: Chris@16: typedef typename reduce_color_spaces_impl::first_t _first_t; Chris@16: typedef typename reduce_color_spaces_impl::second_t _second_t; Chris@16: typedef typename mpl::and_, mpl::not_< color_space_is_base<_second_t> > > swap_t; Chris@16: public: Chris@16: typedef typename mpl::if_::type first_t; Chris@16: typedef typename mpl::if_::type second_t; Chris@16: }; Chris@16: */ Chris@16: // TODO: Use the old code for reduce_color_spaces above to do color layout reduction Chris@16: template Chris@16: struct reduce_color_layouts { Chris@16: typedef SrcLayout first_t; Chris@16: typedef DstLayout second_t; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Reduce for copy_pixels Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: struct copy_pixels_fn; Chris@16: Chris@16: /* Chris@16: // 1D reduce for copy_pixels reduces the channel to mutable and the color space to its base with same dimensions Chris@16: template Chris@16: struct reduce_view_basic { Chris@16: private: Chris@16: typedef typename reduce_color_space::type Cs; // reduce the color space Chris@16: typedef layout layout_t; Chris@16: public: Chris@16: typedef typename derived_view_type::type type; Chris@16: }; Chris@16: */ Chris@16: // Incompatible views cannot be used in copy_pixels - will throw std::bad_cast Chris@16: template Chris@16: struct reduce_copy_pixop_compat { Chris@16: typedef error_t type; Chris@16: }; Chris@16: Chris@16: // For compatible basic views, reduce their color spaces based on their channel mapping. Chris@16: // Make the source immutable and the destination mutable (they should already be that way) Chris@16: template Chris@16: struct reduce_copy_pixop_compat { Chris@16: typedef layout layout1; Chris@16: typedef layout layout2; Chris@16: Chris@16: typedef typename reduce_color_layouts::first_t L1; Chris@16: typedef typename reduce_color_layouts::second_t L2; Chris@16: Chris@16: typedef typename derived_view_type::type DV1; Chris@16: typedef typename derived_view_type::type DV2; Chris@16: Chris@16: typedef std::pair type; Chris@16: }; Chris@16: Chris@16: // The general 2D version branches into compatible and incompatible views Chris@16: template Chris@16: struct reduce_views_basic Chris@16: : public reduce_copy_pixop_compat, view_is_mutable >::value > { Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Reduce for variant destructor (basic views have no destructor) Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: struct destructor_op; Chris@16: template struct reduce_view_basic { typedef gray8_view_t type; }; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Reduce for get_dimensions (basic views and images have the same structure and the dimensions are contained at the beginning) Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: struct any_type_get_dimensions; Chris@16: template struct reduce_view_basic { typedef gray8_view_t type; }; Chris@16: template struct reduce_image_basic { typedef gray8_image_t type; }; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Reduce for get_num_channels (only color space matters) Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: struct any_type_get_num_channels; Chris@16: template struct reduce_view_basic { Chris@16: typedef typename View::color_space_t::base Cs; Chris@16: typedef typename view_type::type>::type type; Chris@16: }; Chris@16: template struct reduce_image_basic { Chris@16: typedef typename Img::color_space_t::base Cs; Chris@16: typedef typename image_type::type>::type type; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Reduce for resample_pixels (same as copy_pixels) Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: template struct resample_pixels_fn; Chris@16: Chris@16: template Chris@16: struct reduce_view_basic, V, IsBasic> : public reduce_view_basic {}; Chris@16: Chris@16: template Chris@16: struct reduce_views_basic, V1, V2, IsBasic> : public reduce_views_basic {}; Chris@16: Chris@16: //////////////////////////////////////////////////////// Chris@16: //// Chris@16: //// Reduce for copy_and_convert_pixels Chris@16: //// (the only reduction could be made when views are compatible and have the same mapping, planarity and stepness) Chris@16: //// Chris@16: //////////////////////////////////////////////////////// Chris@16: Chris@16: Chris@16: template class copy_and_convert_pixels_fn; Chris@16: Chris@16: // the only thing for 1D reduce is making them all mutable... Chris@16: template Chris@16: struct reduce_view_basic, View, IsBasic> Chris@16: : public derived_view_type { Chris@16: }; Chris@16: Chris@16: // For 2D reduce, if they have the same channels and color spaces (i.e. the same pixels) then copy_and_convert is just copy. Chris@16: // In this case, reduce their common color space. In general make the first immutable and the second mutable Chris@16: template Chris@16: struct reduce_views_basic, V1, V2, AreBasic> { Chris@16: typedef is_same Same; Chris@16: Chris@16: typedef reduce_color_space CsR; Chris@16: typedef typename mpl::if_::type Cs1; Chris@16: typedef typename mpl::if_::type Cs2; Chris@16: Chris@16: typedef typename derived_view_type, use_default, use_default, mpl::false_>::type DV1; Chris@16: typedef typename derived_view_type, use_default, use_default, mpl::true_ >::type DV2; Chris@16: Chris@16: typedef std::pair type; Chris@16: }; Chris@16: Chris@16: Chris@16: //integral_image_generator Chris@16: //resize_clobber_image_fnobj Chris@16: //image_default_construct_fnobj Chris@16: //fill_converted_pixels_fn Chris@16: //bind(gil::detail::copy_pixels_fn(), _1, dst) Chris@16: //bind(gil::detail::copy_pixels_fn(), src,_1) Chris@16: Chris@16: //bind(detail::copy_and_convert_pixels_fn(), _1, dst) Chris@16: //bind(detail::copy_and_convert_pixels_fn(), src, _1) Chris@16: //gil::detail::fill_pixels_fn(val) Chris@16: Chris@16: //detail::copy_construct_in_place_fn Chris@16: //detail::equal_to_fn::base_t> Chris@16: Chris@16: //detail::any_image_get_view::view_t> Chris@16: //detail::any_image_get_const_view::view_t> Chris@16: //detail::flipped_up_down_view_fn > Chris@16: //detail::flipped_left_right_view_fn::dynamic_step_t> Chris@16: //detail::tranposed_view_fn::dynamic_step_t> Chris@16: //detail::rotated90cw_view_fn::dynamic_step_t> Chris@16: //detail::rotated90ccw_view_fn::dynamic_step_t> Chris@16: //detail::rotated180_view_fn::dynamic_step_t> Chris@16: //detail::subimage_view_fn > Chris@16: //detail::subsampled_view_fn::dynamic_step_t> Chris@16: //detail::nth_channel_view_fn > Chris@16: //detail::color_converted_view_fn, DstP>::type > Chris@16: } Chris@16: Chris@16: } } // namespace boost::gil Chris@16: Chris@16: #endif // GIL_REDUCE_CODE_BLOAT Chris@16: Chris@16: Chris@16: #endif