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

vigra/rgbvalue.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*                                                                      */
00005 /*    This file is part of the VIGRA computer vision library.           */
00006 /*    The VIGRA Website is                                              */
00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
00008 /*    Please direct questions, bug reports, and contributions to        */
00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00010 /*        vigra@informatik.uni-hamburg.de                               */
00011 /*                                                                      */
00012 /*    Permission is hereby granted, free of charge, to any person       */
00013 /*    obtaining a copy of this software and associated documentation    */
00014 /*    files (the "Software"), to deal in the Software without           */
00015 /*    restriction, including without limitation the rights to use,      */
00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00017 /*    sell copies of the Software, and to permit persons to whom the    */
00018 /*    Software is furnished to do so, subject to the following          */
00019 /*    conditions:                                                       */
00020 /*                                                                      */
00021 /*    The above copyright notice and this permission notice shall be    */
00022 /*    included in all copies or substantial portions of the             */
00023 /*    Software.                                                         */
00024 /*                                                                      */
00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
00033 /*                                                                      */
00034 /************************************************************************/
00035 
00036 
00037 #ifndef VIGRA_RGBVALUE_HXX
00038 #define VIGRA_RGBVALUE_HXX
00039 
00040 #include <cmath>    // abs(double)
00041 #include <cstdlib>  // abs(int)
00042 #include "config.hxx"
00043 #include "numerictraits.hxx"
00044 #include "accessor.hxx"
00045 #include "tinyvector.hxx"
00046 #include "static_assert.hxx"
00047 
00048 namespace vigra {
00049 
00050 namespace detail {
00051 
00052 template <unsigned int I, unsigned int R, unsigned int G, unsigned int B>
00053 struct SelectColorIndexRHS;
00054 
00055 template <unsigned int R, unsigned int G, unsigned int B>
00056 struct SelectColorIndexRHS<0, R, G, B>
00057 {
00058     enum { res = R };
00059 };
00060 
00061 template <unsigned int R, unsigned int G, unsigned int B>
00062 struct SelectColorIndexRHS<1, R, G, B>
00063 {
00064     enum { res = G };
00065 };
00066 
00067 template <unsigned int R, unsigned int G, unsigned int B>
00068 struct SelectColorIndexRHS<2, R, G, B>
00069 {
00070     enum { res = B };
00071 };
00072 
00073 } // namespace detail
00074 
00075 #ifndef DOXYGEN
00076 
00077 template <unsigned int R, unsigned int G, unsigned int B>
00078 struct RGBValue_bad_color_indices
00079 : staticAssert::AssertBool<(R < 3 && G < 3 && B < 3 &&
00080                            ((1 << R) + (1 << G) + (1 << B) == 7))>
00081 {};
00082 
00083 #endif /* DOXYGEN */
00084 
00085 
00086 /********************************************************/
00087 /*                                                      */
00088 /*                      RGBValue                        */
00089 /*                                                      */
00090 /********************************************************/
00091 
00092 /** \brief Class for a single RGB value.
00093 
00094     This class contains three values (of the specified type) that represent
00095     red, green, and blue color channels. By means of the template parameters
00096     <tt>RED_IDX, GREEN_IDX, BLUE_IDX</tt>, the indices 0, 1, 2 can be assigned to
00097     the three colors arbitrarily, so that, for example, a BGR type can be created
00098     as
00099 
00100     \code
00101     typedef RGBValue<unsigned char, 2,1,0> BGRValue;
00102     \endcode
00103 
00104     The standard order red=0, green=1, blue=2 is the default. There are three possibilities
00105     to access the color values: accessor functions (\ref red(), \ref green(),
00106     \ref blue()), index operator (operator[](dx), where the <tt>rgb[RED_IDX]</tt>
00107     returns red etc.) and iterator (STL-compatible random access
00108     iterator that references the three colors in turn). The latter two
00109     methods, together with the necessary embedded typedefs, ensure
00110     compatibility of a RGBValue with a STL vector.
00111 
00112     \ref RGBValueOperators "Arithmetic operations" are defined as component-wise applications of these
00113     operations. Addition, subtraction, and multiplication of two RGBValues
00114     (+=, -=, *=, +, -, *, unary -), multiplication and division of an
00115     RGBValue with a double, and NumericTraits/PromoteTraits are defined,
00116     so that RGBValue fulfills the requirements of a \ref LinearAlgebraConcept "Linear Algebra".
00117 
00118     A number of \ref RGBValueAccessors "accessors" are provided
00119     that support access to RGBValues as a whole, to a selected
00120     color component, or to the luminance value.
00121 
00122     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00123     Namespace: vigra
00124 */
00125 template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX = 1, unsigned int BLUE_IDX = 2>
00126 class RGBValue
00127 : public TinyVector<VALUETYPE, 3>
00128 {
00129     typedef TinyVector<VALUETYPE, 3> Base;
00130 
00131         // inverse mapping from index to color
00132     enum {
00133       IDX0 = (RED_IDX == 0) ? 0 : (GREEN_IDX == 0) ? 1 : 2,
00134       IDX1 = (RED_IDX == 1) ? 0 : (GREEN_IDX == 1) ? 1 : 2,
00135       IDX2 = (RED_IDX == 2) ? 0 : (GREEN_IDX == 2) ? 1 : 2
00136     };
00137 
00138   public:
00139         /** STL-compatible definition of valuetype
00140         */
00141     typedef typename Base::value_type value_type;
00142         /** STL-compatible definition of iterator
00143         */
00144     typedef typename Base::iterator iterator;
00145         /** STL-compatible definition of const iterator
00146         */
00147     typedef typename Base::const_iterator const_iterator;
00148         /** squared norm type (result of squaredManitude())
00149         */
00150     typedef typename Base::SquaredNormType SquaredNormType;
00151         /** norm type (result of magnitude())
00152         */
00153     typedef typename Base::NormType NormType;
00154 
00155     typedef typename Base::reference reference;
00156     typedef typename Base::const_reference const_reference;
00157     typedef typename Base::pointer pointer;
00158     typedef typename Base::const_pointer const_pointer;
00159     typedef typename Base::size_type size_type;
00160     typedef typename Base::difference_type difference_type;
00161     typedef typename Base::scalar_multiplier scalar_multiplier;
00162     typedef typename Base::ReverseCopyTag ReverseCopyTag;
00163 
00164         /** Color index positions
00165         */
00166     enum
00167     {
00168       RedIdx = RED_IDX,
00169       GreenIdx = GREEN_IDX,
00170       BlueIdx = BLUE_IDX
00171     };
00172 
00173         /** Construct from explicit color values.
00174             \a first, \a second, \a third are written in this order,
00175             irrespective of how the color indices are specified.
00176         */
00177     RGBValue(value_type first, value_type second, value_type third)
00178     : Base(first, second, third)
00179     {
00180         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00181     }
00182 
00183         /** Construct gray value.
00184         */
00185     RGBValue(value_type gray)
00186     : Base(gray, gray, gray)
00187     {
00188         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00189     }
00190 
00191         /** Copy from raw memory. The order is preserved,
00192             irrespective of how the color indices are specified.
00193         */
00194     explicit RGBValue(const_pointer i)
00195     : Base(i)
00196     {
00197         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00198     }
00199 
00200         /** Construct by reverse copying from raw memory.
00201         */
00202     RGBValue(const_pointer i, ReverseCopyTag reverse)
00203     : Base(i, reverse)
00204     {
00205         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00206     }
00207 
00208         /** Default constructor (sets all components to 0)
00209         */
00210     RGBValue()
00211     : Base(0, 0, 0)
00212     {
00213         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00214     }
00215 
00216 #if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG)
00217 
00218     RGBValue(RGBValue const & r)
00219     : Base((Base const &)r)
00220     {
00221         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00222     }
00223 
00224     RGBValue & operator=(RGBValue const & r)
00225     {
00226         Base::operator=(r);
00227         return *this;
00228     }
00229 
00230 #endif // TEMPLATE_COPY_CONSTRUCTOR_BUG
00231 
00232         /** Copy constructor.
00233         */
00234     template <class U, unsigned int R, unsigned int G, unsigned int B>
00235     RGBValue(RGBValue<U, R, G, B> const & r)
00236     : Base(detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX0, R, G, B>::res]),
00237            detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX1, R, G, B>::res]),
00238            detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX2, R, G, B>::res]))
00239     {
00240         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00241     }
00242 
00243         /** Copy assignment.
00244         */
00245     template <class U, unsigned int R, unsigned int G, unsigned int B>
00246     RGBValue & operator=(RGBValue<U, R, G, B> const & r)
00247     {
00248         setRed(detail::RequiresExplicitCast<value_type>::cast(r.red()));
00249         setGreen(detail::RequiresExplicitCast<value_type>::cast(r.green()));
00250         setBlue(detail::RequiresExplicitCast<value_type>::cast(r.blue()));
00251         return *this;
00252     }
00253 
00254         /** construct from TinyVector
00255         */
00256     RGBValue(TinyVector<value_type, 3> const & r)
00257     : Base(r)
00258     {
00259         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
00260     }
00261 
00262         /** assign TinyVector.
00263         */
00264     RGBValue & operator=(TinyVector<value_type, 3> const & r)
00265     {
00266         Base::operator=(r);
00267         return *this;
00268     }
00269 
00270         /** Unary negation (construct RGBValue with negative values)
00271         */
00272     RGBValue operator-() const
00273     {
00274         return RGBValue(-(*this)[0], -(*this)[1], -(*this)[2]);
00275     }
00276 
00277         /** Access red component.
00278         */
00279     value_type & red() { return (*this)[RED_IDX]; }
00280 
00281         /** Access green component.
00282         */
00283     value_type & green() { return (*this)[GREEN_IDX]; }
00284 
00285         /** Access blue component.
00286         */
00287     value_type & blue() { return (*this)[BLUE_IDX]; }
00288 
00289         /** Get red component.
00290         */
00291     value_type const & red() const { return (*this)[RED_IDX]; }
00292 
00293         /** Get green component.
00294         */
00295     value_type const & green() const { return (*this)[GREEN_IDX]; }
00296 
00297         /** Get blue component.
00298         */
00299     value_type const & blue() const { return (*this)[BLUE_IDX]; }
00300 
00301         /** Calculate luminance.
00302         */
00303     value_type luminance() const {
00304          return detail::RequiresExplicitCast<value_type>::cast(0.3*red() + 0.59*green() + 0.11*blue()); }
00305 
00306         /** Calculate magnitude.
00307         */
00308     NormType magnitude() const {
00309          return Base::magnitude();
00310     }
00311 
00312         /** Calculate squared magnitude.
00313         */
00314     SquaredNormType squaredMagnitude() const {
00315          return Base::squaredMagnitude();
00316     }
00317 
00318         /** Set red component. The type <TT>V</TT> of the passed
00319             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00320         */
00321     template <class V>
00322     void setRed(V value) { (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
00323 
00324         /** Set green component.The type <TT>V</TT> of the passed
00325             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00326         */
00327     template <class V>
00328     void setGreen(V value) { (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
00329 
00330         /** Set blue component.The type <TT>V</TT> of the passed
00331             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00332         */
00333     template <class V>
00334     void setBlue(V value) { (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
00335 
00336 
00337     template <class V>
00338     void setRGB(V r, V g, V b)
00339     {
00340         (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(r);
00341         (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(g);
00342         (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(b);
00343     }
00344 };
00345 
00346 /********************************************************/
00347 /*                                                      */
00348 /*                     RGBValue Comparison              */
00349 /*                                                      */
00350 /********************************************************/
00351 
00352 /** \addtogroup RGBValueOperators Functions for RGBValue
00353 
00354     \brief Implement basic arithmetic and equality for RGBValue.
00355 
00356     These functions fulfill the requirements of a Linear Algebra.
00357     Return types are determined according to \ref RGBValueTraits.
00358 
00359     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00360     Namespace: vigra
00361     <p>
00362 
00363  */
00364 //@{
00365     /// component-wise equal
00366 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00367           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00368 inline
00369 bool
00370 operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
00371            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00372 {
00373     return (l.red() == r.red()) &&
00374            (l.green() == r.green()) &&
00375            (l.blue() == r.blue());
00376 }
00377 
00378     /// component-wise not equal
00379 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
00380           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
00381 inline
00382 bool
00383 operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
00384            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
00385 {
00386     return (l.red() != r.red()) ||
00387            (l.green() != r.green()) ||
00388            (l.blue() != r.blue());
00389 }
00390 
00391 
00392 //@}
00393 
00394 /********************************************************/
00395 /*                                                      */
00396 /*                      RGBValue-Traits                 */
00397 /*                                                      */
00398 /********************************************************/
00399 
00400 /** \page RGBValueTraits Numeric and Promote Traits of RGBValue
00401     The numeric and promote traits for RGBValues follow
00402     the general specifications for \ref NumericPromotionTraits.
00403     They are implemented in terms of the traits of the basic types by
00404     partial template specialization. Note that PromoteTraits are only defined
00405     for the case that the color indices are the same in both RGBValues.
00406 
00407     \code
00408 
00409     template <class T, unsigned int R, unsigned int G, unsigned int B>
00410     struct NumericTraits<RGBValue<T, R, G, B> >
00411     {
00412         typedef RGBValue<T, R, G, B> Type;
00413         typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
00414         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
00415         typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
00416         typedef T ValueType;
00417 
00418         typedef typename NumericTraits<T>::isIntegral isIntegral;
00419         typedef VigraFalseType isScalar;
00420         typedef typename NumericTraits<T>::isSigned isSigned;
00421 
00422         // etc.
00423     };
00424 
00425     template <class T, unsigned int R, unsigned int G, unsigned int B>
00426     struct NormTraits<RGBValue<T, R, G, B> >
00427     {
00428         typedef RGBValue<T, R, G, B> Type;
00429         typedef typename Type::SquaredNormType    SquaredNormType;
00430         typedef typename Type::NormType           NormType;
00431     };
00432 
00433     template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
00434     struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
00435     {
00436         typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
00437     };
00438 
00439     template <class T, unsigned int R, unsigned int G, unsigned int B>
00440     struct PromoteTraits<RGBValue<T, R, G, B>, double >
00441     {
00442         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
00443     };
00444 
00445     template <class T, unsigned int R, unsigned int G, unsigned int B>
00446     struct PromoteTraits<double, RGBValue<T, R, G, B> >
00447     {
00448         typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
00449     };
00450     \endcode
00451 
00452     <b>\#include</b> <vigra/rgbvalue.hxx><br>
00453     Namespace: vigra
00454 
00455 */
00456 
00457 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
00458 
00459 template <class T, unsigned int R, unsigned int G, unsigned int B>
00460 struct NumericTraits<RGBValue<T, R, G, B> >
00461 {
00462     typedef RGBValue<T, R, G, B> Type;
00463     typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
00464     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
00465     typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
00466     typedef T ValueType;
00467 
00468     typedef typename NumericTraits<T>::isIntegral isIntegral;
00469     typedef VigraFalseType isScalar;
00470     typedef typename NumericTraits<T>::isSigned isSigned;
00471     typedef 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> <vigra/rgbvalue.hxx><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> <vigra/rgbvalue.hxx><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> <vigra/rgbvalue.hxx><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> <vigra/rgbvalue.hxx><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> <vigra/rgbvalue.hxx><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> <vigra/rgbvalue.hxx><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.8.0 (20 Sep 2011)