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

vigra/rgbvalue.hxx |

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)