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