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

details vigra/rgbvalue.hxx VIGRA

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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)