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