[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/rgbvalue.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*                                                                      */
00005 /*    This file is part of the VIGRA computer vision library.           */
00006 /*    The VIGRA Website is                                              */
00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
00008 /*    Please direct questions, bug reports, and contributions to        */
00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00010 /*        vigra@informatik.uni-hamburg.de                               */
00011 /*                                                                      */
00012 /*    Permission is hereby granted, free of charge, to any person       */
00013 /*    obtaining a copy of this software and associated documentation    */
00014 /*    files (the "Software"), to deal in the Software without           */
00015 /*    restriction, including without limitation the rights to use,      */
00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00017 /*    sell copies of the Software, and to permit persons to whom the    */
00018 /*    Software is furnished to do so, subject to the following          */
00019 /*    conditions:                                                       */
00020 /*                                                                      */
00021 /*    The above copyright notice and this permission notice shall be    */
00022 /*    included in all copies or substantial portions of the             */
00023 /*    Software.                                                         */
00024 /*                                                                      */
00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
00033 /*                                                                      */
00034 /************************************************************************/
00035 
00036 
00037 #ifndef VIGRA_RGBVALUE_HXX
00038 #define VIGRA_RGBVALUE_HXX
00039 
00040 #include <cmath>    // abs(double)
00041 #include <cstdlib>  // abs(int)
00042 #include "config.hxx"
00043 #include "numerictraits.hxx"
00044 #include "accessor.hxx"
00045 #include "tinyvector.hxx"
00046 #include "static_assert.hxx"
00047 
00048 namespace vigra {
00049 
00050 namespace detail {
00051 
00052 template <unsigned int I, unsigned int R, unsigned int G, unsigned int B>
00053 struct SelectColorIndexRHS;
00054 
00055 template <unsigned int R, unsigned int G, unsigned int B>
00056 struct SelectColorIndexRHS<0, R, G, B>
00057 {
00058     enum { res = R };
00059 };
00060 
00061 template <unsigned int R, unsigned int G, unsigned int B>
00062 struct SelectColorIndexRHS<1, R, G, B>
00063 {
00064     enum { res = G };
00065 };
00066 
00067 template <unsigned int R, unsigned int G, unsigned int B>
00068 struct SelectColorIndexRHS<2, R, G, B>
00069 {
00070     enum { res = B };
00071 };
00072 
00073 } // namespace detail
00074 
00075 #ifndef DOXYGEN
00076 
00077 template <unsigned int R, unsigned int G, unsigned int B>
00078 struct RGBValue_bad_color_indices
00079 : staticAssert::AssertBool<(R < 3 && G < 3 && B < 3 &&
00080                            ((1 << R) + (1 << G) + (1 << B) == 7))>
00081 {};
00082 
00083 #endif /* DOXYGEN */
00084 
00085 
00086 /********************************************************/
00087 /*                                                      */
00088 /*                      RGBValue                        */
00089 /*                                                      */
00090 /********************************************************/
00091 
00092 /** \brief Class for a single RGB value.
00093 
00094     This class contains three values (of the specified type) that represent
00095     red, green, and blue color channels. By means of the template parameters
00096     <tt>RED_IDX, GREEN_IDX, BLUE_IDX</tt>, the indices 0, 1, 2 can be assigned to
00097     the three colors arbitrarily, so that, for example, a BGR type can be created
00098     as
00099 
00100     \code
00101     typedef RGBValue<unsigned char, 2,1,0> BGRValue;
00102     \endcode
00103 
00104     The standard order red=0, green=1, blue=2 is the default. There are three possibilities
00105     to access the color values: accessor functions (\ref red(), \ref green(),
00106     \ref blue()), index operator (operator[](dx), where the <tt>rgb[RED_IDX]</tt>
00107     returns red etc.) and iterator (STL-compatible random access
00108     iterator that references the three colors in turn). The latter two
00109     methods, together with the necessary embedded typedefs, ensure
00110     compatibility of a RGBValue with a STL vector.
00111 
00112     \ref RGBValueOperators "Arithmetic operations" are defined as component-wise applications of these
00113     operations. Addition, subtraction, and multiplication of two RGBValues
00114     (+=, -=, *=, +, -, *, unary -), multiplication and division of an
00115     RGBValue with a double, and NumericTraits/PromoteTraits are defined,
00116     so that RGBValue fulfills the requirements of a \ref LinearAlgebraConcept "Linear Algebra".
00117 
00118     A number of \ref RGBValueAccessors "accessors" are provided
00119     that support access to RGBValues as a whole, to a selected
00120     color component, or to the luminance value.
00121 
00122     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00123     Namespace: vigra
00124 */
00125 template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX = 1, unsigned int BLUE_IDX = 2>
00126 class RGBValue
00127 : public TinyVector<VALUETYPE, 3>
00128 {
00129     typedef TinyVector<VALUETYPE, 3> Base;
00130 
00131         // inverse mapping from index to color
00132     enum {
00133       IDX0 = (RED_IDX == 0) ? 0 : (GREEN_IDX == 0) ? 1 : 2,
00134       IDX1 = (RED_IDX == 1) ? 0 : (GREEN_IDX == 1) ? 1 : 2,
00135       IDX2 = (RED_IDX == 2) ? 0 : (GREEN_IDX == 2) ? 1 : 2
00136     };
00137 
00138   public:
00139         /** STL-compatible definition of valuetype
00140         */
00141     typedef typename Base::value_type value_type;
00142         /** STL-compatible definition of iterator
00143         */
00144     typedef typename Base::iterator iterator;
00145         /** STL-compatible definition of const iterator
00146         */
00147     typedef typename Base::const_iterator const_iterator;
00148         /** squared norm type (result of squaredManitude())
00149         */
00150     typedef typename Base::SquaredNormType SquaredNormType;
00151         /** norm type (result of magnitude())
00152         */
00153     typedef typename Base::NormType NormType;
00154 
00155     typedef typename Base::reference reference;
00156     typedef typename Base::const_reference const_reference;
00157     typedef typename Base::pointer pointer;
00158     typedef typename Base::const_pointer const_pointer;
00159     typedef typename Base::size_type size_type;
00160     typedef typename Base::difference_type difference_type;
00161     typedef typename Base::scalar_multiplier scalar_multiplier;
00162     typedef typename Base::ReverseCopyTag ReverseCopyTag;
00163 
00164         /** Color index positions
00165         */
00166     enum
00167     {
00168       RedIdx = RED_IDX,
00169       GreenIdx = GREEN_IDX,
00170       BlueIdx = BLUE_IDX
00171     };
00172 
00173         /** Construct from explicit color values.
00174             \a first, \a second, \a third are written in this order,
00175             irrespective of how the color indices are specified.
00176         */
00177     RGBValue(value_type first, value_type second, value_type third)
00178     : Base(first, second, third)
00179     {
00180         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00181     }
00182 
00183         /** Construct gray value.
00184         */
00185     RGBValue(value_type gray)
00186     : Base(gray, gray, gray)
00187     {
00188         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00189     }
00190 
00191         /** Copy from raw memory. The order is preserved,
00192             irrespective of how the color indices are specified.
00193         */
00194     explicit RGBValue(const_pointer i)
00195     : Base(i)
00196     {
00197         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00198     }
00199 
00200         /** Construct by reverse copying from raw memory.
00201         */
00202     RGBValue(const_pointer i, ReverseCopyTag reverse)
00203     : Base(i, reverse)
00204     {
00205         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00206     }
00207 
00208         /** Default constructor (sets all components to 0)
00209         */
00210     RGBValue()
00211     : Base(0, 0, 0)
00212     {
00213         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00214     }
00215 
00216 #if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG)
00217 
00218     RGBValue(RGBValue const & r)
00219     : Base((Base const &)r)
00220     {
00221         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00222     }
00223 
00224     RGBValue & operator=(RGBValue const & r)
00225     {
00226         Base::operator=(r);
00227         return *this;
00228     }
00229 
00230 #endif // TEMPLATE_COPY_CONSTRUCTOR_BUG
00231 
00232         /** Copy constructor.
00233         */
00234     template <class U, unsigned int R, unsigned int G, unsigned int B>
00235     RGBValue(RGBValue<U, R, G, B> const & r)
00236     : Base(detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX0, R, G, B>::res]),
00237            detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX1, R, G, B>::res]),
00238            detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX2, R, G, B>::res]))
00239     {
00240         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00241     }
00242 
00243         /** Copy assignment.
00244         */
00245     template <class U, unsigned int R, unsigned int G, unsigned int B>
00246     RGBValue & operator=(RGBValue<U, R, G, B> const & r)
00247     {
00248         setRed(detail::RequiresExplicitCast<value_type>::cast(r.red()));
00249         setGreen(detail::RequiresExplicitCast<value_type>::cast(r.green()));
00250         setBlue(detail::RequiresExplicitCast<value_type>::cast(r.blue()));
00251         return *this;
00252     }
00253 
00254         /** construct from TinyVector
00255         */
00256     RGBValue(TinyVector<value_type, 3> const & r)
00257     : Base(r)
00258     {
00259         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00260     }
00261 
00262         /** assign TinyVector.
00263         */
00264     RGBValue & operator=(TinyVector<value_type, 3> const & r)
00265     {
00266         Base::operator=(r);
00267         return *this;
00268     }
00269 
00270         /** Unary negation (construct RGBValue with negative values)
00271         */
00272     RGBValue operator-() const
00273     {
00274         return RGBValue(-(*this)[0], -(*this)[1], -(*this)[2]);
00275     }
00276 
00277         /** Access red component.
00278         */
00279     value_type & red() { return (*this)[RED_IDX]; }
00280 
00281         /** Access green component.
00282         */
00283     value_type & green() { return (*this)[GREEN_IDX]; }
00284 
00285         /** Access blue component.
00286         */
00287     value_type & blue() { return (*this)[BLUE_IDX]; }
00288 
00289         /** Get red component.
00290         */
00291     value_type const & red() const { return (*this)[RED_IDX]; }
00292 
00293         /** Get green component.
00294         */
00295     value_type const & green() const { return (*this)[GREEN_IDX]; }
00296 
00297         /** Get blue component.
00298         */
00299     value_type const & blue() const { return (*this)[BLUE_IDX]; }
00300 
00301         /** Calculate luminance.
00302         */
00303     value_type luminance() const {
00304          return detail::RequiresExplicitCast<value_type>::cast(0.3*red() + 0.59*green() + 0.11*blue()); }
00305 
00306         /** Calculate magnitude.
00307         */
00308     NormType magnitude() const {
00309          return Base::magnitude();
00310     }
00311 
00312         /** Calculate squared magnitude.
00313         */
00314     SquaredNormType squaredMagnitude() const {
00315          return Base::squaredMagnitude();
00316     }
00317 
00318         /** Set red component. The type <TT>V</TT> of the passed
00319             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00320         */
00321     template <class V>
00322     void setRed(V value) { (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
00323 
00324         /** Set green component.The type <TT>V</TT> of the passed
00325             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00326         */
00327     template <class V>
00328     void setGreen(V value) { (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
00329 
00330         /** Set blue component.The type <TT>V</TT> of the passed
00331             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00332         */
00333     template <class V>
00334     void setBlue(V value) { (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
00335 
00336 
00337     template <class V>
00338     void setRGB(V r, V g, V b)
00339     {
00340         (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(r);
00341         (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(g);
00342         (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(b);
00343     }
00344 };
00345 
00346 /********************************************************/
00347 /*                                                      */
00348 /*                     RGBValue Comparison              */
00349 /*                                                      */
00350 /********************************************************/
00351 
00352 /** \addtogroup RGBValueOperators Functions for RGBValue
00353 
00354     \brief Implement basic arithmetic and equality for RGBValue.
00355 
00356     These functions fulfill the requirements of a Linear Algebra.
00357     Return types are determined according to \ref RGBValueTraits.
00358 
00359     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00360     Namespace: vigra
00361     <p>
00362 
00363  */
00364 //@{
00365     /// component-wise equal
00366 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00367           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00368 inline
00369 bool
00370 operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
00371            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00372 {
00373     return (l.red() == r.red()) &&
00374            (l.green() == r.green()) &&
00375            (l.blue() == r.blue());
00376 }
00377 
00378     /// component-wise not equal
00379 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00380           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00381 inline
00382 bool
00383 operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
00384            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00385 {
00386     return (l.red() != r.red()) ||
00387            (l.green() != r.green()) ||
00388            (l.blue() != r.blue());
00389 }
00390 
00391 
00392 //@}
00393 
00394 /********************************************************/
00395 /*                                                      */
00396 /*                      RGBValue-Traits                 */
00397 /*                                                      */
00398 /********************************************************/
00399 
00400 /** \page RGBValueTraits Numeric and Promote Traits of RGBValue
00401     The numeric and promote traits for RGBValues follow
00402     the general specifications for \ref NumericPromotionTraits.
00403     They are implemented in terms of the traits of the basic types by
00404     partial template specialization. Note that PromoteTraits are only defined
00405     for the case that the color indices are the same in both RGBValues.
00406 
00407     \code
00408 
00409     template <class T, unsigned int R, unsigned int G, unsigned int B>
00410     struct NumericTraits<RGBValue<T, R, G, B> >
00411     {
00412         typedef RGBValue<T, R, G, B> Type;
00413         typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
00414         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
00415         typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
00416         typedef T ValueType;
00417 
00418         typedef typename NumericTraits<T>::isIntegral isIntegral;
00419         typedef VigraFalseType isScalar;
00420         typedef typename NumericTraits<T>::isSigned isSigned;
00421 
00422         // etc.
00423     };
00424 
00425     template <class T, unsigned int R, unsigned int G, unsigned int B>
00426     struct NormTraits<RGBValue<T, R, G, B> >
00427     {
00428         typedef RGBValue<T, R, G, B> Type;
00429         typedef typename Type::SquaredNormType    SquaredNormType;
00430         typedef typename Type::NormType           NormType;
00431     };
00432 
00433     template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
00434     struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
00435     {
00436         typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
00437     };
00438 
00439     template <class T, unsigned int R, unsigned int G, unsigned int B>
00440     struct PromoteTraits<RGBValue<T, R, G, B>, double >
00441     {
00442         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
00443     };
00444 
00445     template <class T, unsigned int R, unsigned int G, unsigned int B>
00446     struct PromoteTraits<double, RGBValue<T, R, G, B> >
00447     {
00448         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
00449     };
00450     \endcode
00451 
00452     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00453     Namespace: vigra
00454 
00455 */
00456 
00457 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
00458 
00459 template <class T, unsigned int R, unsigned int G, unsigned int B>
00460 struct NumericTraits<RGBValue<T, R, G, B> >
00461 {
00462     typedef RGBValue<T, R, G, B> Type;
00463     typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
00464     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
00465     typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
00466     typedef T ValueType;
00467 
00468     typedef typename NumericTraits<T>::isIntegral isIntegral;
00469     typedef VigraFalseType isScalar;
00470     typedef typename NumericTraits<T>::isSigned isSigned;
00471     typedef VigraTrueType isOrdered;
00472     typedef VigraFalseType isComplex;
00473 
00474     static Type zero()
00475     {
00476         return Type(NumericTraits<T>::zero());
00477     }
00478     static Type one()
00479     {
00480         return Type(NumericTraits<T>::one());
00481     }
00482     static Type nonZero()
00483     {
00484         return Type(NumericTraits<T>::nonZero());
00485     }
00486 
00487     static Type min()
00488     {
00489         return Type(NumericTraits<T>::min());
00490     }
00491     static Type max()
00492     {
00493         return Type(NumericTraits<T>::max());
00494     }
00495 
00496     static Promote toPromote(Type const & v)
00497     {
00498         return Promote(v);
00499     }
00500     static RealPromote toRealPromote(Type const & v)
00501     {
00502         return RealPromote(v);
00503     }
00504     static Type fromPromote(Promote const & v)
00505     {
00506       return Type(NumericTraits<T>::fromPromote(v.red()),
00507                   NumericTraits<T>::fromPromote(v.green()),
00508                   NumericTraits<T>::fromPromote(v.blue()));
00509     }
00510     static Type fromRealPromote(RealPromote const & v)
00511     {
00512         return Type(NumericTraits<T>::fromRealPromote(v.red()),
00513                     NumericTraits<T>::fromRealPromote(v.green()),
00514                     NumericTraits<T>::fromRealPromote(v.blue()));
00515     }
00516 };
00517 
00518 template <class T, unsigned int R, unsigned int G, unsigned int B>
00519 struct NormTraits<RGBValue<T, R, G, B> >
00520 {
00521     typedef RGBValue<T, R, G, B> Type;
00522     typedef typename Type::SquaredNormType    SquaredNormType;
00523     typedef typename Type::NormType           NormType;
00524 };
00525 
00526 template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
00527 struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
00528 {
00529     typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
00530 };
00531 
00532 template <class T, unsigned int R, unsigned int G, unsigned int B>
00533 struct PromoteTraits<RGBValue<T, R, G, B>, double >
00534 {
00535     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
00536 };
00537 
00538 template <class T, unsigned int R, unsigned int G, unsigned int B>
00539 struct PromoteTraits<double, RGBValue<T, R, G, B> >
00540 {
00541     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
00542 };
00543 
00544 template<class T, unsigned int R, unsigned int G, unsigned int B>
00545 struct CanSkipInitialization<RGBValue<T, R, G, B> >
00546 {
00547     typedef typename CanSkipInitialization<T>::type type;
00548     static const bool value = type::asBool;
00549 };
00550 
00551 
00552 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00553 
00554 #define RGBVALUE_NUMTRAITS(T) \
00555 template<>\
00556 struct NumericTraits<RGBValue<T, 0, 1, 2> >\
00557 {\
00558     typedef RGBValue<T> Type; \
00559     typedef RGBValue<NumericTraits<T>::Promote> Promote; \
00560     typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \
00561     typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \
00562     typedef T ValueType; \
00563     \
00564     typedef NumericTraits<T>::isIntegral isIntegral; \
00565     typedef VigraFalseType isScalar; \
00566     typedef NumericTraits<T>::isSigned isSigned; \
00567     typedef VigraFalseType isOrdered; \
00568     typedef VigraFalseType isComplex; \
00569     \
00570     static RGBValue<T> zero() { \
00571         return RGBValue<T>(NumericTraits<T>::zero()); \
00572     }\
00573     static RGBValue<T> one() { \
00574         return RGBValue<T>(NumericTraits<T>::one()); \
00575     }\
00576     static RGBValue<T> nonZero() { \
00577         return RGBValue<T>(NumericTraits<T>::nonZero()); \
00578     }\
00579     \
00580     static Promote toPromote(RGBValue<T> const & v) { \
00581         return Promote(v); \
00582     }\
00583     static RealPromote toRealPromote(RGBValue<T> const & v) { \
00584         return RealPromote(v); \
00585     }\
00586     static RGBValue<T> fromPromote(Promote const & v) { \
00587         RGBValue<T> res;\
00588         RGBValue<T>::iterator d = res.begin();\
00589         Promote::const_iterator s = v.begin();\
00590         for(; d != res.end(); ++d, ++s)\
00591             *d = NumericTraits<T>::fromPromote(*s);\
00592         return res;\
00593     }\
00594     static RGBValue<T> fromRealPromote(RealPromote const & v) {\
00595         RGBValue<T> res;\
00596         RGBValue<T>::iterator d = res.begin();\
00597         RealPromote::const_iterator s = v.begin();\
00598         for(; d != res.end(); ++d, ++s)\
00599             *d = NumericTraits<T>::fromRealPromote(*s);\
00600         return res;\
00601     }\
00602 }; \
00603 template<>\
00604 struct NormTraits<RGBValue<T, 0, 1, 2> >\
00605 {\
00606     typedef RGBValue<T> Type;\
00607     typedef Type::SquaredNormType           SquaredNormType; \
00608     typedef Type::NormType NormType; \
00609 };
00610 
00611 #define RGBVALUE_PROMTRAITS1(type1) \
00612 template<> \
00613 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \
00614 { \
00615     typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \
00616     static Promote toPromote(RGBValue<type1> const & v) { \
00617         return static_cast<Promote>(v); } \
00618 }; \
00619 template <> \
00620 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \
00621 { \
00622     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
00623 }; \
00624 template <> \
00625 struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \
00626 { \
00627     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
00628 };
00629 
00630 #define RGBVALUE_PROMTRAITS2(type1, type2) \
00631 template<> \
00632 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \
00633 { \
00634     typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \
00635     static Promote toPromote(RGBValue<type1> const & v) { \
00636         return static_cast<Promote>(v); } \
00637     static Promote toPromote(RGBValue<type2> const & v) { \
00638         return static_cast<Promote>(v); } \
00639 };
00640 
00641 RGBVALUE_NUMTRAITS(unsigned char)
00642 RGBVALUE_NUMTRAITS(int)
00643 RGBVALUE_NUMTRAITS(float)
00644 RGBVALUE_NUMTRAITS(double)
00645 RGBVALUE_PROMTRAITS1(unsigned char)
00646 RGBVALUE_PROMTRAITS1(int)
00647 RGBVALUE_PROMTRAITS1(float)
00648 RGBVALUE_PROMTRAITS1(double)
00649 RGBVALUE_PROMTRAITS2(float, unsigned char)
00650 RGBVALUE_PROMTRAITS2(unsigned char, float)
00651 RGBVALUE_PROMTRAITS2(int, unsigned char)
00652 RGBVALUE_PROMTRAITS2(unsigned char, int)
00653 RGBVALUE_PROMTRAITS2(int, float)
00654 RGBVALUE_PROMTRAITS2(float, int)
00655 RGBVALUE_PROMTRAITS2(double, unsigned char)
00656 RGBVALUE_PROMTRAITS2(unsigned char, double)
00657 RGBVALUE_PROMTRAITS2(int, double)
00658 RGBVALUE_PROMTRAITS2(double, int)
00659 RGBVALUE_PROMTRAITS2(double, float)
00660 RGBVALUE_PROMTRAITS2(float, double)
00661 
00662 #undef RGBVALUE_NUMTRAITS
00663 #undef RGBVALUE_PROMTRAITS1
00664 #undef RGBVALUE_PROMTRAITS2
00665 
00666 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00667 
00668 
00669 /********************************************************/
00670 /*                                                      */
00671 /*                      RGBValue-Arithmetic             */
00672 /*                                                      */
00673 /********************************************************/
00674 
00675 /** \addtogroup RGBValueOperators
00676  */
00677 //@{
00678     /// componentwise add-assignment
00679 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00680           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00681 inline
00682 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
00683 operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
00684            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00685 {
00686     l.red() += r.red();
00687     l.green() += r.green();
00688     l.blue() += r.blue();
00689     return l;
00690 }
00691 
00692     /// componentwise subtract-assignment
00693 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00694           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00695 inline
00696 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
00697 operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
00698            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00699 {
00700     l.red() -= r.red();
00701     l.green() -= r.green();
00702     l.blue() -= r.blue();
00703     return l;
00704 }
00705 
00706     /// componentwise multiply-assignment
00707 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00708           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00709 inline
00710 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
00711 operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
00712            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00713 {
00714     l.red() = V1(l.red() * r.red());
00715     l.green() = V1(l.green() * r.green());
00716     l.blue() = V1(l.blue() * r.blue());
00717     return l;
00718 }
00719 
00720     /// componentwise scalar multiply-assignment
00721 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00722 inline
00723 RGBValue<V, RIDX, GIDX, BIDX> &
00724 operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
00725 {
00726     l.red() = V(l.red() * r);
00727     l.green() = V(l.green() * r);
00728     l.blue() = V(l.blue() * r);
00729     return l;
00730 }
00731 
00732     /// componentwise divide-assignment
00733 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00734           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00735 inline
00736 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
00737 operator/=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
00738            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00739 {
00740     l.red() = V1(l.red() / r.red());
00741     l.green() = V1(l.green() / r.green());
00742     l.blue() = V1(l.blue() / r.blue());
00743     return l;
00744 }
00745 
00746     /// componentwise scalar divide-assignment
00747 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00748 inline
00749 RGBValue<V, RIDX, GIDX, BIDX> &
00750 operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
00751 {
00752     l.red() = V(l.red() / r);
00753     l.green() = V(l.green() / r);
00754     l.blue() = V(l.blue() / r);
00755     return l;
00756 }
00757 
00758 using VIGRA_CSTD::abs;
00759 
00760     /// component-wise absolute value
00761 template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00762 inline
00763 RGBValue<T, RIDX, GIDX, BIDX>
00764 abs(RGBValue<T, RIDX, GIDX, BIDX> const & v)
00765 {
00766   return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v.blue()));
00767 }
00768 
00769     /// component-wise addition
00770 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
00771 inline
00772 typename PromoteTraits<RGBValue<V1, R, G, B>,
00773                        RGBValue<V2, R, G, B> >::Promote
00774 operator+(RGBValue<V1, R, G, B> const & r1,
00775           RGBValue<V2, R, G, B> const & r2)
00776 {
00777     typename PromoteTraits<RGBValue<V1, R, G, B>,
00778                            RGBValue<V2, R, G, B> >::Promote res(r1);
00779 
00780     res += r2;
00781 
00782     return res;
00783 }
00784 
00785     /// component-wise subtraction
00786 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
00787 inline
00788 typename PromoteTraits<RGBValue<V1, R, G, B>,
00789                        RGBValue<V2, R, G, B> >::Promote
00790 operator-(RGBValue<V1, R, G, B> const & r1,
00791           RGBValue<V2, R, G, B> const & r2)
00792 {
00793     typename PromoteTraits<RGBValue<V1, R, G, B>,
00794                            RGBValue<V2, R, G, B> >::Promote res(r1);
00795 
00796     res -= r2;
00797 
00798     return res;
00799 }
00800 
00801     /// component-wise multiplication
00802 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
00803 inline
00804 typename PromoteTraits<RGBValue<V1, R, G, B>,
00805                        RGBValue<V2, R, G, B> >::Promote
00806 operator*(RGBValue<V1, R, G, B> const & r1,
00807           RGBValue<V2, R, G, B> const & r2)
00808 {
00809     typename PromoteTraits<RGBValue<V1, R, G, B>,
00810                            RGBValue<V2, R, G, B> >::Promote res(r1);
00811 
00812     res *= r2;
00813 
00814     return res;
00815 }
00816 
00817     /// component-wise left scalar multiplication
00818 template <class V, unsigned int R, unsigned int G, unsigned int B>
00819 inline
00820 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
00821 operator*(double v, RGBValue<V, R, G, B> const & r)
00822 {
00823     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
00824 
00825     res *= v;
00826 
00827     return res;
00828 }
00829 
00830     /// component-wise right scalar multiplication
00831 template <class V, unsigned int R, unsigned int G, unsigned int B>
00832 inline
00833 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
00834 operator*(RGBValue<V, R, G, B> const & r, double v)
00835 {
00836     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
00837 
00838     res *= v;
00839 
00840     return res;
00841 }
00842 
00843     /// component-wise division
00844 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
00845 inline
00846 typename PromoteTraits<RGBValue<V1, R, G, B>,
00847                        RGBValue<V2, R, G, B> >::Promote
00848 operator/(RGBValue<V1, R, G, B> const & r1,
00849           RGBValue<V2, R, G, B> const & r2)
00850 {
00851     typename PromoteTraits<RGBValue<V1, R, G, B>,
00852                            RGBValue<V2, R, G, B> >::Promote res(r1);
00853 
00854     res /= r2;
00855 
00856     return res;
00857 }
00858 
00859     /// component-wise scalar division
00860 template <class V, unsigned int R, unsigned int G, unsigned int B>
00861 inline
00862 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
00863 operator/(RGBValue<V, R, G, B> const & r, double v)
00864 {
00865     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
00866 
00867     res /= v;
00868 
00869     return res;
00870 }
00871 
00872     /// cross product
00873 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
00874 inline
00875 typename PromoteTraits<RGBValue<V1, R, G, B>,
00876                        RGBValue<V2, R, G, B> >::Promote
00877 cross(RGBValue<V1, R, G, B> const & r1,
00878       RGBValue<V2, R, G, B> const & r2)
00879 {
00880     typedef typename PromoteTraits<RGBValue<V1, R, G, B>,
00881                                    RGBValue<V2, R, G, B> >::Promote
00882             Res;
00883 
00884     return  Res(r1.green()*r2.blue() - r1.blue()*r2.green(),
00885                 r1.blue()*r2.red() - r1.red()*r2.blue(),
00886                 r1.red()*r2.green() - r1.green()*r2.red());
00887 }
00888 
00889     /// dot product
00890 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00891           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00892 inline
00893 typename PromoteTraits<V1, V2>::Promote
00894 dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1,
00895     RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2)
00896 {
00897     return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue();
00898 }
00899 
00900 using VIGRA_CSTD::ceil;
00901 
00902     /** Apply ceil() function to each RGB component.
00903     */
00904 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00905 inline
00906 RGBValue<V, RIDX, GIDX, BIDX>
00907 ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r)
00908 {
00909     return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()),
00910                                          ceil(r.green()),
00911                                          ceil(r.blue()));
00912 }
00913 
00914 using VIGRA_CSTD::floor;
00915 
00916     /** Apply floor() function to each RGB component.
00917     */
00918 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00919 inline
00920 RGBValue<V, RIDX, GIDX, BIDX>
00921 floor(RGBValue<V, RIDX, GIDX, BIDX> const & r)
00922 {
00923     return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()),
00924                                          floor(r.green()),
00925                                          floor(r.blue()));
00926 }
00927 
00928 // overload min and max to avoid that std:min() and std::max() match
00929 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00930 inline
00931 RGBValue<V, RIDX, GIDX, BIDX>
00932 min(RGBValue<V, RIDX, GIDX, BIDX> const & l,
00933     RGBValue<V, RIDX, GIDX, BIDX> const & r)
00934 {
00935     typedef typename detail::LoopType<3>::type ltype;
00936     RGBValue<V, RIDX, GIDX, BIDX> res(l);
00937     ltype::min(res.begin(), r.begin());
00938     return res;
00939 }
00940 
00941 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
00942 inline
00943 RGBValue<V, RIDX, GIDX, BIDX>
00944 max(RGBValue<V, RIDX, GIDX, BIDX> const & l,
00945     RGBValue<V, RIDX, GIDX, BIDX> const & r)
00946 {
00947     typedef typename detail::LoopType<3>::type ltype;
00948     RGBValue<V, RIDX, GIDX, BIDX> res(l);
00949     ltype::max(res.begin(), r.begin());
00950     return res;
00951 }
00952 
00953 
00954 //@}
00955 
00956 /********************************************************/
00957 /*                                                      */
00958 /*                      RGBValue-Accessors              */
00959 /*                                                      */
00960 /********************************************************/
00961 
00962 /** \addtogroup DataAccessors
00963 */
00964 //@{
00965 /** \defgroup RGBValueAccessors Accessors for RGBValue */
00966 //@{
00967     /** Encapsulate access to rgb values.
00968 
00969     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00970     Namespace: vigra
00971     */
00972 template <class RGBVALUE>
00973 class RGBAccessor
00974 : public VectorAccessor<RGBVALUE>
00975 {
00976   public:
00977 
00978     typedef typename RGBVALUE::value_type component_type;
00979 
00980         /** Get value of the red component
00981         */
00982     template <class RGBIterator>
00983     component_type const & red(RGBIterator const & rgb) const
00984     {
00985         return (*rgb).red();
00986     }
00987 
00988     template <class V, class RGBIterator>
00989     void setRGB(V r, V g, V b, RGBIterator const & rgb) const
00990     {
00991         (*rgb).setRGB( r, g, b );
00992     }
00993 
00994 
00995         /** Set value of the red component. The type <TT>V</TT> of the passed
00996             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
00997         */
00998     template <class V, class RGBIterator>
00999     void setRed(V value, RGBIterator const & rgb) const
01000     {
01001         (*rgb).setRed(value);
01002     }
01003 
01004         /** Get value of the red component at an offset
01005         */
01006     template <class RGBIterator, class DIFFERENCE>
01007     component_type const & red(RGBIterator const & rgb, DIFFERENCE diff) const
01008     {
01009         return rgb[diff].red();
01010     }
01011 
01012         /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
01013             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
01014         */
01015     template <class V, class RGBIterator, class DIFFERENCE>
01016     void setRed(V value, RGBIterator const & rgb, DIFFERENCE diff) const
01017     {
01018         rgb[diff].setRed(value);
01019     }
01020 
01021         /** Get value of the green component
01022         */
01023     template <class RGBIterator>
01024     component_type const & green(RGBIterator const & rgb) const
01025     {
01026         return (*rgb).green();
01027     }
01028 
01029         /** Set value of the green component. The type <TT>V</TT> of the passed
01030             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
01031         */
01032     template <class V, class RGBIterator>
01033     void setGreen(V value, RGBIterator const & rgb) const
01034     {
01035         (*rgb).setGreen(value);
01036     }
01037 
01038         /** Get value of the green component at an offset
01039         */
01040     template <class RGBIterator, class DIFFERENCE>
01041     component_type const & green(RGBIterator const & rgb, DIFFERENCE d) const
01042     {
01043         return rgb[d].green();
01044     }
01045 
01046         /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
01047             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
01048         */
01049     template <class V, class RGBIterator, class DIFFERENCE>
01050     void setGreen(V value, RGBIterator const & rgb, DIFFERENCE d) const
01051     {
01052         rgb[d].setGreen(value);
01053     }
01054 
01055         /** Get value of the blue component
01056         */
01057     template <class RGBIterator>
01058     component_type const & blue(RGBIterator const & rgb) const
01059     {
01060         return (*rgb).blue();
01061     }
01062 
01063         /** Set value of the blue component. The type <TT>V</TT> of the passed
01064             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
01065         */
01066     template <class V, class RGBIterator>
01067     void setBlue(V value, RGBIterator const & rgb) const
01068     {
01069         (*rgb).setBlue(value);
01070     }
01071 
01072         /** Get value of the blue component at an offset
01073         */
01074     template <class RGBIterator, class DIFFERENCE>
01075     component_type const & blue(RGBIterator const & rgb, DIFFERENCE d) const
01076     {
01077         return rgb[d].blue();
01078     }
01079 
01080         /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
01081             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
01082         */
01083     template <class V, class RGBIterator, class DIFFERENCE>
01084     void setBlue(V value, RGBIterator const & rgb, DIFFERENCE d) const
01085     {
01086         rgb[d].setBlue(value);
01087     }
01088 
01089 };
01090 
01091 
01092 /********************************************************/
01093 /*                                                      */
01094 /*                       RedAccessor                    */
01095 /*                                                      */
01096 /********************************************************/
01097 
01098     /** Encapsulate access to red band of an rgb value.
01099 
01100     <b>\#include</b> <vigra/rgbvalue.hxx><br>
01101     Namespace: vigra
01102     */
01103 template <class RGBVALUE>
01104 class RedAccessor
01105 {
01106   public:
01107     typedef typename RGBVALUE::value_type value_type;
01108 
01109         /** Get value of the red component
01110         */
01111     template <class ITERATOR>
01112     value_type const & operator()(ITERATOR const & i) const {
01113         return (*i).red();
01114     }
01115 
01116         /** Get value of the red component at an offset
01117         */
01118     template <class ITERATOR, class DIFFERENCE>
01119     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
01120     {
01121         return i[d].red();
01122     }
01123 
01124         /** Set value of the red component. The type <TT>V</TT> of the passed
01125             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
01126         */
01127     template <class V, class ITERATOR>
01128     void set(V value, ITERATOR const & i) const {
01129         (*i).setRed(value);
01130     }
01131 
01132 
01133         /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
01134             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
01135         */
01136     template <class V, class ITERATOR, class DIFFERENCE>
01137     void set(V value, ITERATOR const & i, DIFFERENCE d) const
01138     {
01139         i[d].setRed(value);
01140     }
01141 };
01142 
01143 /********************************************************/
01144 /*                                                      */
01145 /*                     GreenAccessor                    */
01146 /*                                                      */
01147 /********************************************************/
01148 
01149     /** Encapsulate access to green band of an rgb value.
01150 
01151     <b>\#include</b> <vigra/rgbvalue.hxx><br>
01152     Namespace: vigra
01153     */
01154 template <class RGBVALUE>
01155 class GreenAccessor
01156 {
01157   public:
01158     typedef typename RGBVALUE::value_type value_type;
01159 
01160         /** Get value of the green component
01161         */
01162     template <class ITERATOR>
01163     value_type const & operator()(ITERATOR const & i) const {
01164         return (*i).green();
01165     }
01166 
01167         /** Get value of the green component at an offset
01168         */
01169     template <class ITERATOR, class DIFFERENCE>
01170     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
01171     {
01172         return i[d].green();
01173     }
01174 
01175         /** Set value of the green component. The type <TT>V</TT> of the passed
01176             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
01177         */
01178     template <class V, class ITERATOR>
01179     void set(V value, ITERATOR const & i) const {
01180         (*i).setGreen(value);
01181     }
01182 
01183 
01184         /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
01185             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
01186         */
01187     template <class V, class ITERATOR, class DIFFERENCE>
01188     void set(V value, ITERATOR const & i, DIFFERENCE d) const
01189     {
01190         i[d].setGreen(value);
01191     }
01192 };
01193 
01194 /********************************************************/
01195 /*                                                      */
01196 /*                     BlueAccessor                     */
01197 /*                                                      */
01198 /********************************************************/
01199 
01200     /** Encapsulate access to blue band of an rgb value.
01201 
01202     <b>\#include</b> <vigra/rgbvalue.hxx><br>
01203     Namespace: vigra
01204     */
01205 template <class RGBVALUE>
01206 class BlueAccessor
01207 {
01208   public:
01209     typedef typename RGBVALUE::value_type value_type;
01210 
01211         /** Get value of the blue component
01212         */
01213     template <class ITERATOR>
01214     value_type const & operator()(ITERATOR const & i) const {
01215         return (*i).blue();
01216     }
01217 
01218         /** Get value of the blue component at an offset
01219         */
01220     template <class ITERATOR, class DIFFERENCE>
01221     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
01222     {
01223         return i[d].blue();
01224     }
01225 
01226         /** Set value of the blue component. The type <TT>V</TT> of the passed
01227             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
01228         */
01229     template <class V, class ITERATOR>
01230     void set(V value, ITERATOR const & i) const {
01231         (*i).setBlue(value);
01232     }
01233 
01234 
01235         /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
01236             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
01237         */
01238     template <class V, class ITERATOR, class DIFFERENCE>
01239     void set(V value, ITERATOR const & i, DIFFERENCE d) const
01240     {
01241         i[d].setBlue(value);
01242     }
01243 };
01244 
01245 /********************************************************/
01246 /*                                                      */
01247 /*                  RGBToGrayAccessor                   */
01248 /*                                                      */
01249 /********************************************************/
01250 
01251     /** Encapsulate access to luminance of an rgb value.
01252 
01253     <b>\#include</b> <vigra/rgbvalue.hxx><br>
01254     Namespace: vigra
01255     */
01256 template <class RGBVALUE>
01257 class RGBToGrayAccessor
01258 {
01259   public:
01260     typedef typename RGBVALUE::value_type value_type;
01261 
01262         /** Get value of the luminance
01263         */
01264     template <class ITERATOR>
01265     value_type operator()(ITERATOR const & i) const {
01266                 return (*i).luminance(); }
01267 
01268         /** Get value of the luminance at an offset
01269         */
01270     template <class ITERATOR, class DIFFERENCE>
01271     value_type operator()(ITERATOR const & i, DIFFERENCE d) const
01272     {
01273         return i[d].luminance();
01274     }
01275 };
01276 
01277 
01278 /********************************************************/
01279 /*                                                      */
01280 /*                  GrayToRGBAccessor                   */
01281 /*                                                      */
01282 /********************************************************/
01283 
01284     /** Create an RGB view for a grayscale image by making all three channels
01285         equal.
01286 
01287     <b>\#include</b> <vigra/rgbvalue.hxx><br>
01288     Namespace: vigra
01289     */
01290 template <class VALUETYPE>
01291 class GrayToRGBAccessor
01292 {
01293    public:
01294      typedef typename vigra::RGBValue<VALUETYPE> value_type;
01295 
01296          /** Get RGB value for the given pixel.
01297          */
01298      template <class ITERATOR>
01299      value_type operator()(ITERATOR const & i) const {
01300                  return value_type(*i,*i,*i); }
01301 
01302          /** Get RGB value at an offset
01303          */
01304      template <class ITERATOR, class DIFFERENCE>
01305      value_type operator()(ITERATOR const & i, DIFFERENCE d) const
01306      {
01307          return value_type(i[d],i[d],i[d]);
01308      }
01309 };
01310 
01311 
01312 //@}
01313 //@}
01314 
01315 
01316 } // namespace vigra
01317 
01318 #endif // VIGRA_RGBVALUE_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)