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

# vigra/rgbvalue.hxx

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