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