Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:12:39

0001 //
0002 // Copyright 2005-2007 Adobe Systems Incorporated
0003 // Copyright 2019 Mateusz Loskot <mateusz at loskot dot net>
0004 //
0005 // Distributed under the Boost Software License, Version 1.0
0006 // See accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt
0008 //
0009 #ifndef BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
0010 #define BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
0011 
0012 #include <boost/gil/concepts.hpp>
0013 #include <boost/gil/utilities.hpp>
0014 #include <boost/gil/detail/mp11.hpp>
0015 
0016 #include <boost/config.hpp>
0017 
0018 #include <algorithm>
0019 #include <type_traits>
0020 
0021 namespace boost { namespace gil {
0022 
0023 ///////////////////////////////////////
0024 /// size:   Semantic channel size
0025 ///////////////////////////////////////
0026 
0027 /**
0028 \defgroup ColorBaseAlgorithmSize size
0029 \ingroup ColorBaseAlgorithm
0030 \brief Returns an integral constant type specifying the number of elements in a color base
0031 
0032 Example:
0033 \code
0034 static_assert(size<rgb8_pixel_t>::value == 3, "");
0035 static_assert(size<cmyk8_planar_ptr_t>::value == 4, "");
0036 \endcode
0037 */
0038 
0039 /// \brief Returns an integral constant type specifying the number of elements in a color base
0040 /// \ingroup ColorBaseAlgorithmSize
0041 template <typename ColorBase>
0042 struct size : public mp11::mp_size<typename ColorBase::layout_t::color_space_t> {};
0043 
0044 ///////////////////////////////////////
0045 /// semantic_at_c:   Semantic channel accessors
0046 ///////////////////////////////////////
0047 
0048 /**
0049 \defgroup ColorBaseAlgorithmSemanticAtC kth_semantic_element_type, kth_semantic_element_reference_type, kth_semantic_element_const_reference_type, semantic_at_c
0050 \ingroup ColorBaseAlgorithm
0051 \brief Support for accessing the elements of a color base by semantic index
0052 
0053 The semantic index of an element is the index of its color in the color space. Semantic indexing allows for proper pairing of elements of color bases
0054 independent on their layout. For example, red is the first semantic element of a color base regardless of whether it has an RGB layout or a BGR layout.
0055 All GIL color base algorithms taking multiple color bases use semantic indexing to access their elements.
0056 
0057 Example:
0058 \code
0059 // 16-bit BGR pixel, 4 bits for the blue, 3 bits for the green, 2 bits for the red channel and 7 unused bits
0060 using bgr432_pixel_t = packed_pixel_type<uint16_t, mp11::mp_list_c<unsigned,4,3,2>, bgr_layout_t>::type;
0061 
0062 // A reference to its red channel. Although the red channel is the third, its semantic index is 0 in the RGB color space
0063 using red_channel_reference_t = kth_semantic_element_reference_type<bgr432_pixel_t, 0>::type;
0064 
0065 // Initialize the pixel to black
0066 bgr432_pixel_t red_pixel(0,0,0);
0067 
0068 // Set the red channel to 100%
0069 red_channel_reference_t red_channel = semantic_at_c<0>(red_pixel);
0070 red_channel = channel_traits<red_channel_reference_t>::max_value();
0071 
0072 \endcode
0073 */
0074 /// \brief Specifies the type of the K-th semantic element of a color base
0075 /// \ingroup ColorBaseAlgorithmSemanticAtC
0076 template <typename ColorBase, int K>
0077 struct kth_semantic_element_type
0078 {
0079     using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
0080     static_assert(K < mp11::mp_size<channel_mapping_t>::value,
0081         "K index should be less than size of channel_mapping_t sequence");
0082 
0083     static constexpr int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
0084     using type = typename kth_element_type<ColorBase, semantic_index>::type;
0085 };
0086 
0087 /// \brief Specifies the return type of the mutable semantic_at_c<K>(color_base);
0088 /// \ingroup ColorBaseAlgorithmSemanticAtC
0089 template <typename ColorBase, int K>
0090 struct kth_semantic_element_reference_type
0091 {
0092     using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
0093     static_assert(K < mp11::mp_size<channel_mapping_t>::value,
0094         "K index should be less than size of channel_mapping_t sequence");
0095 
0096     static constexpr int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
0097     using type = typename kth_element_reference_type<ColorBase, semantic_index>::type;
0098     static type get(ColorBase& cb) { return gil::at_c<semantic_index>(cb); }
0099 };
0100 
0101 /// \brief Specifies the return type of the constant semantic_at_c<K>(color_base);
0102 /// \ingroup ColorBaseAlgorithmSemanticAtC
0103 template <typename ColorBase, int K>
0104 struct kth_semantic_element_const_reference_type
0105 {
0106     using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
0107     static_assert(K < mp11::mp_size<channel_mapping_t>::value,
0108         "K index should be less than size of channel_mapping_t sequence");
0109 
0110     static constexpr int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
0111     using type = typename kth_element_const_reference_type<ColorBase,semantic_index>::type;
0112     static type get(const ColorBase& cb) { return gil::at_c<semantic_index>(cb); }
0113 };
0114 
0115 /// \brief A mutable accessor to the K-th semantic element of a color base
0116 /// \ingroup ColorBaseAlgorithmSemanticAtC
0117 template <int K, typename ColorBase>
0118 inline
0119 auto semantic_at_c(ColorBase& p)
0120     -> typename std::enable_if
0121     <
0122         !std::is_const<ColorBase>::value,
0123         typename kth_semantic_element_reference_type<ColorBase, K>::type
0124     >::type
0125 {
0126     return kth_semantic_element_reference_type<ColorBase, K>::get(p);
0127 }
0128 
0129 /// \brief A constant accessor to the K-th semantic element of a color base
0130 /// \ingroup ColorBaseAlgorithmSemanticAtC
0131 template <int K, typename ColorBase>
0132 inline
0133 auto semantic_at_c(ColorBase const& p)
0134     -> typename kth_semantic_element_const_reference_type<ColorBase, K>::type
0135 {
0136     return kth_semantic_element_const_reference_type<ColorBase, K>::get(p);
0137 }
0138 
0139 ///////////////////////////////////////
0140 /// get_color:   Named channel accessors
0141 ///////////////////////////////////////
0142 
0143 /**
0144 \defgroup ColorBaseAlgorithmColor color_element_type, color_element_reference_type, color_element_const_reference_type, get_color, contains_color
0145 \ingroup ColorBaseAlgorithm
0146 \brief Support for accessing the elements of a color base by color name
0147 
0148 Example: A function that takes a generic pixel containing a red channel and sets it to 100%:
0149 
0150 \code
0151 template <typename Pixel>
0152 void set_red_to_max(Pixel& pixel) {
0153     boost::function_requires<MutablePixelConcept<Pixel> >();
0154     static_assert(contains_color<Pixel, red_t>::value, "");
0155 
0156     using red_channel_t = typename color_element_type<Pixel, red_t>::type;
0157     get_color(pixel, red_t()) = channel_traits<red_channel_t>::max_value();
0158 }
0159 \endcode
0160 */
0161 
0162 /// \brief A predicate metafunction determining whether a given color base contains a given color
0163 /// \ingroup ColorBaseAlgorithmColor
0164 template <typename ColorBase, typename Color>
0165 struct contains_color
0166     : mp11::mp_contains<typename ColorBase::layout_t::color_space_t, Color>
0167 {};
0168 
0169 template <typename ColorBase, typename Color>
0170 struct color_index_type : public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
0171 
0172 /// \brief Specifies the type of the element associated with a given color tag
0173 /// \ingroup ColorBaseAlgorithmColor
0174 template <typename ColorBase, typename Color>
0175 struct color_element_type : public kth_semantic_element_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
0176 
0177 /// \brief Specifies the return type of the mutable element accessor by color name, get_color(color_base, Color());
0178 /// \ingroup ColorBaseAlgorithmColor
0179 template <typename ColorBase, typename Color>
0180 struct color_element_reference_type : public kth_semantic_element_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
0181 
0182 /// \brief Specifies the return type of the constant element accessor by color name, get_color(color_base, Color());
0183 /// \ingroup ColorBaseAlgorithmColor
0184 template <typename ColorBase, typename Color>
0185 struct color_element_const_reference_type : public kth_semantic_element_const_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
0186 
0187 /// \brief Mutable accessor to the element associated with a given color name
0188 /// \ingroup ColorBaseAlgorithmColor
0189 template <typename ColorBase, typename Color>
0190 auto get_color(ColorBase& cb, Color=Color()) 
0191     -> typename color_element_reference_type<ColorBase,Color>::type
0192 {
0193     return color_element_reference_type<ColorBase,Color>::get(cb);
0194 }
0195 
0196 /// \brief Constant accessor to the element associated with a given color name
0197 /// \ingroup ColorBaseAlgorithmColor
0198 template <typename ColorBase, typename Color>
0199 auto get_color(const ColorBase& cb, Color=Color())
0200     -> typename color_element_const_reference_type<ColorBase,Color>::type
0201 {
0202     return color_element_const_reference_type<ColorBase,Color>::get(cb);
0203 }
0204 
0205 ///////////////////////////////////////
0206 ///
0207 /// element_type, element_reference_type, element_const_reference_type: Support for homogeneous color bases
0208 ///
0209 ///////////////////////////////////////
0210 
0211 /**
0212 \defgroup ColorBaseAlgorithmHomogeneous element_type, element_reference_type, element_const_reference_type
0213 \ingroup ColorBaseAlgorithm
0214 \brief Types for homogeneous color bases
0215 
0216 Example:
0217 \code
0218 using element_t = element_type<rgb8c_planar_ptr_t>::type;
0219 static_assert(std::is_same<element_t, const uint8_t*>::value, "");
0220 \endcode
0221 */
0222 /// \brief Specifies the element type of a homogeneous color base
0223 /// \ingroup ColorBaseAlgorithmHomogeneous
0224 template <typename ColorBase>
0225 struct element_type : public kth_element_type<ColorBase, 0> {};
0226 
0227 /// \brief Specifies the return type of the mutable element accessor at_c of a homogeneous color base
0228 /// \ingroup ColorBaseAlgorithmHomogeneous
0229 template <typename ColorBase>
0230 struct element_reference_type : public kth_element_reference_type<ColorBase, 0> {};
0231 
0232 /// \brief Specifies the return type of the constant element accessor at_c of a homogeneous color base
0233 /// \ingroup ColorBaseAlgorithmHomogeneous
0234 template <typename ColorBase>
0235 struct element_const_reference_type : public kth_element_const_reference_type<ColorBase, 0> {};
0236 
0237 
0238 namespace detail {
0239 
0240 // compile-time recursion for per-element operations on color bases
0241 template <int N>
0242 struct element_recursion
0243 {
0244 
0245 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0246 #pragma GCC diagnostic push
0247 #pragma GCC diagnostic ignored "-Wconversion"
0248 #pragma GCC diagnostic ignored "-Wfloat-equal"
0249 #endif
0250 
0251     template <typename P1,typename P2>
0252     static bool static_equal(const P1& p1, const P2& p2)
0253     {
0254         return element_recursion<N-1>::static_equal(p1,p2) &&
0255                semantic_at_c<N-1>(p1)==semantic_at_c<N-1>(p2);
0256     }
0257 
0258     template <typename P1,typename P2>
0259     static void static_copy(const P1& p1, P2& p2)
0260     {
0261         element_recursion<N-1>::static_copy(p1,p2);
0262         semantic_at_c<N-1>(p2)=semantic_at_c<N-1>(p1);
0263     }
0264 
0265     template <typename P,typename T2>
0266     static void static_fill(P& p, T2 v)
0267     {
0268         element_recursion<N-1>::static_fill(p,v);
0269         semantic_at_c<N-1>(p)=v;
0270     }
0271 
0272     template <typename Dst,typename Op>
0273     static void static_generate(Dst& dst, Op op)
0274     {
0275         element_recursion<N-1>::static_generate(dst,op);
0276         semantic_at_c<N-1>(dst)=op();
0277     }
0278 
0279 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0280 #pragma GCC diagnostic pop
0281 #endif
0282 
0283     //static_for_each with one source
0284     template <typename P1,typename Op>
0285     static Op static_for_each(P1& p1, Op op) {
0286         Op op2(element_recursion<N-1>::static_for_each(p1,op));
0287         op2(semantic_at_c<N-1>(p1));
0288         return op2;
0289     }
0290     template <typename P1,typename Op>
0291     static Op static_for_each(const P1& p1, Op op) {
0292         Op op2(element_recursion<N-1>::static_for_each(p1,op));
0293         op2(semantic_at_c<N-1>(p1));
0294         return op2;
0295     }
0296     //static_for_each with two sources
0297     template <typename P1,typename P2,typename Op>
0298     static Op static_for_each(P1& p1, P2& p2, Op op) {
0299         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0300         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0301         return op2;
0302     }
0303     template <typename P1,typename P2,typename Op>
0304     static Op static_for_each(P1& p1, const P2& p2, Op op) {
0305         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0306         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0307         return op2;
0308     }
0309     template <typename P1,typename P2,typename Op>
0310     static Op static_for_each(const P1& p1, P2& p2, Op op) {
0311         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0312         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0313         return op2;
0314     }
0315     template <typename P1,typename P2,typename Op>
0316     static Op static_for_each(const P1& p1, const P2& p2, Op op) {
0317         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0318         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0319         return op2;
0320     }
0321     //static_for_each with three sources
0322     template <typename P1,typename P2,typename P3,typename Op>
0323     static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
0324         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0325         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0326         return op2;
0327     }
0328     template <typename P1,typename P2,typename P3,typename Op>
0329     static Op static_for_each(P1& p1, P2& p2, const P3& p3, Op op) {
0330         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0331         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0332         return op2;
0333     }
0334     template <typename P1,typename P2,typename P3,typename Op>
0335     static Op static_for_each(P1& p1, const P2& p2, P3& p3, Op op) {
0336         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0337         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0338         return op2;
0339     }
0340     template <typename P1,typename P2,typename P3,typename Op>
0341     static Op static_for_each(P1& p1, const P2& p2, const P3& p3, Op op) {
0342         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0343         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0344         return op2;
0345     }
0346     template <typename P1,typename P2,typename P3,typename Op>
0347     static Op static_for_each(const P1& p1, P2& p2, P3& p3, Op op) {
0348         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0349         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0350         return op2;
0351     }
0352     template <typename P1,typename P2,typename P3,typename Op>
0353     static Op static_for_each(const P1& p1, P2& p2, const P3& p3, Op op) {
0354         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0355         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0356         return op2;
0357     }
0358     template <typename P1,typename P2,typename P3,typename Op>
0359     static Op static_for_each(const P1& p1, const P2& p2, P3& p3, Op op) {
0360         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0361         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0362         return op2;
0363     }
0364     template <typename P1,typename P2,typename P3,typename Op>
0365     static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, Op op) {
0366         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0367         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0368         return op2;
0369     }
0370     //static_transform with one source
0371     template <typename P1,typename Dst,typename Op>
0372     static Op static_transform(P1& src, Dst& dst, Op op) {
0373         Op op2(element_recursion<N-1>::static_transform(src,dst,op));
0374         semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
0375         return op2;
0376     }
0377     template <typename P1,typename Dst,typename Op>
0378     static Op static_transform(const P1& src, Dst& dst, Op op) {
0379         Op op2(element_recursion<N-1>::static_transform(src,dst,op));
0380         semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
0381         return op2;
0382     }
0383     //static_transform with two sources
0384     template <typename P1,typename P2,typename Dst,typename Op>
0385     static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
0386         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0387         semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0388         return op2;
0389     }
0390     template <typename P1,typename P2,typename Dst,typename Op>
0391     static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) {
0392         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0393         semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0394         return op2;
0395     }
0396     template <typename P1,typename P2,typename Dst,typename Op>
0397     static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) {
0398         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0399         semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0400         return op2;
0401     }
0402     template <typename P1,typename P2,typename Dst,typename Op>
0403     static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) {
0404         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0405         semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0406         return op2;
0407     }
0408 };
0409 
0410 // Termination condition of the compile-time recursion for element operations on a color base
0411 template<> struct element_recursion<0> {
0412     //static_equal
0413     template <typename P1,typename P2>
0414     static bool static_equal(const P1&, const P2&) { return true; }
0415     //static_copy
0416     template <typename P1,typename P2>
0417     static void static_copy(const P1&, const P2&) {}
0418     //static_fill
0419     template <typename P, typename T2>
0420     static void static_fill(const P&, T2) {}
0421     //static_generate
0422     template <typename Dst,typename Op>
0423     static void static_generate(const Dst&,Op){}
0424     //static_for_each with one source
0425     template <typename P1,typename Op>
0426     static Op static_for_each(const P1&,Op op){return op;}
0427     //static_for_each with two sources
0428     template <typename P1,typename P2,typename Op>
0429     static Op static_for_each(const P1&,const P2&,Op op){return op;}
0430     //static_for_each with three sources
0431     template <typename P1,typename P2,typename P3,typename Op>
0432     static Op static_for_each(const P1&,const P2&,const P3&,Op op){return op;}
0433     //static_transform with one source
0434     template <typename P1,typename Dst,typename Op>
0435     static Op static_transform(const P1&,const Dst&,Op op){return op;}
0436     //static_transform with two sources
0437     template <typename P1,typename P2,typename Dst,typename Op>
0438     static Op static_transform(const P1&,const P2&,const Dst&,Op op){return op;}
0439 };
0440 
0441 // std::min and std::max don't have the mutable overloads...
0442 template <typename Q>
0443 inline auto mutable_min(Q const& x, Q const& y) -> Q const& { return x<y ? x : y; }
0444 
0445 template <typename Q>
0446 inline auto mutable_min(Q& x, Q& y) -> Q& { return x<y ? x : y; }
0447 
0448 template <typename Q>
0449 inline auto mutable_max(Q const& x, Q const& y) -> Q const& { return x<y ? y : x; }
0450 
0451 template <typename Q>
0452 inline auto mutable_max(Q& x, Q& y) -> Q& { return x<y ? y : x; }
0453 
0454 
0455 // compile-time recursion for min/max element
0456 template <int N>
0457 struct min_max_recur
0458 {
0459     template <typename P>
0460     static auto max_(P const& p) -> typename element_const_reference_type<P>::type
0461     {
0462         return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
0463     }
0464     
0465     template <typename P>
0466     static auto max_(P& p) -> typename element_reference_type<P>::type
0467     {
0468         return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
0469     }
0470     
0471     template <typename P>
0472     static auto min_(P const& p) -> typename element_const_reference_type<P>::type 
0473     {
0474         return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
0475     }
0476     
0477     template <typename P>
0478     static auto min_(P& p) -> typename element_reference_type<P>::type
0479     {
0480         return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
0481     }
0482 };
0483 
0484 // termination condition of the compile-time recursion for min/max element
0485 template <>
0486 struct min_max_recur<1>
0487 {
0488     template <typename P>
0489     static auto max_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
0490     
0491     template <typename P>
0492     static auto max_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
0493     
0494     template <typename P>
0495     static auto min_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
0496     
0497     template <typename P>
0498     static auto min_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
0499 };
0500 }  // namespace detail
0501 
0502 /// \defgroup ColorBaseAlgorithmMinMax static_min, static_max
0503 /// \ingroup ColorBaseAlgorithm
0504 /// \brief Equivalents to std::min_element and std::max_element for homogeneous color bases
0505 ///
0506 /// Example:
0507 /// \code
0508 /// rgb8_pixel_t pixel(10,20,30);
0509 /// assert(pixel[2] == 30);
0510 /// static_max(pixel) = static_min(pixel);
0511 /// assert(pixel[2] == 10);
0512 /// \endcode
0513 /// \{
0514 
0515 template <typename P>
0516 BOOST_FORCEINLINE
0517 auto static_max(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
0518 
0519 template <typename P>
0520 BOOST_FORCEINLINE
0521 auto static_max(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
0522 
0523 template <typename P>
0524 BOOST_FORCEINLINE
0525 auto static_min(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
0526 
0527 template <typename P>
0528 BOOST_FORCEINLINE
0529 auto static_min(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
0530 /// \}
0531 
0532 /// \defgroup ColorBaseAlgorithmEqual static_equal
0533 /// \ingroup ColorBaseAlgorithm
0534 /// \brief Equivalent to std::equal. Pairs the elements semantically
0535 ///
0536 /// Example:
0537 /// \code
0538 /// rgb8_pixel_t rgb_red(255,0,0);
0539 /// bgr8_pixel_t bgr_red(0,0,255);
0540 /// assert(rgb_red[0]==255 && bgr_red[0]==0);
0541 ///
0542 /// assert(static_equal(rgb_red,bgr_red));
0543 /// assert(rgb_red==bgr_red);  // operator== invokes static_equal
0544 /// \endcode
0545 /// \{
0546 
0547 template <typename P1,typename P2>
0548 BOOST_FORCEINLINE
0549 bool static_equal(P1 const& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
0550 
0551 /// \}
0552 
0553 /// \defgroup ColorBaseAlgorithmCopy static_copy
0554 /// \ingroup ColorBaseAlgorithm
0555 /// \brief Equivalent to std::copy. Pairs the elements semantically
0556 ///
0557 /// Example:
0558 /// \code
0559 /// rgb8_pixel_t rgb_red(255,0,0);
0560 /// bgr8_pixel_t bgr_red;
0561 /// static_copy(rgb_red, bgr_red);  // same as bgr_red = rgb_red
0562 ///
0563 /// assert(rgb_red[0] == 255 && bgr_red[0] == 0);
0564 /// assert(rgb_red == bgr_red);
0565 /// \endcode
0566 /// \{
0567 
0568 template <typename Src,typename Dst>
0569 BOOST_FORCEINLINE
0570 void static_copy(const Src& src, Dst& dst)
0571 {
0572     detail::element_recursion<size<Dst>::value>::static_copy(src, dst);
0573 }
0574 
0575 /// \}
0576 
0577 /// \defgroup ColorBaseAlgorithmFill static_fill
0578 /// \ingroup ColorBaseAlgorithm
0579 /// \brief Equivalent to std::fill.
0580 ///
0581 /// Example:
0582 /// \code
0583 /// rgb8_pixel_t p;
0584 /// static_fill(p, 10);
0585 /// assert(p == rgb8_pixel_t(10,10,10));
0586 /// \endcode
0587 /// \{
0588 
0589 template <typename P,typename V>
0590 BOOST_FORCEINLINE
0591 void static_fill(P& p, const V& v)
0592 {
0593     detail::element_recursion<size<P>::value>::static_fill(p,v);
0594 }
0595 
0596 /// \}
0597 
0598 /// \defgroup ColorBaseAlgorithmGenerate static_generate
0599 /// \ingroup ColorBaseAlgorithm
0600 /// \brief Equivalent to std::generate.
0601 ///
0602 /// Example: Set each channel of a pixel to its semantic index. The channels must be assignable from an integer.
0603 /// \code
0604 /// struct consecutive_fn {
0605 ///     int& _current;
0606 ///     consecutive_fn(int& start) : _current(start) {}
0607 ///     int operator()() { return _current++; }
0608 /// };
0609 /// rgb8_pixel_t p;
0610 /// int start=0;
0611 /// static_generate(p, consecutive_fn(start));
0612 /// assert(p == rgb8_pixel_t(0,1,2));
0613 /// \endcode
0614 ///
0615 /// \{
0616 
0617 template <typename P1,typename Op>
0618 BOOST_FORCEINLINE
0619 void static_generate(P1& dst,Op op)                      { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
0620 /// \}
0621 
0622 /// \defgroup ColorBaseAlgorithmTransform static_transform
0623 /// \ingroup ColorBaseAlgorithm
0624 /// \brief Equivalent to std::transform. Pairs the elements semantically
0625 ///
0626 /// Example: Write a generic function that adds two pixels into a homogeneous result pixel.
0627 /// \code
0628 /// template <typename Result>
0629 /// struct my_plus {
0630 ///     template <typename T1, typename T2>
0631 ///     Result operator()(T1 f1, T2 f2) const { return f1+f2; }
0632 /// };
0633 ///
0634 /// template <typename Pixel1, typename Pixel2, typename Pixel3>
0635 /// void sum_channels(const Pixel1& p1, const Pixel2& p2, Pixel3& result) {
0636 ///     using result_channel_t = typename channel_type<Pixel3>::type;
0637 ///     static_transform(p1,p2,result,my_plus<result_channel_t>());
0638 /// }
0639 ///
0640 /// rgb8_pixel_t p1(1,2,3);
0641 /// bgr8_pixel_t p2(3,2,1);
0642 /// rgb8_pixel_t result;
0643 /// sum_channels(p1,p2,result);
0644 /// assert(result == rgb8_pixel_t(2,4,6));
0645 /// \endcode
0646 /// \{
0647 
0648 //static_transform with one source
0649 template <typename Src,typename Dst,typename Op>
0650 BOOST_FORCEINLINE
0651 Op static_transform(Src& src,Dst& dst,Op op)              { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
0652 template <typename Src,typename Dst,typename Op>
0653 BOOST_FORCEINLINE
0654 Op static_transform(const Src& src,Dst& dst,Op op)              { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
0655 //static_transform with two sources
0656 template <typename P2,typename P3,typename Dst,typename Op>
0657 BOOST_FORCEINLINE
0658 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0659 template <typename P2,typename P3,typename Dst,typename Op>
0660 BOOST_FORCEINLINE
0661 Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0662 template <typename P2,typename P3,typename Dst,typename Op>
0663 BOOST_FORCEINLINE
0664 Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0665 template <typename P2,typename P3,typename Dst,typename Op>
0666 BOOST_FORCEINLINE
0667 Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0668 /// \}
0669 
0670 /// \defgroup ColorBaseAlgorithmForEach static_for_each
0671 /// \ingroup ColorBaseAlgorithm
0672 /// \brief Equivalent to std::for_each. Pairs the elements semantically
0673 ///
0674 /// Example: Use static_for_each to increment a planar pixel iterator
0675 /// \code
0676 /// struct increment {
0677 ///     template <typename Incrementable>
0678 ///     void operator()(Incrementable& x) const { ++x; }
0679 /// };
0680 ///
0681 /// template <typename ColorBase>
0682 /// void increment_elements(ColorBase& cb) {
0683 ///     static_for_each(cb, increment());
0684 /// }
0685 ///
0686 /// uint8_t red[2], green[2], blue[2];
0687 /// rgb8c_planar_ptr_t p1(red,green,blue);
0688 /// rgb8c_planar_ptr_t p2=p1;
0689 /// increment_elements(p1);
0690 /// ++p2;
0691 /// assert(p1 == p2);
0692 /// \endcode
0693 /// \{
0694 
0695 //static_for_each with one source
0696 template <typename P1,typename Op>
0697 BOOST_FORCEINLINE
0698 Op static_for_each(      P1& p1, Op op)                          { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
0699 template <typename P1,typename Op>
0700 BOOST_FORCEINLINE
0701 Op static_for_each(const P1& p1, Op op)                          { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
0702 //static_for_each with two sources
0703 template <typename P1,typename P2,typename Op>
0704 BOOST_FORCEINLINE
0705 Op static_for_each(P1& p1,      P2& p2, Op op)             { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0706 template <typename P1,typename P2,typename Op>
0707 BOOST_FORCEINLINE
0708 Op static_for_each(P1& p1,const P2& p2, Op op)             { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0709 template <typename P1,typename P2,typename Op>
0710 BOOST_FORCEINLINE
0711 Op static_for_each(const P1& p1,      P2& p2, Op op)             { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0712 template <typename P1,typename P2,typename Op>
0713 BOOST_FORCEINLINE
0714 Op static_for_each(const P1& p1,const P2& p2, Op op)             { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0715 //static_for_each with three sources
0716 template <typename P1,typename P2,typename P3,typename Op>
0717 BOOST_FORCEINLINE
0718 Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0719 template <typename P1,typename P2,typename P3,typename Op>
0720 BOOST_FORCEINLINE
0721 Op static_for_each(P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0722 template <typename P1,typename P2,typename P3,typename Op>
0723 BOOST_FORCEINLINE
0724 Op static_for_each(P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0725 template <typename P1,typename P2,typename P3,typename Op>
0726 BOOST_FORCEINLINE
0727 Op static_for_each(P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0728 template <typename P1,typename P2,typename P3,typename Op>
0729 BOOST_FORCEINLINE
0730 Op static_for_each(const P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0731 template <typename P1,typename P2,typename P3,typename Op>
0732 BOOST_FORCEINLINE
0733 Op static_for_each(const P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0734 template <typename P1,typename P2,typename P3,typename Op>
0735 BOOST_FORCEINLINE
0736 Op static_for_each(const P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0737 template <typename P1,typename P2,typename P3,typename Op>
0738 BOOST_FORCEINLINE
0739 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0740 ///\}
0741 
0742 }}  // namespace boost::gil
0743 
0744 #endif