[ 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> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><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> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><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> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><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 VigraFalseType isOrdered;
    00472     typedef VigraFalseType isComplex;
    00473
    00474     static Type zero() {
    00475         return Type(NumericTraits<T>::zero());
    00476     }
    00477     static Type one() {
    00478         return Type(NumericTraits<T>::one());
    00479     }
    00480     static Type nonZero() {
    00481         return Type(NumericTraits<T>::nonZero());
    00482     }
    00483
    00484     static Promote toPromote(Type const & v) {
    00485         return Promote(v);
    00486     }
    00487     static RealPromote toRealPromote(Type const & v) {
    00488         return RealPromote(v);
    00489     }
    00490     static Type fromPromote(Promote const & v) {
    00491       return Type(NumericTraits<T>::fromPromote(v.red()),
    00492                   NumericTraits<T>::fromPromote(v.green()),
    00493                   NumericTraits<T>::fromPromote(v.blue()));
    00494     }
    00495     static Type fromRealPromote(RealPromote const & v) {
    00496         return Type(NumericTraits<T>::fromRealPromote(v.red()),
    00497                     NumericTraits<T>::fromRealPromote(v.green()),
    00498                     NumericTraits<T>::fromRealPromote(v.blue()));
    00499     }
    00500 };
    00501
    00502 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00503 struct NormTraits<RGBValue<T, R, G, B> >
    00504 {
    00505     typedef RGBValue<T, R, G, B> Type;
    00506     typedef typename Type::SquaredNormType    SquaredNormType;
    00507     typedef typename Type::NormType           NormType;
    00508 };
    00509
    00510 template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
    00511 struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
    00512 {
    00513     typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
    00514 };
    00515
    00516 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00517 struct PromoteTraits<RGBValue<T, R, G, B>, double >
    00518 {
    00519     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
    00520 };
    00521
    00522 template <class T, unsigned int R, unsigned int G, unsigned int B>
    00523 struct PromoteTraits<double, RGBValue<T, R, G, B> >
    00524 {
    00525     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
    00526 };
    00527
    00528 template<class T, unsigned int R, unsigned int G, unsigned int B>
    00529 struct CanSkipInitialization<RGBValue<T, R, G, B> >
    00530 {
    00531     typedef typename CanSkipInitialization<T>::type type;
    00532     static const bool value = type::asBool;
    00533 };
    00534
    00535
    00536 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00537
    00538 #define RGBVALUE_NUMTRAITS(T) \
    00539 template<>\
    00540 struct NumericTraits<RGBValue<T, 0, 1, 2> >\
    00541 {\
    00542     typedef RGBValue<T> Type; \
    00543     typedef RGBValue<NumericTraits<T>::Promote> Promote; \
    00544     typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \
    00545     typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \
    00546     typedef T ValueType; \
    00547     \
    00548     typedef NumericTraits<T>::isIntegral isIntegral; \
    00549     typedef VigraFalseType isScalar; \
    00550     typedef NumericTraits<T>::isSigned isSigned; \
    00551     typedef VigraFalseType isOrdered; \
    00552     typedef VigraFalseType isComplex; \
    00553     \
    00554     static RGBValue<T> zero() { \
    00555         return RGBValue<T>(NumericTraits<T>::zero()); \
    00556     }\
    00557     static RGBValue<T> one() { \
    00558         return RGBValue<T>(NumericTraits<T>::one()); \
    00559     }\
    00560     static RGBValue<T> nonZero() { \
    00561         return RGBValue<T>(NumericTraits<T>::nonZero()); \
    00562     }\
    00563     \
    00564     static Promote toPromote(RGBValue<T> const & v) { \
    00565         return Promote(v); \
    00566     }\
    00567     static RealPromote toRealPromote(RGBValue<T> const & v) { \
    00568         return RealPromote(v); \
    00569     }\
    00570     static RGBValue<T> fromPromote(Promote const & v) { \
    00571         RGBValue<T> res;\
    00572         RGBValue<T>::iterator d = res.begin();\
    00573         Promote::const_iterator s = v.begin();\
    00574         for(; d != res.end(); ++d, ++s)\
    00575             *d = NumericTraits<T>::fromPromote(*s);\
    00576         return res;\
    00577     }\
    00578     static RGBValue<T> fromRealPromote(RealPromote const & v) {\
    00579         RGBValue<T> res;\
    00580         RGBValue<T>::iterator d = res.begin();\
    00581         RealPromote::const_iterator s = v.begin();\
    00582         for(; d != res.end(); ++d, ++s)\
    00583             *d = NumericTraits<T>::fromRealPromote(*s);\
    00584         return res;\
    00585     }\
    00586 }; \
    00587 template<>\
    00588 struct NormTraits<RGBValue<T, 0, 1, 2> >\
    00589 {\
    00590     typedef RGBValue<T> Type;\
    00591     typedef Type::SquaredNormType           SquaredNormType; \
    00592     typedef Type::NormType NormType; \
    00593 };
    00594
    00595 #define RGBVALUE_PROMTRAITS1(type1) \
    00596 template<> \
    00597 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \
    00598 { \
    00599     typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \
    00600     static Promote toPromote(RGBValue<type1> const & v) { \
    00601         return static_cast<Promote>(v); } \
    00602 }; \
    00603 template <> \
    00604 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \
    00605 { \
    00606     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
    00607 }; \
    00608 template <> \
    00609 struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \
    00610 { \
    00611     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
    00612 };
    00613
    00614 #define RGBVALUE_PROMTRAITS2(type1, type2) \
    00615 template<> \
    00616 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \
    00617 { \
    00618     typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \
    00619     static Promote toPromote(RGBValue<type1> const & v) { \
    00620         return static_cast<Promote>(v); } \
    00621     static Promote toPromote(RGBValue<type2> const & v) { \
    00622         return static_cast<Promote>(v); } \
    00623 };
    00624
    00625 RGBVALUE_NUMTRAITS(unsigned char)
    00626 RGBVALUE_NUMTRAITS(int)
    00627 RGBVALUE_NUMTRAITS(float)
    00628 RGBVALUE_NUMTRAITS(double)
    00629 RGBVALUE_PROMTRAITS1(unsigned char)
    00630 RGBVALUE_PROMTRAITS1(int)
    00631 RGBVALUE_PROMTRAITS1(float)
    00632 RGBVALUE_PROMTRAITS1(double)
    00633 RGBVALUE_PROMTRAITS2(float, unsigned char)
    00634 RGBVALUE_PROMTRAITS2(unsigned char, float)
    00635 RGBVALUE_PROMTRAITS2(int, unsigned char)
    00636 RGBVALUE_PROMTRAITS2(unsigned char, int)
    00637 RGBVALUE_PROMTRAITS2(int, float)
    00638 RGBVALUE_PROMTRAITS2(float, int)
    00639 RGBVALUE_PROMTRAITS2(double, unsigned char)
    00640 RGBVALUE_PROMTRAITS2(unsigned char, double)
    00641 RGBVALUE_PROMTRAITS2(int, double)
    00642 RGBVALUE_PROMTRAITS2(double, int)
    00643 RGBVALUE_PROMTRAITS2(double, float)
    00644 RGBVALUE_PROMTRAITS2(float, double)
    00645
    00646 #undef RGBVALUE_NUMTRAITS
    00647 #undef RGBVALUE_PROMTRAITS1
    00648 #undef RGBVALUE_PROMTRAITS2
    00649
    00650 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00651
    00652
    00653 /********************************************************/
    00654 /*                                                      */
    00655 /*                      RGBValue-Arithmetic             */
    00656 /*                                                      */
    00657 /********************************************************/
    00658
    00659 /** \addtogroup RGBValueOperators
    00660  */
    00661 //@{
    00662     /// componentwise add-assignment
    00663 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00664           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00665 inline
    00666 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00667 operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00668            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00669 {
    00670     l.red() += r.red();
    00671     l.green() += r.green();
    00672     l.blue() += r.blue();
    00673     return l;
    00674 }
    00675
    00676     /// componentwise subtract-assignment
    00677 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00678           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00679 inline
    00680 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00681 operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00682            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00683 {
    00684     l.red() -= r.red();
    00685     l.green() -= r.green();
    00686     l.blue() -= r.blue();
    00687     return l;
    00688 }
    00689
    00690     /// componentwise multiply-assignment
    00691 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00692           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00693 inline
    00694 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00695 operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00696            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00697 {
    00698     l.red() = V1(l.red() * r.red());
    00699     l.green() = V1(l.green() * r.green());
    00700     l.blue() = V1(l.blue() * r.blue());
    00701     return l;
    00702 }
    00703
    00704     /// componentwise scalar multiply-assignment
    00705 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00706 inline
    00707 RGBValue<V, RIDX, GIDX, BIDX> &
    00708 operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
    00709 {
    00710     l.red() = V(l.red() * r);
    00711     l.green() = V(l.green() * r);
    00712     l.blue() = V(l.blue() * r);
    00713     return l;
    00714 }
    00715
    00716     /// componentwise divide-assignment
    00717 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00718           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00719 inline
    00720 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
    00721 operator/=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
    00722            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
    00723 {
    00724     l.red() = V1(l.red() / r.red());
    00725     l.green() = V1(l.green() / r.green());
    00726     l.blue() = V1(l.blue() / r.blue());
    00727     return l;
    00728 }
    00729
    00730     /// componentwise scalar divide-assignment
    00731 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00732 inline
    00733 RGBValue<V, RIDX, GIDX, BIDX> &
    00734 operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
    00735 {
    00736     l.red() = V(l.red() / r);
    00737     l.green() = V(l.green() / r);
    00738     l.blue() = V(l.blue() / r);
    00739     return l;
    00740 }
    00741
    00742 using VIGRA_CSTD::abs;
    00743
    00744     /// component-wise absolute value
    00745 template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00746 inline
    00747 RGBValue<T, RIDX, GIDX, BIDX>
    00748 abs(RGBValue<T, RIDX, GIDX, BIDX> const & v)
    00749 {
    00750   return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v.blue()));
    00751 }
    00752
    00753     /// component-wise addition
    00754 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
    00755 inline
    00756 typename PromoteTraits<RGBValue<V1, R, G, B>,
    00757                        RGBValue<V2, R, G, B> >::Promote
    00758 operator+(RGBValue<V1, R, G, B> const & r1,
    00759           RGBValue<V2, R, G, B> const & r2)
    00760 {
    00761     typename PromoteTraits<RGBValue<V1, R, G, B>,
    00762                            RGBValue<V2, R, G, B> >::Promote res(r1);
    00763
    00764     res += r2;
    00765
    00766     return res;
    00767 }
    00768
    00769     /// component-wise subtraction
    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 multiplication
    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 left scalar multiplication
    00802 template <class V, unsigned int R, unsigned int G, unsigned int B>
    00803 inline
    00804 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
    00805 operator*(double v, RGBValue<V, R, G, B> const & r)
    00806 {
    00807     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
    00808
    00809     res *= v;
    00810
    00811     return res;
    00812 }
    00813
    00814     /// component-wise right scalar multiplication
    00815 template <class V, unsigned int R, unsigned int G, unsigned int B>
    00816 inline
    00817 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
    00818 operator*(RGBValue<V, R, G, B> const & r, double v)
    00819 {
    00820     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
    00821
    00822     res *= v;
    00823
    00824     return res;
    00825 }
    00826
    00827     /// component-wise division
    00828 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
    00829 inline
    00830 typename PromoteTraits<RGBValue<V1, R, G, B>,
    00831                        RGBValue<V2, R, G, B> >::Promote
    00832 operator/(RGBValue<V1, R, G, B> const & r1,
    00833           RGBValue<V2, R, G, B> const & r2)
    00834 {
    00835     typename PromoteTraits<RGBValue<V1, R, G, B>,
    00836                            RGBValue<V2, R, G, B> >::Promote res(r1);
    00837
    00838     res /= r2;
    00839
    00840     return res;
    00841 }
    00842
    00843     /// component-wise scalar division
    00844 template <class V, unsigned int R, unsigned int G, unsigned int B>
    00845 inline
    00846 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
    00847 operator/(RGBValue<V, R, G, B> const & r, double v)
    00848 {
    00849     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
    00850
    00851     res /= v;
    00852
    00853     return res;
    00854 }
    00855
    00856     /// cross product
    00857 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
    00858 inline
    00859 typename PromoteTraits<RGBValue<V1, R, G, B>,
    00860                        RGBValue<V2, R, G, B> >::Promote
    00861 cross(RGBValue<V1, R, G, B> const & r1,
    00862       RGBValue<V2, R, G, B> const & r2)
    00863 {
    00864     typedef typename PromoteTraits<RGBValue<V1, R, G, B>,
    00865                                    RGBValue<V2, R, G, B> >::Promote
    00866             Res;
    00867
    00868     return  Res(r1.green()*r2.blue() - r1.blue()*r2.green(),
    00869                 r1.blue()*r2.red() - r1.red()*r2.blue(),
    00870                 r1.red()*r2.green() - r1.green()*r2.red());
    00871 }
    00872
    00873     /// dot product
    00874 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
    00875           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
    00876 inline
    00877 typename PromoteTraits<V1, V2>::Promote
    00878 dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1,
    00879     RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2)
    00880 {
    00881     return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue();
    00882 }
    00883
    00884 using VIGRA_CSTD::ceil;
    00885
    00886     /** Apply ceil() function to each RGB component.
    00887     */
    00888 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00889 inline
    00890 RGBValue<V, RIDX, GIDX, BIDX>
    00891 ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r)
    00892 {
    00893     return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()),
    00894                                          ceil(r.green()),
    00895                                          ceil(r.blue()));
    00896 }
    00897
    00898 using VIGRA_CSTD::floor;
    00899
    00900     /** Apply floor() function to each RGB component.
    00901     */
    00902 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
    00903 inline
    00904 RGBValue<V, RIDX, GIDX, BIDX>
    00905 floor(RGBValue<V, RIDX, GIDX, BIDX> const & r)
    00906 {
    00907     return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()),
    00908                                          floor(r.green()),
    00909                                          floor(r.blue()));
    00910 }
    00911
    00912 //@}
    00913
    00914 /********************************************************/
    00915 /*                                                      */
    00916 /*                      RGBValue-Accessors              */
    00917 /*                                                      */
    00918 /********************************************************/
    00919
    00920 /** \addtogroup DataAccessors
    00921 */
    00922 //@{
    00923 /** \defgroup RGBValueAccessors Accessors for RGBValue */
    00924 //@{
    00925     /** Encapsulate access to rgb values.
    00926
    00927     <b>\#include</b> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><br>
    00928     Namespace: vigra
    00929     */
    00930 template <class RGBVALUE>
    00931 class RGBAccessor
    00932 : public VectorAccessor<RGBVALUE>
    00933 {
    00934   public:
    00935
    00936     typedef typename RGBVALUE::value_type component_type;
    00937
    00938         /** Get value of the red component
    00939         */
    00940     template <class RGBIterator>
    00941     component_type const & red(RGBIterator const & rgb) const
    00942     {
    00943         return (*rgb).red();
    00944     }
    00945
    00946     template <class V, class RGBIterator>
    00947     void setRGB(V r, V g, V b, RGBIterator const & rgb) const
    00948     {
    00949         (*rgb).setRGB( r, g, b );
    00950     }
    00951
    00952
    00953         /** Set value of the red component. The type <TT>V</TT> of the passed
    00954             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00955         */
    00956     template <class V, class RGBIterator>
    00957     void setRed(V value, RGBIterator const & rgb) const
    00958     {
    00959         (*rgb).setRed(value);
    00960     }
    00961
    00962         /** Get value of the red component at an offset
    00963         */
    00964     template <class RGBIterator, class DIFFERENCE>
    00965     component_type const & red(RGBIterator const & rgb, DIFFERENCE diff) const
    00966     {
    00967         return rgb[diff].red();
    00968     }
    00969
    00970         /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
    00971             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00972         */
    00973     template <class V, class RGBIterator, class DIFFERENCE>
    00974     void setRed(V value, RGBIterator const & rgb, DIFFERENCE diff) const
    00975     {
    00976         rgb[diff].setRed(value);
    00977     }
    00978
    00979         /** Get value of the green component
    00980         */
    00981     template <class RGBIterator>
    00982     component_type const & green(RGBIterator const & rgb) const
    00983     {
    00984         return (*rgb).green();
    00985     }
    00986
    00987         /** Set value of the green component. The type <TT>V</TT> of the passed
    00988             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    00989         */
    00990     template <class V, class RGBIterator>
    00991     void setGreen(V value, RGBIterator const & rgb) const
    00992     {
    00993         (*rgb).setGreen(value);
    00994     }
    00995
    00996         /** Get value of the green component at an offset
    00997         */
    00998     template <class RGBIterator, class DIFFERENCE>
    00999     component_type const & green(RGBIterator const & rgb, DIFFERENCE d) const
    01000     {
    01001         return rgb[d].green();
    01002     }
    01003
    01004         /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
    01005             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    01006         */
    01007     template <class V, class RGBIterator, class DIFFERENCE>
    01008     void setGreen(V value, RGBIterator const & rgb, DIFFERENCE d) const
    01009     {
    01010         rgb[d].setGreen(value);
    01011     }
    01012
    01013         /** Get value of the blue component
    01014         */
    01015     template <class RGBIterator>
    01016     component_type const & blue(RGBIterator const & rgb) const
    01017     {
    01018         return (*rgb).blue();
    01019     }
    01020
    01021         /** Set value of the blue component. The type <TT>V</TT> of the passed
    01022             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    01023         */
    01024     template <class V, class RGBIterator>
    01025     void setBlue(V value, RGBIterator const & rgb) const
    01026     {
    01027         (*rgb).setBlue(value);
    01028     }
    01029
    01030         /** Get value of the blue component at an offset
    01031         */
    01032     template <class RGBIterator, class DIFFERENCE>
    01033     component_type const & blue(RGBIterator const & rgb, DIFFERENCE d) const
    01034     {
    01035         return rgb[d].blue();
    01036     }
    01037
    01038         /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
    01039             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
    01040         */
    01041     template <class V, class RGBIterator, class DIFFERENCE>
    01042     void setBlue(V value, RGBIterator const & rgb, DIFFERENCE d) const
    01043     {
    01044         rgb[d].setBlue(value);
    01045     }
    01046
    01047 };
    01048
    01049
    01050 /********************************************************/
    01051 /*                                                      */
    01052 /*                       RedAccessor                    */
    01053 /*                                                      */
    01054 /********************************************************/
    01055
    01056     /** Encapsulate access to red band of an rgb value.
    01057
    01058     <b>\#include</b> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><br>
    01059     Namespace: vigra
    01060     */
    01061 template <class RGBVALUE>
    01062 class RedAccessor
    01063 {
    01064   public:
    01065     typedef typename RGBVALUE::value_type value_type;
    01066
    01067         /** Get value of the red component
    01068         */
    01069     template <class ITERATOR>
    01070     value_type const & operator()(ITERATOR const & i) const {
    01071         return (*i).red();
    01072     }
    01073
    01074         /** Get value of the red component at an offset
    01075         */
    01076     template <class ITERATOR, class DIFFERENCE>
    01077     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
    01078     {
    01079         return i[d].red();
    01080     }
    01081
    01082         /** Set value of the red component. The type <TT>V</TT> of the passed
    01083             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01084         */
    01085     template <class V, class ITERATOR>
    01086     void set(V value, ITERATOR const & i) const {
    01087         (*i).setRed(value);
    01088     }
    01089
    01090
    01091         /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
    01092             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01093         */
    01094     template <class V, class ITERATOR, class DIFFERENCE>
    01095     void set(V value, ITERATOR const & i, DIFFERENCE d) const
    01096     {
    01097         i[d].setRed(value);
    01098     }
    01099 };
    01100
    01101 /********************************************************/
    01102 /*                                                      */
    01103 /*                     GreenAccessor                    */
    01104 /*                                                      */
    01105 /********************************************************/
    01106
    01107     /** Encapsulate access to green band of an rgb value.
    01108
    01109     <b>\#include</b> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><br>
    01110     Namespace: vigra
    01111     */
    01112 template <class RGBVALUE>
    01113 class GreenAccessor
    01114 {
    01115   public:
    01116     typedef typename RGBVALUE::value_type value_type;
    01117
    01118         /** Get value of the green component
    01119         */
    01120     template <class ITERATOR>
    01121     value_type const & operator()(ITERATOR const & i) const {
    01122         return (*i).green();
    01123     }
    01124
    01125         /** Get value of the green component at an offset
    01126         */
    01127     template <class ITERATOR, class DIFFERENCE>
    01128     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
    01129     {
    01130         return i[d].green();
    01131     }
    01132
    01133         /** Set value of the green component. 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>
    01137     void set(V value, ITERATOR const & i) const {
    01138         (*i).setGreen(value);
    01139     }
    01140
    01141
    01142         /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
    01143             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01144         */
    01145     template <class V, class ITERATOR, class DIFFERENCE>
    01146     void set(V value, ITERATOR const & i, DIFFERENCE d) const
    01147     {
    01148         i[d].setGreen(value);
    01149     }
    01150 };
    01151
    01152 /********************************************************/
    01153 /*                                                      */
    01154 /*                     BlueAccessor                     */
    01155 /*                                                      */
    01156 /********************************************************/
    01157
    01158     /** Encapsulate access to blue band of an rgb value.
    01159
    01160     <b>\#include</b> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><br>
    01161     Namespace: vigra
    01162     */
    01163 template <class RGBVALUE>
    01164 class BlueAccessor
    01165 {
    01166   public:
    01167     typedef typename RGBVALUE::value_type value_type;
    01168
    01169         /** Get value of the blue component
    01170         */
    01171     template <class ITERATOR>
    01172     value_type const & operator()(ITERATOR const & i) const {
    01173         return (*i).blue();
    01174     }
    01175
    01176         /** Get value of the blue component at an offset
    01177         */
    01178     template <class ITERATOR, class DIFFERENCE>
    01179     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
    01180     {
    01181         return i[d].blue();
    01182     }
    01183
    01184         /** Set value of the blue component. 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>
    01188     void set(V value, ITERATOR const & i) const {
    01189         (*i).setBlue(value);
    01190     }
    01191
    01192
    01193         /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
    01194             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
    01195         */
    01196     template <class V, class ITERATOR, class DIFFERENCE>
    01197     void set(V value, ITERATOR const & i, DIFFERENCE d) const
    01198     {
    01199         i[d].setBlue(value);
    01200     }
    01201 };
    01202
    01203 /********************************************************/
    01204 /*                                                      */
    01205 /*                  RGBToGrayAccessor                   */
    01206 /*                                                      */
    01207 /********************************************************/
    01208
    01209     /** Encapsulate access to luminance of an rgb value.
    01210
    01211     <b>\#include</b> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><br>
    01212     Namespace: vigra
    01213     */
    01214 template <class RGBVALUE>
    01215 class RGBToGrayAccessor
    01216 {
    01217   public:
    01218     typedef typename RGBVALUE::value_type value_type;
    01219
    01220         /** Get value of the luminance
    01221         */
    01222     template <class ITERATOR>
    01223     value_type operator()(ITERATOR const & i) const {
    01224                 return (*i).luminance(); }
    01225
    01226         /** Get value of the luminance at an offset
    01227         */
    01228     template <class ITERATOR, class DIFFERENCE>
    01229     value_type operator()(ITERATOR const & i, DIFFERENCE d) const
    01230     {
    01231         return i[d].luminance();
    01232     }
    01233 };
    01234
    01235
    01236 /********************************************************/
    01237 /*                                                      */
    01238 /*                  GrayToRGBAccessor                   */
    01239 /*                                                      */
    01240 /********************************************************/
    01241
    01242     /** Create an RGB view for a grayscale image by making all three channels
    01243         equal.
    01244
    01245     <b>\#include</b> <<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hxx</a>><br>
    01246     Namespace: vigra
    01247     */
    01248 template <class VALUETYPE>
    01249 class GrayToRGBAccessor
    01250 {
    01251    public:
    01252      typedef typename vigra::RGBValue<VALUETYPE> value_type;
    01253
    01254          /** Get RGB value for the given pixel.
    01255          */
    01256      template <class ITERATOR>
    01257      value_type operator()(ITERATOR const & i) const {
    01258                  return value_type(*i,*i,*i); }
    01259
    01260          /** Get RGB value at an offset
    01261          */
    01262      template <class ITERATOR, class DIFFERENCE>
    01263      value_type operator()(ITERATOR const & i, DIFFERENCE d) const
    01264      {
    01265          return value_type(i[d],i[d],i[d]);
    01266      }
    01267 };
    01268
    01269
    01270 //@}
    01271 //@}
    01272
    01273
    01274 } // namespace vigra
    01275
    01276 #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.7.1 (3 Dec 2010)