[ VIGRA Homepage | Class Index | Function Index | File Index | 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.5.0, Dec 07 2006 )                                    */
    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 /*        koethe@informatik.uni-hamburg.de          or                  */
    00012 /*        vigra@kogs1.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 LinearAlgebra.
    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 <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>
    00340
    00341     These functions fulfill the requirements of a Linear Algebra.
    00342     Return types are determined according to \ref RGBValueTraits.
    00343
    00344     Namespace: vigra
    00345     <p>
    00346
    00347  */
    00348 //@{
    00349     /// component-wise equal
    00350 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00351           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00352 inline
    00353 bool
    00354 operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
    00355            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00356 {
    00357     return (l.red() == r.red()) &&
    00358            (l.green() == r.green()) &&
    00359            (l.blue() == r.blue());
    00360 }
    00361
    00362     /// component-wise not equal
    00363 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00364           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00365 inline
    00366 bool
    00367 operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
    00368            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00369 {
    00370     return (l.red() != r.red()) ||
    00371            (l.green() != r.green()) ||
    00372            (l.blue() != r.blue());
    00373 }
    00374
    00375
    00376 //@}
    00377
    00378 /********************************************************/
    00379 /*                                                      */
    00380 /*                      RGBValue-Traits                 */
    00381 /*                                                      */
    00382 /********************************************************/
    00383
    00384 /** \page RGBValueTraits Numeric and Promote Traits of RGBValue
    00385     The numeric and promote traits for RGBValues follow
    00386     the general specifications for \ref NumericPromotionTraits.
    00387     They are implemented in terms of the traits of the basic types by
    00388     partial template specialization. Note that PromoteTraits are only defined
    00389     for the case that the color indices are the same in both RGBValues.
    00390
    00391     \code
    00392
    00393     template <class T, unsigned int R, unsigned int G, unsigned int B>
    00394     struct NumericTraits<RGBValue<T, R, G, B> >
    00395     {
    00396         typedef RGBValue<T, R, G, B> Type;
    00397         typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
    00398         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
    00399         typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
    00400         typedef T ValueType;
    00401
    00402         typedef typename NumericTraits<T>::isIntegral isIntegral;
    00403         typedef VigraFalseType isScalar;
    00404         typedef typename NumericTraits<T>::isSigned isSigned;
    00405
    00406         // etc.
    00407     };
    00408
    00409     template <class T, unsigned int R, unsigned int G, unsigned int B>
    00410     struct NormTraits<RGBValue<T, R, G, B> >
    00411     {
    00412         typedef RGBValue<T, R, G, B> Type;
    00413         typedef typename Type::SquaredNormType    SquaredNormType;
    00414         typedef typename Type::NormType           NormType;
    00415     };
    00416
    00417     template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
    00418     struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
    00419     {
    00420         typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
    00421     };
    00422
    00423     template <class T, unsigned int R, unsigned int G, unsigned int B>
    00424     struct PromoteTraits<RGBValue<T, R, G, B>, double >
    00425     {
    00426         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
    00427     };
    00428
    00429     template <class T, unsigned int R, unsigned int G, unsigned int B>
    00430     struct PromoteTraits<double, RGBValue<T, R, G, B> >
    00431     {
    00432         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
    00433     };
    00434     \endcode
    00435
    00436     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    00437     Namespace: vigra
    00438
    00439 */
    00440
    00441 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
    00442
    00443 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00444 struct NumericTraits<RGBValue<T, R, G, B> >
    00445 {
    00446     typedef RGBValue<T, R, G, B> Type;
    00447     typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
    00448     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
    00449     typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
    00450     typedef T ValueType;
    00451
    00452     typedef typename NumericTraits<T>::isIntegral isIntegral;
    00453     typedef VigraFalseType isScalar;
    00454     typedef typename NumericTraits<T>::isSigned isSigned;
    00455     typedef VigraFalseType isOrdered;
    00456     typedef VigraFalseType isComplex;
    00457
    00458     static Type zero() {
    00459         return Type(NumericTraits<T>::zero());
    00460     }
    00461     static Type one() {
    00462         return Type(NumericTraits<T>::one());
    00463     }
    00464     static Type nonZero() {
    00465         return Type(NumericTraits<T>::nonZero());
    00466     }
    00467
    00468     static Promote toPromote(Type const & v) {
    00469         return Promote(v);
    00470     }
    00471     static RealPromote toRealPromote(Type const & v) {
    00472         return RealPromote(v);
    00473     }
    00474     static Type fromPromote(Promote const & v) {
    00475       return Type(NumericTraits<T>::fromPromote(v.red()),
    00476                   NumericTraits<T>::fromPromote(v.green()),
    00477                   NumericTraits<T>::fromPromote(v.blue()));
    00478     }
    00479     static Type fromRealPromote(RealPromote const & v) {
    00480         return Type(NumericTraits<T>::fromRealPromote(v.red()),
    00481                     NumericTraits<T>::fromRealPromote(v.green()),
    00482                     NumericTraits<T>::fromRealPromote(v.blue()));
    00483     }
    00484 };
    00485
    00486 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00487 struct NormTraits<RGBValue<T, R, G, B> >
    00488 {
    00489     typedef RGBValue<T, R, G, B> Type;
    00490     typedef typename Type::SquaredNormType    SquaredNormType;
    00491     typedef typename Type::NormType           NormType;
    00492 };
    00493
    00494 template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
    00495 struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
    00496 {
    00497     typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
    00498 };
    00499
    00500 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00501 struct PromoteTraits<RGBValue<T, R, G, B>, double >
    00502 {
    00503     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
    00504 };
    00505
    00506 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00507 struct PromoteTraits<double, RGBValue<T, R, G, B> >
    00508 {
    00509     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
    00510 };
    00511
    00512 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00513
    00514 #define RGBVALUE_NUMTRAITS(T) \
    00515 template<>\
    00516 struct NumericTraits<RGBValue<T, 0, 1, 2> >\
    00517 {\
    00518     typedef RGBValue<T> Type; \
    00519     typedef RGBValue<NumericTraits<T>::Promote> Promote; \
    00520     typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \
    00521     typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \
    00522     typedef T ValueType; \
    00523     \
    00524     typedef NumericTraits<T>::isIntegral isIntegral; \
    00525     typedef VigraFalseType isScalar; \
    00526     typedef NumericTraits<T>::isSigned isSigned; \
    00527     typedef VigraFalseType isOrdered; \
    00528     typedef VigraFalseType isComplex; \
    00529     \
    00530     static RGBValue<T> zero() { \
    00531         return RGBValue<T>(NumericTraits<T>::zero()); \
    00532     }\
    00533     static RGBValue<T> one() { \
    00534         return RGBValue<T>(NumericTraits<T>::one()); \
    00535     }\
    00536     static RGBValue<T> nonZero() { \
    00537         return RGBValue<T>(NumericTraits<T>::nonZero()); \
    00538     }\
    00539     \
    00540     static Promote toPromote(RGBValue<T> const & v) { \
    00541         return Promote(v); \
    00542     }\
    00543     static RealPromote toRealPromote(RGBValue<T> const & v) { \
    00544         return RealPromote(v); \
    00545     }\
    00546     static RGBValue<T> fromPromote(Promote const & v) { \
    00547         RGBValue<T> res;\
    00548         RGBValue<T>::iterator d = res.begin();\
    00549         Promote::const_iterator s = v.begin();\
    00550         for(; d != res.end(); ++d, ++s)\
    00551             *d = NumericTraits<T>::fromPromote(*s);\
    00552         return res;\
    00553     }\
    00554     static RGBValue<T> fromRealPromote(RealPromote const & v) {\
    00555         RGBValue<T> res;\
    00556         RGBValue<T>::iterator d = res.begin();\
    00557         RealPromote::const_iterator s = v.begin();\
    00558         for(; d != res.end(); ++d, ++s)\
    00559             *d = NumericTraits<T>::fromRealPromote(*s);\
    00560         return res;\
    00561     }\
    00562 }; \
    00563 template<>\
    00564 struct NormTraits<RGBValue<T, 0, 1, 2> >\
    00565 {\
    00566     typedef RGBValue<T> Type;\
    00567     typedef Type::SquaredNormType           SquaredNormType; \
    00568     typedef Type::NormType NormType; \
    00569 };
    00570
    00571 #define RGBVALUE_PROMTRAITS1(type1) \
    00572 template<> \
    00573 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \
    00574 { \
    00575     typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \
    00576     static Promote toPromote(RGBValue<type1> const & v) { \
    00577         return static_cast<Promote>(v); } \
    00578 }; \
    00579 template <> \
    00580 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \
    00581 { \
    00582     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
    00583 }; \
    00584 template <> \
    00585 struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \
    00586 { \
    00587     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
    00588 };
    00589
    00590 #define RGBVALUE_PROMTRAITS2(type1, type2) \
    00591 template<> \
    00592 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \
    00593 { \
    00594     typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \
    00595     static Promote toPromote(RGBValue<type1> const & v) { \
    00596         return static_cast<Promote>(v); } \
    00597     static Promote toPromote(RGBValue<type2> const & v) { \
    00598         return static_cast<Promote>(v); } \
    00599 };
    00600
    00601 RGBVALUE_NUMTRAITS(unsigned char)
    00602 RGBVALUE_NUMTRAITS(int)
    00603 RGBVALUE_NUMTRAITS(float)
    00604 RGBVALUE_NUMTRAITS(double)
    00605 RGBVALUE_PROMTRAITS1(unsigned char)
    00606 RGBVALUE_PROMTRAITS1(int)
    00607 RGBVALUE_PROMTRAITS1(float)
    00608 RGBVALUE_PROMTRAITS1(double)
    00609 RGBVALUE_PROMTRAITS2(float, unsigned char)
    00610 RGBVALUE_PROMTRAITS2(unsigned char, float)
    00611 RGBVALUE_PROMTRAITS2(int, unsigned char)
    00612 RGBVALUE_PROMTRAITS2(unsigned char, int)
    00613 RGBVALUE_PROMTRAITS2(int, float)
    00614 RGBVALUE_PROMTRAITS2(float, int)
    00615 RGBVALUE_PROMTRAITS2(double, unsigned char)
    00616 RGBVALUE_PROMTRAITS2(unsigned char, double)
    00617 RGBVALUE_PROMTRAITS2(int, double)
    00618 RGBVALUE_PROMTRAITS2(double, int)
    00619 RGBVALUE_PROMTRAITS2(double, float)
    00620 RGBVALUE_PROMTRAITS2(float, double)
    00621
    00622 #undef RGBVALUE_NUMTRAITS
    00623 #undef RGBVALUE_PROMTRAITS1
    00624 #undef RGBVALUE_PROMTRAITS2
    00625
    00626 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00627
    00628
    00629 /********************************************************/
    00630 /*                                                      */
    00631 /*                      RGBValue-Arithmetic             */
    00632 /*                                                      */
    00633 /********************************************************/
    00634
    00635 /** \addtogroup RGBValueOperators
    00636  */
    00637 //@{
    00638     /// componentwise add-assignment
    00639 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00640           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00641 inline
    00642 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00643 operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00644            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00645 {
    00646     l.red() += r.red();
    00647     l.green() += r.green();
    00648     l.blue() += r.blue();
    00649     return l;
    00650 }
    00651
    00652     /// componentwise subtract-assignment
    00653 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00654           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00655 inline
    00656 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00657 operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00658            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00659 {
    00660     l.red() -= r.red();
    00661     l.green() -= r.green();
    00662     l.blue() -= r.blue();
    00663     return l;
    00664 }
    00665
    00666     /// componentwise multiply-assignment
    00667 template <class V1, unsigned int RIDX1, unsigned int BIDX1, unsigned int GIDX1, class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00668 inline
    00669 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00670 operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00671            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00672 {
    00673     l.red() *= r.red();
    00674     l.green() *= r.green();
    00675     l.blue() *= r.blue();
    00676     return l;
    00677 }
    00678
    00679     /// componentwise scalar multiply-assignment
    00680 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00681 inline
    00682 RGBValue<V, RIDX, GIDX, BIDX> &
    00683 operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
    00684 {
    00685     l.red() *= r;
    00686     l.green() *= r;
    00687     l.blue() *= r;
    00688     return l;
    00689 }
    00690
    00691     /// componentwise scalar divide-assignment
    00692 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00693 inline
    00694 RGBValue<V, RIDX, GIDX, BIDX> &
    00695 operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
    00696 {
    00697     l.red() /= r;
    00698     l.green() /= r;
    00699     l.blue() /= r;
    00700     return l;
    00701 }
    00702
    00703 using VIGRA_CSTD::abs;
    00704
    00705     /// component-wise absolute value
    00706 template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00707 inline
    00708 RGBValue<T, RIDX, GIDX, BIDX>
    00709 abs(RGBValue<T, RIDX, GIDX, BIDX> const & v)
    00710 {
    00711   return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v.blue()));
    00712 }
    00713
    00714     /// component-wise addition
    00715 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
    00716 inline
    00717 typename PromoteTraits<RGBValue<V1, R, G, B>,
    00718                        RGBValue<V2, R, G, B> >::Promote
    00719 operator+(RGBValue<V1, R, G, B> const & r1,
    00720           RGBValue<V2, R, G, B> const & r2)
    00721 {
    00722     typename PromoteTraits<RGBValue<V1, R, G, B>,
    00723                            RGBValue<V2, R, G, B> >::Promote res(r1);
    00724
    00725     res += r2;
    00726
    00727     return res;
    00728 }
    00729
    00730     /// component-wise subtraction
    00731 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
    00732 inline
    00733 typename PromoteTraits<RGBValue<V1, R, G, B>,
    00734                        RGBValue<V2, R, G, B> >::Promote
    00735 operator-(RGBValue<V1, R, G, B> const & r1,
    00736           RGBValue<V2, R, G, B> const & r2)
    00737 {
    00738     typename PromoteTraits<RGBValue<V1, R, G, B>,
    00739                            RGBValue<V2, R, G, B> >::Promote res(r1);
    00740
    00741     res -= r2;
    00742
    00743     return res;
    00744 }
    00745
    00746     /// component-wise multiplication
    00747 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
    00748 inline
    00749 typename PromoteTraits<RGBValue<V1, R, G, B>,
    00750                        RGBValue<V2, R, G, B> >::Promote
    00751 operator*(RGBValue<V1, R, G, B> const & r1,
    00752           RGBValue<V2, R, G, B> const & r2)
    00753 {
    00754     typename PromoteTraits<RGBValue<V1, R, G, B>,
    00755                            RGBValue<V2, R, G, B> >::Promote res(r1);
    00756
    00757     res *= r2;
    00758
    00759     return res;
    00760 }
    00761
    00762     /// component-wise left scalar multiplication
    00763 template <class V, unsigned int R, unsigned int G, unsigned int B>
    00764 inline
    00765 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
    00766 operator*(double v, RGBValue<V, R, G, B> const & r)
    00767 {
    00768     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
    00769
    00770     res *= v;
    00771
    00772     return res;
    00773 }
    00774
    00775     /// component-wise right scalar multiplication
    00776 template <class V, unsigned int R, unsigned int G, unsigned int B>
    00777 inline
    00778 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
    00779 operator*(RGBValue<V, R, G, B> const & r, double v)
    00780 {
    00781     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
    00782
    00783     res *= v;
    00784
    00785     return res;
    00786 }
    00787
    00788     /// component-wise scalar division
    00789 template <class V, unsigned int R, unsigned int G, unsigned int B>
    00790 inline
    00791 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
    00792 operator/(RGBValue<V, R, G, B> const & r, double v)
    00793 {
    00794     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
    00795
    00796     res /= v;
    00797
    00798     return res;
    00799 }
    00800
    00801     /// cross product
    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 cross(RGBValue<V1, R, G, B> const & r1,
    00807       RGBValue<V2, R, G, B> const & r2)
    00808 {
    00809     typedef typename PromoteTraits<RGBValue<V1, R, G, B>,
    00810                                    RGBValue<V2, R, G, B> >::Promote
    00811             Res;
    00812
    00813     return  Res(r1.green()*r2.blue() - r1.blue()*r2.green(),
    00814                 r1.blue()*r2.red() - r1.red()*r2.blue(),
    00815                 r1.red()*r2.green() - r1.green()*r2.red());
    00816 }
    00817
    00818     /// dot product
    00819 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00820           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00821 inline
    00822 typename PromoteTraits<V1, V2>::Promote
    00823 dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1,
    00824     RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2)
    00825 {
    00826     return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue();
    00827 }
    00828
    00829 using VIGRA_CSTD::ceil;
    00830
    00831     /** Apply ceil() function to each RGB component.
    00832     */
    00833 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00834 inline
    00835 RGBValue<V, RIDX, GIDX, BIDX>
    00836 ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r)
    00837 {
    00838     return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()),
    00839                                          ceil(r.green()),
    00840                                          ceil(r.blue()));
    00841 }
    00842
    00843 using VIGRA_CSTD::floor;
    00844
    00845     /** Apply floor() function to each RGB component.
    00846     */
    00847 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00848 inline
    00849 RGBValue<V, RIDX, GIDX, BIDX>
    00850 floor(RGBValue<V, RIDX, GIDX, BIDX> const & r)
    00851 {
    00852     return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()),
    00853                                          floor(r.green()),
    00854                                          floor(r.blue()));
    00855 }
    00856
    00857 //@}
    00858
    00859 /********************************************************/
    00860 /*                                                      */
    00861 /*                      RGBValue-Accessors              */
    00862 /*                                                      */
    00863 /********************************************************/
    00864
    00865 /** \addtogroup DataAccessors
    00866 */
    00867 //@{
    00868 /** \defgroup RGBValueAccessors Accessors for RGBValue */
    00869 //@{
    00870     /** Encapsulate access to rgb values.
    00871
    00872     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    00873     Namespace: vigra
    00874     */
    00875 template <class RGBVALUE>
    00876 class RGBAccessor
    00877 : public VectorAccessor<RGBVALUE>
    00878 {
    00879   public:
    00880
    00881     typedef typename RGBVALUE::value_type component_type;
    00882
    00883         /** Get value of the red component
    00884         */
    00885     template <class RGBIterator>
    00886     component_type const & red(RGBIterator const & rgb) const
    00887     {
    00888         return (*rgb).red();
    00889     }
    00890
    00891     template <class V, class RGBIterator>
    00892     void setRGB(V r, V g, V b, RGBIterator const & rgb) const
    00893     {
    00894         (*rgb).setRGB( r, g, b );
    00895     }
    00896
    00897
    00898         /** Set value of the red component. The type <TT>V</TT> of the passed
    00899             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00900         */
    00901     template <class V, class RGBIterator>
    00902     void setRed(V value, RGBIterator const & rgb) const
    00903     {
    00904         (*rgb).setRed(value);
    00905     }
    00906
    00907         /** Get value of the red component at an offset
    00908         */
    00909     template <class RGBIterator, class DIFFERENCE>
    00910     component_type const & red(RGBIterator const & rgb, DIFFERENCE diff) const
    00911     {
    00912         return rgb[diff].red();
    00913     }
    00914
    00915         /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
    00916             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00917         */
    00918     template <class V, class RGBIterator, class DIFFERENCE>
    00919     void setRed(V value, RGBIterator const & rgb, DIFFERENCE diff) const
    00920     {
    00921         rgb[diff].setRed(value);
    00922     }
    00923
    00924         /** Get value of the green component
    00925         */
    00926     template <class RGBIterator>
    00927     component_type const & green(RGBIterator const & rgb) const
    00928     {
    00929         return (*rgb).green();
    00930     }
    00931
    00932         /** Set value of the green component. The type <TT>V</TT> of the passed
    00933             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00934         */
    00935     template <class V, class RGBIterator>
    00936     void setGreen(V value, RGBIterator const & rgb) const
    00937     {
    00938         (*rgb).setGreen(value);
    00939     }
    00940
    00941         /** Get value of the green component at an offset
    00942         */
    00943     template <class RGBIterator, class DIFFERENCE>
    00944     component_type const & green(RGBIterator const & rgb, DIFFERENCE d) const
    00945     {
    00946         return rgb[d].green();
    00947     }
    00948
    00949         /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
    00950             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00951         */
    00952     template <class V, class RGBIterator, class DIFFERENCE>
    00953     void setGreen(V value, RGBIterator const & rgb, DIFFERENCE d) const
    00954     {
    00955         rgb[d].setGreen(value);
    00956     }
    00957
    00958         /** Get value of the blue component
    00959         */
    00960     template <class RGBIterator>
    00961     component_type const & blue(RGBIterator const & rgb) const
    00962     {
    00963         return (*rgb).blue();
    00964     }
    00965
    00966         /** Set value of the blue component. The type <TT>V</TT> of the passed
    00967             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00968         */
    00969     template <class V, class RGBIterator>
    00970     void setBlue(V value, RGBIterator const & rgb) const
    00971     {
    00972         (*rgb).setBlue(value);
    00973     }
    00974
    00975         /** Get value of the blue component at an offset
    00976         */
    00977     template <class RGBIterator, class DIFFERENCE>
    00978     component_type const & blue(RGBIterator const & rgb, DIFFERENCE d) const
    00979     {
    00980         return rgb[d].blue();
    00981     }
    00982
    00983         /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
    00984             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00985         */
    00986     template <class V, class RGBIterator, class DIFFERENCE>
    00987     void setBlue(V value, RGBIterator const & rgb, DIFFERENCE d) const
    00988     {
    00989         rgb[d].setBlue(value);
    00990     }
    00991
    00992 };
    00993
    00994
    00995 /********************************************************/
    00996 /*                                                      */
    00997 /*                       RedAccessor                    */
    00998 /*                                                      */
    00999 /********************************************************/
    01000
    01001     /** Encapsulate access to red band of an rgb value.
    01002
    01003     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    01004     Namespace: vigra
    01005     */
    01006 template <class RGBVALUE>
    01007 class RedAccessor
    01008 {
    01009   public:
    01010     typedef typename RGBVALUE::value_type value_type;
    01011
    01012         /** Get value of the red component
    01013         */
    01014     template <class ITERATOR>
    01015     value_type const & operator()(ITERATOR const & i) const {
    01016         return (*i).red();
    01017     }
    01018
    01019         /** Get value of the red component at an offset
    01020         */
    01021     template <class ITERATOR, class DIFFERENCE>
    01022     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
    01023     {
    01024         return i[d].red();
    01025     }
    01026
    01027         /** Set value of the red component. The type <TT>V</TT> of the passed
    01028             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01029         */
    01030     template <class V, class ITERATOR>
    01031     void set(V value, ITERATOR const & i) const {
    01032         (*i).setRed(value);
    01033     }
    01034
    01035
    01036         /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
    01037             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01038         */
    01039     template <class V, class ITERATOR, class DIFFERENCE>
    01040     void set(V value, ITERATOR const & i, DIFFERENCE d) const
    01041     {
    01042         i[d].setRed(value);
    01043     }
    01044 };
    01045
    01046 /********************************************************/
    01047 /*                                                      */
    01048 /*                     GreenAccessor                    */
    01049 /*                                                      */
    01050 /********************************************************/
    01051
    01052     /** Encapsulate access to green band of an rgb value.
    01053
    01054     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    01055     Namespace: vigra
    01056     */
    01057 template <class RGBVALUE>
    01058 class GreenAccessor
    01059 {
    01060   public:
    01061     typedef typename RGBVALUE::value_type value_type;
    01062
    01063         /** Get value of the green component
    01064         */
    01065     template <class ITERATOR>
    01066     value_type const & operator()(ITERATOR const & i) const {
    01067         return (*i).green();
    01068     }
    01069
    01070         /** Get value of the green component at an offset
    01071         */
    01072     template <class ITERATOR, class DIFFERENCE>
    01073     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
    01074     {
    01075         return i[d].green();
    01076     }
    01077
    01078         /** Set value of the green component. The type <TT>V</TT> of the passed
    01079             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01080         */
    01081     template <class V, class ITERATOR>
    01082     void set(V value, ITERATOR const & i) const {
    01083         (*i).setGreen(value);
    01084     }
    01085
    01086
    01087         /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
    01088             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01089         */
    01090     template <class V, class ITERATOR, class DIFFERENCE>
    01091     void set(V value, ITERATOR const & i, DIFFERENCE d) const
    01092     {
    01093         i[d].setGreen(value);
    01094     }
    01095 };
    01096
    01097 /********************************************************/
    01098 /*                                                      */
    01099 /*                     BlueAccessor                     */
    01100 /*                                                      */
    01101 /********************************************************/
    01102
    01103     /** Encapsulate access to blue band of an rgb value.
    01104
    01105     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    01106     Namespace: vigra
    01107     */
    01108 template <class RGBVALUE>
    01109 class BlueAccessor
    01110 {
    01111   public:
    01112     typedef typename RGBVALUE::value_type value_type;
    01113
    01114         /** Get value of the blue component
    01115         */
    01116     template <class ITERATOR>
    01117     value_type const & operator()(ITERATOR const & i) const {
    01118         return (*i).blue();
    01119     }
    01120
    01121         /** Get value of the blue component at an offset
    01122         */
    01123     template <class ITERATOR, class DIFFERENCE>
    01124     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
    01125     {
    01126         return i[d].blue();
    01127     }
    01128
    01129         /** Set value of the blue component. The type <TT>V</TT> of the passed
    01130             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01131         */
    01132     template <class V, class ITERATOR>
    01133     void set(V value, ITERATOR const & i) const {
    01134         (*i).setBlue(value);
    01135     }
    01136
    01137
    01138         /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
    01139             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01140         */
    01141     template <class V, class ITERATOR, class DIFFERENCE>
    01142     void set(V value, ITERATOR const & i, DIFFERENCE d) const
    01143     {
    01144         i[d].setBlue(value);
    01145     }
    01146 };
    01147
    01148 /********************************************************/
    01149 /*                                                      */
    01150 /*                  RGBToGrayAccessor                   */
    01151 /*                                                      */
    01152 /********************************************************/
    01153
    01154     /** Encapsulate access to luminance of an rgb value.
    01155
    01156     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    01157     Namespace: vigra
    01158     */
    01159 template <class RGBVALUE>
    01160 class RGBToGrayAccessor
    01161 {
    01162   public:
    01163     typedef typename RGBVALUE::value_type value_type;
    01164
    01165         /** Get value of the luminance
    01166         */
    01167     template <class ITERATOR>
    01168     value_type operator()(ITERATOR const & i) const {
    01169                 return (*i).luminance(); }
    01170
    01171         /** Get value of the luminance at an offset
    01172         */
    01173     template <class ITERATOR, class DIFFERENCE>
    01174     value_type operator()(ITERATOR const & i, DIFFERENCE d) const
    01175     {
    01176         return i[d].luminance();
    01177     }
    01178 };
    01179
    01180
    01181 /********************************************************/
    01182 /*                                                      */
    01183 /*                  GrayToRGBAccessor                   */
    01184 /*                                                      */
    01185 /********************************************************/
    01186
    01187     /** Create an RGB view for a grayscale image by making all three channels
    01188         equal.
    01189
    01190     <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>"<br>
    01191     Namespace: vigra
    01192     */
    01193 template <class VALUETYPE>
    01194 class GrayToRGBAccessor
    01195 {
    01196    public:
    01197      typedef typename vigra::RGBValue<VALUETYPE> value_type;
    01198
    01199          /** Get RGB value for the given pixel.
    01200          */
    01201      template <class ITERATOR>
    01202      value_type operator()(ITERATOR const & i) const {
    01203                  return value_type(*i,*i,*i); }
    01204
    01205          /** Get RGB value at an offset
    01206          */
    01207      template <class ITERATOR, class DIFFERENCE>
    01208      value_type operator()(ITERATOR const & i, DIFFERENCE d) const
    01209      {
    01210          return value_type(i[d],i[d],i[d]);
    01211      }
    01212 };
    01213
    01214
    01215 //@}
    01216 //@}
    01217
    01218
    01219 } // namespace vigra
    01220
    01221 #endif // VIGRA_RGBVALUE_HXX

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.5.0 (7 Dec 2006)