37 #ifndef VIGRA_RGBVALUE_HXX 
   38 #define VIGRA_RGBVALUE_HXX 
   43 #include "numerictraits.hxx" 
   44 #include "accessor.hxx" 
   45 #include "tinyvector.hxx" 
   46 #include "static_assert.hxx" 
   52 template <
unsigned int I, 
unsigned int R, 
unsigned int G, 
unsigned int B>
 
   53 struct SelectColorIndexRHS;
 
   55 template <
unsigned int R, 
unsigned int G, 
unsigned int B>
 
   56 struct SelectColorIndexRHS<0, R, G, B>
 
   61 template <
unsigned int R, 
unsigned int G, 
unsigned int B>
 
   62 struct SelectColorIndexRHS<1, R, G, B>
 
   67 template <
unsigned int R, 
unsigned int G, 
unsigned int B>
 
   68 struct SelectColorIndexRHS<2, R, G, B>
 
   77 template <
unsigned int R, 
unsigned int G, 
unsigned int B>
 
   78 struct RGBValue_bad_color_indices
 
   79 : staticAssert::AssertBool<(R < 3 && G < 3 && B < 3 &&
 
   80                            ((1 << R) + (1 << G) + (1 << B) == 7))>
 
  125 template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX = 1, unsigned int BLUE_IDX = 2>
 
  127 : public TinyVector<VALUETYPE, 3>
 
  129     typedef TinyVector<VALUETYPE, 3> Base;
 
  133       IDX0 = (RED_IDX == 0) ? 0 : (GREEN_IDX == 0) ? 1 : 2,
 
  134       IDX1 = (RED_IDX == 1) ? 0 : (GREEN_IDX == 1) ? 1 : 2,
 
  135       IDX2 = (RED_IDX == 2) ? 0 : (GREEN_IDX == 2) ? 1 : 2
 
  141     typedef typename Base::value_type value_type;
 
  144     typedef typename Base::iterator iterator;
 
  147     typedef typename Base::const_iterator const_iterator;
 
  150     typedef typename Base::SquaredNormType SquaredNormType;
 
  153     typedef typename Base::NormType NormType;
 
  155     typedef typename Base::reference reference;
 
  156     typedef typename Base::const_reference const_reference;
 
  157     typedef typename Base::pointer pointer;
 
  158     typedef typename Base::const_pointer const_pointer;
 
  159     typedef typename Base::size_type size_type;
 
  160     typedef typename Base::difference_type difference_type;
 
  161     typedef typename Base::scalar_multiplier scalar_multiplier;
 
  168       GreenIdx = GREEN_IDX,
 
  176     RGBValue(value_type first, value_type second, value_type third)
 
  177     : Base(first, second, third)
 
  179         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  184     RGBValue(value_type gray)
 
  185     : Base(gray, gray, gray)
 
  187         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  193     explicit RGBValue(const_pointer i)
 
  196         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  201     RGBValue(const_pointer i, ReverseCopyTag reverse)
 
  204         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  212         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  215 #if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG)
 
  217     RGBValue(RGBValue const & r)
 
  218     : Base((Base const &)r)
 
  220         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  223     RGBValue & operator=(RGBValue const & r)
 
  233     template <class U, unsigned int R, unsigned int G, unsigned int B>
 
  234     RGBValue(RGBValue<U, R, G, B> const & r)
 
  235     : Base(detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX0, R, G, B>::res]),
 
  236            detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX1, R, G, B>::res]),
 
  237            detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX2, R, G, B>::res]))
 
  239         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  244     template <class U, unsigned int R, unsigned int G, unsigned int B>
 
  245     RGBValue & operator=(RGBValue<U, R, G, B> const & r)
 
  247         setRed(detail::RequiresExplicitCast<value_type>::cast(r.red()));
 
  248         setGreen(detail::RequiresExplicitCast<value_type>::cast(r.green()));
 
  249         setBlue(detail::RequiresExplicitCast<value_type>::cast(r.blue()));
 
  255     RGBValue(TinyVector<value_type, 3> const & r)
 
  258         VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
 
  263     RGBValue & operator=(TinyVector<value_type, 3> const & r)
 
  271     RGBValue operator-() const
 
  273         return RGBValue(-(*this)[0], -(*this)[1], -(*this)[2]);
 
  278     value_type & red() { return (*this)[RED_IDX]; }
 
  282     value_type & green() { return (*this)[GREEN_IDX]; }
 
  286     value_type & blue() { return (*this)[BLUE_IDX]; }
 
  290     value_type const & red() const { return (*this)[RED_IDX]; }
 
  294     value_type const & green() const { return (*this)[GREEN_IDX]; }
 
  298     value_type const & blue() const { return (*this)[BLUE_IDX]; }
 
  302     value_type luminance() const {
 
  303          return detail::RequiresExplicitCast<value_type>::cast(0.3*red() + 0.59*green() + 0.11*blue()); }
 
  307     NormType magnitude() const {
 
  308          return Base::magnitude();
 
  313     SquaredNormType squaredMagnitude() const {
 
  314          return Base::squaredMagnitude();
 
  321     void setRed(V value) { (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
 
  327     void setGreen(V value) { (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
 
  333     void setBlue(V value) { (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
 
  337     void setRGB(V r, V g, V b)
 
  339         (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(r);
 
  340         (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(g);
 
  341         (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(b);
 
  365 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  366           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  369 operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
 
  370            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
 
  372     return (l.red() == r.red()) &&
 
  373            (l.green() == r.green()) &&
 
  374            (l.blue() == r.blue());
 
  378 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  379           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  382 operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
 
  383            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
 
  385     return (l.red() != r.red()) ||
 
  386            (l.green() != r.green()) ||
 
  387            (l.blue() != r.blue());
 
  390 template <class V, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  391                    unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  394 closeAtTolerance(RGBValue<V, RIDX1, GIDX1, BIDX1> const & l,
 
  395                  RGBValue<V, RIDX2, GIDX2, BIDX2> const & r,
 
  396                  V epsilon = NumericTraits<V>::epsilon())
 
  398     return closeAtTolerance(l.red(), r.red(), epsilon) &&
 
  399            closeAtTolerance(l.green(), r.green(), epsilon) &&
 
  400            closeAtTolerance(l.blue(), r.blue(), epsilon);
 
  469 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
 
  471 template <class T, unsigned int R, unsigned int G, unsigned int B>
 
  472 struct NumericTraits<RGBValue<T, R, G, B> >
 
  474     typedef RGBValue<T, R, G, B> Type;
 
  475     typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
 
  476     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
 
  477     typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
 
  480     typedef typename NumericTraits<T>::isIntegral isIntegral;
 
  481     typedef VigraFalseType isScalar;
 
  482     typedef typename NumericTraits<T>::isSigned isSigned;
 
  483     typedef VigraTrueType isOrdered;
 
  484     typedef VigraFalseType isComplex;
 
  488         return Type(NumericTraits<T>::zero());
 
  492         return Type(NumericTraits<T>::one());
 
  494     static Type nonZero()
 
  496         return Type(NumericTraits<T>::nonZero());
 
  501         return Type(NumericTraits<T>::min());
 
  505         return Type(NumericTraits<T>::max());
 
  508     static Promote toPromote(Type const & v)
 
  512     static RealPromote toRealPromote(Type const & v)
 
  514         return RealPromote(v);
 
  516     static Type fromPromote(Promote const & v)
 
  518       return Type(NumericTraits<T>::fromPromote(v.red()),
 
  519                   NumericTraits<T>::fromPromote(v.green()),
 
  520                   NumericTraits<T>::fromPromote(v.blue()));
 
  522     static Type fromRealPromote(RealPromote const & v)
 
  524         return Type(NumericTraits<T>::fromRealPromote(v.red()),
 
  525                     NumericTraits<T>::fromRealPromote(v.green()),
 
  526                     NumericTraits<T>::fromRealPromote(v.blue()));
 
  530 template <class T, unsigned int R, unsigned int G, unsigned int B>
 
  531 struct NormTraits<RGBValue<T, R, G, B> >
 
  533     typedef RGBValue<T, R, G, B> Type;
 
  534     typedef typename Type::SquaredNormType    SquaredNormType;
 
  535     typedef typename Type::NormType           NormType;
 
  538 template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
 
  539 struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
 
  541     typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
 
  544 template <class T, unsigned int R, unsigned int G, unsigned int B>
 
  545 struct PromoteTraits<RGBValue<T, R, G, B>, double >
 
  547     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
 
  550 template <class T, unsigned int R, unsigned int G, unsigned int B>
 
  551 struct PromoteTraits<double, RGBValue<T, R, G, B> >
 
  553     typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
 
  556 template<class T, unsigned int R, unsigned int G, unsigned int B>
 
  557 struct CanSkipInitialization<RGBValue<T, R, G, B> >
 
  559     typedef typename CanSkipInitialization<T>::type type;
 
  560     static const bool value = type::asBool;
 
  566 #define RGBVALUE_NUMTRAITS(T) \
 
  568 struct NumericTraits<RGBValue<T, 0, 1, 2> >\
 
  570     typedef RGBValue<T> Type; \
 
  571     typedef RGBValue<NumericTraits<T>::Promote> Promote; \
 
  572     typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \
 
  573     typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \
 
  574     typedef T ValueType; \
 
  576     typedef NumericTraits<T>::isIntegral isIntegral; \
 
  577     typedef VigraFalseType isScalar; \
 
  578     typedef NumericTraits<T>::isSigned isSigned; \
 
  579     typedef VigraFalseType isOrdered; \
 
  580     typedef VigraFalseType isComplex; \
 
  582     static RGBValue<T> zero() { \
 
  583         return RGBValue<T>(NumericTraits<T>::zero()); \
 
  585     static RGBValue<T> one() { \
 
  586         return RGBValue<T>(NumericTraits<T>::one()); \
 
  588     static RGBValue<T> nonZero() { \
 
  589         return RGBValue<T>(NumericTraits<T>::nonZero()); \
 
  592     static Promote toPromote(RGBValue<T> const & v) { \
 
  595     static RealPromote toRealPromote(RGBValue<T> const & v) { \
 
  596         return RealPromote(v); \
 
  598     static RGBValue<T> fromPromote(Promote const & v) { \
 
  600         RGBValue<T>::iterator d = res.begin();\
 
  601         Promote::const_iterator s = v.begin();\
 
  602         for(; d != res.end(); ++d, ++s)\
 
  603             *d = NumericTraits<T>::fromPromote(*s);\
 
  606     static RGBValue<T> fromRealPromote(RealPromote const & v) {\
 
  608         RGBValue<T>::iterator d = res.begin();\
 
  609         RealPromote::const_iterator s = v.begin();\
 
  610         for(; d != res.end(); ++d, ++s)\
 
  611             *d = NumericTraits<T>::fromRealPromote(*s);\
 
  616 struct NormTraits<RGBValue<T, 0, 1, 2> >\
 
  618     typedef RGBValue<T> Type;\
 
  619     typedef Type::SquaredNormType           SquaredNormType; \
 
  620     typedef Type::NormType NormType; \
 
  623 #define RGBVALUE_PROMTRAITS1(type1) \
 
  625 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \
 
  627     typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \
 
  628     static Promote toPromote(RGBValue<type1> const & v) { \
 
  629         return static_cast<Promote>(v); } \
 
  632 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \
 
  634     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
 
  637 struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \
 
  639     typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
 
  642 #define RGBVALUE_PROMTRAITS2(type1, type2) \
 
  644 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \
 
  646     typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \
 
  647     static Promote toPromote(RGBValue<type1> const & v) { \
 
  648         return static_cast<Promote>(v); } \
 
  649     static Promote toPromote(RGBValue<type2> const & v) { \
 
  650         return static_cast<Promote>(v); } \
 
  653 RGBVALUE_NUMTRAITS(unsigned char)
 
  654 RGBVALUE_NUMTRAITS(int)
 
  655 RGBVALUE_NUMTRAITS(float)
 
  656 RGBVALUE_NUMTRAITS(double)
 
  657 RGBVALUE_PROMTRAITS1(unsigned char)
 
  658 RGBVALUE_PROMTRAITS1(int)
 
  659 RGBVALUE_PROMTRAITS1(float)
 
  660 RGBVALUE_PROMTRAITS1(double)
 
  661 RGBVALUE_PROMTRAITS2(float, unsigned char)
 
  662 RGBVALUE_PROMTRAITS2(unsigned char, float)
 
  663 RGBVALUE_PROMTRAITS2(int, unsigned char)
 
  664 RGBVALUE_PROMTRAITS2(unsigned char, int)
 
  665 RGBVALUE_PROMTRAITS2(int, float)
 
  666 RGBVALUE_PROMTRAITS2(float, int)
 
  667 RGBVALUE_PROMTRAITS2(double, unsigned char)
 
  668 RGBVALUE_PROMTRAITS2(unsigned char, double)
 
  669 RGBVALUE_PROMTRAITS2(int, double)
 
  670 RGBVALUE_PROMTRAITS2(double, int)
 
  671 RGBVALUE_PROMTRAITS2(double, float)
 
  672 RGBVALUE_PROMTRAITS2(float, double)
 
  674 #undef RGBVALUE_NUMTRAITS
 
  675 #undef RGBVALUE_PROMTRAITS1
 
  676 #undef RGBVALUE_PROMTRAITS2
 
  691 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  692           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  694 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
 
  695 operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
 
  696            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
 
  699     l.green() += r.green();
 
  700     l.blue() += r.blue();
 
  705 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  706           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  708 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
 
  709 operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
 
  710            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
 
  713     l.green() -= r.green();
 
  714     l.blue() -= r.blue();
 
  719 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  720           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  722 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
 
  723 operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
 
  724            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
 
  726     l.red() = V1(l.red() * r.red());
 
  727     l.green() = V1(l.green() * r.green());
 
  728     l.blue() = V1(l.blue() * r.blue());
 
  733 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  735 RGBValue<V, RIDX, GIDX, BIDX> &
 
  736 operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
 
  738     l.red() = V(l.red() * r);
 
  739     l.green() = V(l.green() * r);
 
  740     l.blue() = V(l.blue() * r);
 
  745 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  746           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  748 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
 
  749 operator/=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
 
  750            RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
 
  752     l.red() = V1(l.red() / r.red());
 
  753     l.green() = V1(l.green() / r.green());
 
  754     l.blue() = V1(l.blue() / r.blue());
 
  759 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  761 RGBValue<V, RIDX, GIDX, BIDX> &
 
  762 operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
 
  764     l.red() = V(l.red() / r);
 
  765     l.green() = V(l.green() / r);
 
  766     l.blue() = V(l.blue() / r);
 
  770 using VIGRA_CSTD::abs;
 
  773 template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  775 RGBValue<T, RIDX, GIDX, BIDX>
 
  776 abs(RGBValue<T, RIDX, GIDX, BIDX> const & v)
 
  778   return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v.blue()));
 
  782 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
 
  784 typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  785                        RGBValue<V2, R, G, B> >::Promote
 
  786 operator+(RGBValue<V1, R, G, B> const & r1,
 
  787           RGBValue<V2, R, G, B> const & r2)
 
  789     typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  790                            RGBValue<V2, R, G, B> >::Promote res(r1);
 
  798 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
 
  800 typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  801                        RGBValue<V2, R, G, B> >::Promote
 
  802 operator-(RGBValue<V1, R, G, B> const & r1,
 
  803           RGBValue<V2, R, G, B> const & r2)
 
  805     typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  806                            RGBValue<V2, R, G, B> >::Promote res(r1);
 
  814 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
 
  816 typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  817                        RGBValue<V2, R, G, B> >::Promote
 
  818 operator*(RGBValue<V1, R, G, B> const & r1,
 
  819           RGBValue<V2, R, G, B> const & r2)
 
  821     typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  822                            RGBValue<V2, R, G, B> >::Promote res(r1);
 
  830 template <class V, unsigned int R, unsigned int G, unsigned int B>
 
  832 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
 
  833 operator*(double v, RGBValue<V, R, G, B> const & r)
 
  835     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
 
  843 template <class V, unsigned int R, unsigned int G, unsigned int B>
 
  845 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
 
  846 operator*(RGBValue<V, R, G, B> const & r, double v)
 
  848     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
 
  856 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
 
  858 typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  859                        RGBValue<V2, R, G, B> >::Promote
 
  860 operator/(RGBValue<V1, R, G, B> const & r1,
 
  861           RGBValue<V2, R, G, B> const & r2)
 
  863     typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  864                            RGBValue<V2, R, G, B> >::Promote res(r1);
 
  872 template <class V, unsigned int R, unsigned int G, unsigned int B>
 
  874 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
 
  875 operator/(RGBValue<V, R, G, B> const & r, double v)
 
  877     typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
 
  885 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
 
  887 typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  888                        RGBValue<V2, R, G, B> >::Promote
 
  889 cross(RGBValue<V1, R, G, B> const & r1,
 
  890       RGBValue<V2, R, G, B> const & r2)
 
  892     typedef typename PromoteTraits<RGBValue<V1, R, G, B>,
 
  893                                    RGBValue<V2, R, G, B> >::Promote
 
  896     return  Res(r1.green()*r2.blue() - r1.blue()*r2.green(),
 
  897                 r1.blue()*r2.red() - r1.red()*r2.blue(),
 
  898                 r1.red()*r2.green() - r1.green()*r2.red());
 
  902 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
 
  903           class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
 
  905 typename PromoteTraits<V1, V2>::Promote
 
  906 dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1,
 
  907     RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2)
 
  909     return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue();
 
  912 using VIGRA_CSTD::ceil;
 
  916 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  918 RGBValue<V, RIDX, GIDX, BIDX>
 
  919 ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r)
 
  921     return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()),
 
  926 using VIGRA_CSTD::floor;
 
  930 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  932 RGBValue<V, RIDX, GIDX, BIDX>
 
  933 floor(RGBValue<V, RIDX, GIDX, BIDX> const & r)
 
  935     return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()),
 
  941 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  943 RGBValue<V, RIDX, GIDX, BIDX>
 
  944 min(RGBValue<V, RIDX, GIDX, BIDX> const & l,
 
  945     RGBValue<V, RIDX, GIDX, BIDX> const & r)
 
  947     typedef typename detail::LoopType<3>::type ltype;
 
  948     RGBValue<V, RIDX, GIDX, BIDX> res(l);
 
  949     ltype::min(res.begin(), r.begin());
 
  953 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
 
  955 RGBValue<V, RIDX, GIDX, BIDX>
 
  956 max(RGBValue<V, RIDX, GIDX, BIDX> const & l,
 
  957     RGBValue<V, RIDX, GIDX, BIDX> const & r)
 
  959     typedef typename detail::LoopType<3>::type ltype;
 
  960     RGBValue<V, RIDX, GIDX, BIDX> res(l);
 
  961     ltype::max(res.begin(), r.begin());
 
  984 template <class RGBVALUE>
 
  986 : public VectorAccessor<RGBVALUE>
 
  990     typedef typename RGBVALUE::value_type component_type;
 
  994     template <class RGBIterator>
 
  995     component_type const & red(RGBIterator const & rgb) const
 
 1000     template <class V, class RGBIterator>
 
 1001     void setRGB(V r, V g, V b, RGBIterator const & rgb) const
 
 1003         (*rgb).setRGB( r, g, b );
 
 1010     template <class V, class RGBIterator>
 
 1011     void setRed(V value, RGBIterator const & rgb) const
 
 1013         (*rgb).setRed(value);
 
 1018     template <class RGBIterator, class DIFFERENCE>
 
 1019     component_type const & red(RGBIterator const & rgb, DIFFERENCE diff) const
 
 1021         return rgb[diff].red();
 
 1027     template <class V, class RGBIterator, class DIFFERENCE>
 
 1028     void setRed(V value, RGBIterator const & rgb, DIFFERENCE diff) const
 
 1030         rgb[diff].setRed(value);
 
 1035     template <class RGBIterator>
 
 1036     component_type const & green(RGBIterator const & rgb) const
 
 1038         return (*rgb).green();
 
 1044     template <class V, class RGBIterator>
 
 1045     void setGreen(V value, RGBIterator const & rgb) const
 
 1047         (*rgb).setGreen(value);
 
 1052     template <class RGBIterator, class DIFFERENCE>
 
 1053     component_type const & green(RGBIterator const & rgb, DIFFERENCE d) const
 
 1055         return rgb[d].green();
 
 1061     template <class V, class RGBIterator, class DIFFERENCE>
 
 1062     void setGreen(V value, RGBIterator const & rgb, DIFFERENCE d) const
 
 1064         rgb[d].setGreen(value);
 
 1069     template <class RGBIterator>
 
 1070     component_type const & blue(RGBIterator const & rgb) const
 
 1072         return (*rgb).blue();
 
 1078     template <class V, class RGBIterator>
 
 1079     void setBlue(V value, RGBIterator const & rgb) const
 
 1081         (*rgb).setBlue(value);
 
 1086     template <class RGBIterator, class DIFFERENCE>
 
 1087     component_type const & blue(RGBIterator const & rgb, DIFFERENCE d) const
 
 1089         return rgb[d].blue();
 
 1095     template <class V, class RGBIterator, class DIFFERENCE>
 
 1096     void setBlue(V value, RGBIterator const & rgb, DIFFERENCE d) const
 
 1098         rgb[d].setBlue(value);
 
 1115 template <class RGBVALUE>
 
 1119     typedef typename RGBVALUE::value_type value_type;
 
 1123     template <class ITERATOR>
 
 1124     value_type const & operator()(ITERATOR const & i) const {
 
 1130     template <class ITERATOR, class DIFFERENCE>
 
 1131     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
 
 1139     template <class V, class ITERATOR>
 
 1140     void set(V value, ITERATOR const & i) const {
 
 1148     template <class V, class ITERATOR, class DIFFERENCE>
 
 1149     void set(V value, ITERATOR const & i, DIFFERENCE d) const
 
 1166 template <class RGBVALUE>
 
 1170     typedef typename RGBVALUE::value_type value_type;
 
 1174     template <class ITERATOR>
 
 1175     value_type const & operator()(ITERATOR const & i) const {
 
 1176         return (*i).green();
 
 1181     template <class ITERATOR, class DIFFERENCE>
 
 1182     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
 
 1184         return i[d].green();
 
 1190     template <class V, class ITERATOR>
 
 1191     void set(V value, ITERATOR const & i) const {
 
 1192         (*i).setGreen(value);
 
 1199     template <class V, class ITERATOR, class DIFFERENCE>
 
 1200     void set(V value, ITERATOR const & i, DIFFERENCE d) const
 
 1202         i[d].setGreen(value);
 
 1217 template <class RGBVALUE>
 
 1221     typedef typename RGBVALUE::value_type value_type;
 
 1225     template <class ITERATOR>
 
 1226     value_type const & operator()(ITERATOR const & i) const {
 
 1232     template <class ITERATOR, class DIFFERENCE>
 
 1233     value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
 
 1241     template <class V, class ITERATOR>
 
 1242     void set(V value, ITERATOR const & i) const {
 
 1243         (*i).setBlue(value);
 
 1250     template <class V, class ITERATOR, class DIFFERENCE>
 
 1251     void set(V value, ITERATOR const & i, DIFFERENCE d) const
 
 1253         i[d].setBlue(value);
 
 1268 template <class RGBVALUE>
 
 1269 class RGBToGrayAccessor
 
 1272     typedef typename RGBVALUE::value_type value_type;
 
 1276     template <class ITERATOR>
 
 1277     value_type operator()(ITERATOR const & i) const {
 
 1278                 return (*i).luminance(); }
 
 1282     template <class ITERATOR, class DIFFERENCE>
 
 1283     value_type operator()(ITERATOR const & i, DIFFERENCE d) const
 
 1285         return i[d].luminance();
 
 1302 template <class VALUETYPE>
 
 1303 class GrayToRGBAccessor
 
 1306      typedef typename vigra::RGBValue<VALUETYPE> value_type;
 
 1310      template <class ITERATOR>
 
 1311      value_type operator()(ITERATOR const & i) const {
 
 1312                  return value_type(*i,*i,*i); }
 
 1316      template <class ITERATOR, class DIFFERENCE>
 
 1317      value_type operator()(ITERATOR const & i, DIFFERENCE d) const
 
 1319          return value_type(i[d],i[d],i[d]);