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;
162 typedef typename Base::ReverseCopyTag ReverseCopyTag;
169 GreenIdx = GREEN_IDX,
177 RGBValue(value_type first, value_type second, value_type third)
178 : Base(first, second, third)
180 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
185 RGBValue(value_type gray)
186 : Base(gray, gray, gray)
188 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
194 explicit RGBValue(const_pointer i)
197 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
202 RGBValue(const_pointer i, ReverseCopyTag reverse)
205 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
213 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
216 #if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG)
218 RGBValue(RGBValue const & r)
219 : Base((Base const &)r)
221 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
224 RGBValue & operator=(RGBValue const & r)
234 template <class U, unsigned int R, unsigned int G, unsigned int B>
235 RGBValue(RGBValue<U, R, G, B> const & r)
236 : Base(detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX0, R, G, B>::res]),
237 detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX1, R, G, B>::res]),
238 detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX2, R, G, B>::res]))
240 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
245 template <class U, unsigned int R, unsigned int G, unsigned int B>
246 RGBValue & operator=(RGBValue<U, R, G, B> const & r)
248 setRed(detail::RequiresExplicitCast<value_type>::cast(r.red()));
249 setGreen(detail::RequiresExplicitCast<value_type>::cast(r.green()));
250 setBlue(detail::RequiresExplicitCast<value_type>::cast(r.blue()));
256 RGBValue(TinyVector<value_type, 3> const & r)
259 VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
264 RGBValue & operator=(TinyVector<value_type, 3> const & r)
272 RGBValue operator-() const
274 return RGBValue(-(*this)[0], -(*this)[1], -(*this)[2]);
279 value_type & red() { return (*this)[RED_IDX]; }
283 value_type & green() { return (*this)[GREEN_IDX]; }
287 value_type & blue() { return (*this)[BLUE_IDX]; }
291 value_type const & red() const { return (*this)[RED_IDX]; }
295 value_type const & green() const { return (*this)[GREEN_IDX]; }
299 value_type const & blue() const { return (*this)[BLUE_IDX]; }
303 value_type luminance() const {
304 return detail::RequiresExplicitCast<value_type>::cast(0.3*red() + 0.59*green() + 0.11*blue()); }
308 NormType magnitude() const {
309 return Base::magnitude();
314 SquaredNormType squaredMagnitude() const {
315 return Base::squaredMagnitude();
322 void setRed(V value) { (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
328 void setGreen(V value) { (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
334 void setBlue(V value) { (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
338 void setRGB(V r, V g, V b)
340 (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(r);
341 (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(g);
342 (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(b);
366 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
367 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
370 operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
371 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
373 return (l.red() == r.red()) &&
374 (l.green() == r.green()) &&
375 (l.blue() == r.blue());
379 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
380 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
383 operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
384 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
386 return (l.red() != r.red()) ||
387 (l.green() != r.green()) ||
388 (l.blue() != r.blue());
391 template <class V, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
392 unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
395 closeAtTolerance(RGBValue<V, RIDX1, GIDX1, BIDX1> const & l,
396 RGBValue<V, RIDX2, GIDX2, BIDX2> const & r,
397 V epsilon = NumericTraits<V>::epsilon())
399 return closeAtTolerance(l.red(), r.red(), epsilon) &&
400 closeAtTolerance(l.green(), r.green(), epsilon) &&
401 closeAtTolerance(l.blue(), r.blue(), epsilon);
470 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
472 template <class T, unsigned int R, unsigned int G, unsigned int B>
473 struct NumericTraits<RGBValue<T, R, G, B> >
475 typedef RGBValue<T, R, G, B> Type;
476 typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
477 typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
478 typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
481 typedef typename NumericTraits<T>::isIntegral isIntegral;
482 typedef VigraFalseType isScalar;
483 typedef typename NumericTraits<T>::isSigned isSigned;
484 typedef VigraTrueType isOrdered;
485 typedef VigraFalseType isComplex;
489 return Type(NumericTraits<T>::zero());
493 return Type(NumericTraits<T>::one());
495 static Type nonZero()
497 return Type(NumericTraits<T>::nonZero());
502 return Type(NumericTraits<T>::min());
506 return Type(NumericTraits<T>::max());
509 static Promote toPromote(Type const & v)
513 static RealPromote toRealPromote(Type const & v)
515 return RealPromote(v);
517 static Type fromPromote(Promote const & v)
519 return Type(NumericTraits<T>::fromPromote(v.red()),
520 NumericTraits<T>::fromPromote(v.green()),
521 NumericTraits<T>::fromPromote(v.blue()));
523 static Type fromRealPromote(RealPromote const & v)
525 return Type(NumericTraits<T>::fromRealPromote(v.red()),
526 NumericTraits<T>::fromRealPromote(v.green()),
527 NumericTraits<T>::fromRealPromote(v.blue()));
531 template <class T, unsigned int R, unsigned int G, unsigned int B>
532 struct NormTraits<RGBValue<T, R, G, B> >
534 typedef RGBValue<T, R, G, B> Type;
535 typedef typename Type::SquaredNormType SquaredNormType;
536 typedef typename Type::NormType NormType;
539 template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
540 struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
542 typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
545 template <class T, unsigned int R, unsigned int G, unsigned int B>
546 struct PromoteTraits<RGBValue<T, R, G, B>, double >
548 typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
551 template <class T, unsigned int R, unsigned int G, unsigned int B>
552 struct PromoteTraits<double, RGBValue<T, R, G, B> >
554 typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
557 template<class T, unsigned int R, unsigned int G, unsigned int B>
558 struct CanSkipInitialization<RGBValue<T, R, G, B> >
560 typedef typename CanSkipInitialization<T>::type type;
561 static const bool value = type::asBool;
567 #define RGBVALUE_NUMTRAITS(T) \
569 struct NumericTraits<RGBValue<T, 0, 1, 2> >\
571 typedef RGBValue<T> Type; \
572 typedef RGBValue<NumericTraits<T>::Promote> Promote; \
573 typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \
574 typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \
575 typedef T ValueType; \
577 typedef NumericTraits<T>::isIntegral isIntegral; \
578 typedef VigraFalseType isScalar; \
579 typedef NumericTraits<T>::isSigned isSigned; \
580 typedef VigraFalseType isOrdered; \
581 typedef VigraFalseType isComplex; \
583 static RGBValue<T> zero() { \
584 return RGBValue<T>(NumericTraits<T>::zero()); \
586 static RGBValue<T> one() { \
587 return RGBValue<T>(NumericTraits<T>::one()); \
589 static RGBValue<T> nonZero() { \
590 return RGBValue<T>(NumericTraits<T>::nonZero()); \
593 static Promote toPromote(RGBValue<T> const & v) { \
596 static RealPromote toRealPromote(RGBValue<T> const & v) { \
597 return RealPromote(v); \
599 static RGBValue<T> fromPromote(Promote const & v) { \
601 RGBValue<T>::iterator d = res.begin();\
602 Promote::const_iterator s = v.begin();\
603 for(; d != res.end(); ++d, ++s)\
604 *d = NumericTraits<T>::fromPromote(*s);\
607 static RGBValue<T> fromRealPromote(RealPromote const & v) {\
609 RGBValue<T>::iterator d = res.begin();\
610 RealPromote::const_iterator s = v.begin();\
611 for(; d != res.end(); ++d, ++s)\
612 *d = NumericTraits<T>::fromRealPromote(*s);\
617 struct NormTraits<RGBValue<T, 0, 1, 2> >\
619 typedef RGBValue<T> Type;\
620 typedef Type::SquaredNormType SquaredNormType; \
621 typedef Type::NormType NormType; \
624 #define RGBVALUE_PROMTRAITS1(type1) \
626 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \
628 typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \
629 static Promote toPromote(RGBValue<type1> const & v) { \
630 return static_cast<Promote>(v); } \
633 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \
635 typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
638 struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \
640 typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
643 #define RGBVALUE_PROMTRAITS2(type1, type2) \
645 struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \
647 typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \
648 static Promote toPromote(RGBValue<type1> const & v) { \
649 return static_cast<Promote>(v); } \
650 static Promote toPromote(RGBValue<type2> const & v) { \
651 return static_cast<Promote>(v); } \
654 RGBVALUE_NUMTRAITS(unsigned char)
655 RGBVALUE_NUMTRAITS(int)
656 RGBVALUE_NUMTRAITS(float)
657 RGBVALUE_NUMTRAITS(double)
658 RGBVALUE_PROMTRAITS1(unsigned char)
659 RGBVALUE_PROMTRAITS1(int)
660 RGBVALUE_PROMTRAITS1(float)
661 RGBVALUE_PROMTRAITS1(double)
662 RGBVALUE_PROMTRAITS2(float, unsigned char)
663 RGBVALUE_PROMTRAITS2(unsigned char, float)
664 RGBVALUE_PROMTRAITS2(int, unsigned char)
665 RGBVALUE_PROMTRAITS2(unsigned char, int)
666 RGBVALUE_PROMTRAITS2(int, float)
667 RGBVALUE_PROMTRAITS2(float, int)
668 RGBVALUE_PROMTRAITS2(double, unsigned char)
669 RGBVALUE_PROMTRAITS2(unsigned char, double)
670 RGBVALUE_PROMTRAITS2(int, double)
671 RGBVALUE_PROMTRAITS2(double, int)
672 RGBVALUE_PROMTRAITS2(double, float)
673 RGBVALUE_PROMTRAITS2(float, double)
675 #undef RGBVALUE_NUMTRAITS
676 #undef RGBVALUE_PROMTRAITS1
677 #undef RGBVALUE_PROMTRAITS2
692 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
693 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
695 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
696 operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
697 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
700 l.green() += r.green();
701 l.blue() += r.blue();
706 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
707 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
709 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
710 operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
711 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
714 l.green() -= r.green();
715 l.blue() -= r.blue();
720 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
721 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
723 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
724 operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
725 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
727 l.red() = V1(l.red() * r.red());
728 l.green() = V1(l.green() * r.green());
729 l.blue() = V1(l.blue() * r.blue());
734 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
736 RGBValue<V, RIDX, GIDX, BIDX> &
737 operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
739 l.red() = V(l.red() * r);
740 l.green() = V(l.green() * r);
741 l.blue() = V(l.blue() * r);
746 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
747 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
749 RGBValue<V1, RIDX1, GIDX1, BIDX1> &
750 operator/=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
751 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
753 l.red() = V1(l.red() / r.red());
754 l.green() = V1(l.green() / r.green());
755 l.blue() = V1(l.blue() / r.blue());
760 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
762 RGBValue<V, RIDX, GIDX, BIDX> &
763 operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
765 l.red() = V(l.red() / r);
766 l.green() = V(l.green() / r);
767 l.blue() = V(l.blue() / r);
771 using VIGRA_CSTD::abs;
774 template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
776 RGBValue<T, RIDX, GIDX, BIDX>
777 abs(RGBValue<T, RIDX, GIDX, BIDX> const & v)
779 return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v.blue()));
783 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
785 typename PromoteTraits<RGBValue<V1, R, G, B>,
786 RGBValue<V2, R, G, B> >::Promote
787 operator+(RGBValue<V1, R, G, B> const & r1,
788 RGBValue<V2, R, G, B> const & r2)
790 typename PromoteTraits<RGBValue<V1, R, G, B>,
791 RGBValue<V2, R, G, B> >::Promote res(r1);
799 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
801 typename PromoteTraits<RGBValue<V1, R, G, B>,
802 RGBValue<V2, R, G, B> >::Promote
803 operator-(RGBValue<V1, R, G, B> const & r1,
804 RGBValue<V2, R, G, B> const & r2)
806 typename PromoteTraits<RGBValue<V1, R, G, B>,
807 RGBValue<V2, R, G, B> >::Promote res(r1);
815 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
817 typename PromoteTraits<RGBValue<V1, R, G, B>,
818 RGBValue<V2, R, G, B> >::Promote
819 operator*(RGBValue<V1, R, G, B> const & r1,
820 RGBValue<V2, R, G, B> const & r2)
822 typename PromoteTraits<RGBValue<V1, R, G, B>,
823 RGBValue<V2, R, G, B> >::Promote res(r1);
831 template <class V, unsigned int R, unsigned int G, unsigned int B>
833 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
834 operator*(double v, RGBValue<V, R, G, B> const & r)
836 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
844 template <class V, unsigned int R, unsigned int G, unsigned int B>
846 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
847 operator*(RGBValue<V, R, G, B> const & r, double v)
849 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
857 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
859 typename PromoteTraits<RGBValue<V1, R, G, B>,
860 RGBValue<V2, R, G, B> >::Promote
861 operator/(RGBValue<V1, R, G, B> const & r1,
862 RGBValue<V2, R, G, B> const & r2)
864 typename PromoteTraits<RGBValue<V1, R, G, B>,
865 RGBValue<V2, R, G, B> >::Promote res(r1);
873 template <class V, unsigned int R, unsigned int G, unsigned int B>
875 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
876 operator/(RGBValue<V, R, G, B> const & r, double v)
878 typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
886 template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
888 typename PromoteTraits<RGBValue<V1, R, G, B>,
889 RGBValue<V2, R, G, B> >::Promote
890 cross(RGBValue<V1, R, G, B> const & r1,
891 RGBValue<V2, R, G, B> const & r2)
893 typedef typename PromoteTraits<RGBValue<V1, R, G, B>,
894 RGBValue<V2, R, G, B> >::Promote
897 return Res(r1.green()*r2.blue() - r1.blue()*r2.green(),
898 r1.blue()*r2.red() - r1.red()*r2.blue(),
899 r1.red()*r2.green() - r1.green()*r2.red());
903 template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
904 class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
906 typename PromoteTraits<V1, V2>::Promote
907 dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1,
908 RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2)
910 return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue();
913 using VIGRA_CSTD::ceil;
917 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
919 RGBValue<V, RIDX, GIDX, BIDX>
920 ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r)
922 return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()),
927 using VIGRA_CSTD::floor;
931 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
933 RGBValue<V, RIDX, GIDX, BIDX>
934 floor(RGBValue<V, RIDX, GIDX, BIDX> const & r)
936 return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()),
942 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
944 RGBValue<V, RIDX, GIDX, BIDX>
945 min(RGBValue<V, RIDX, GIDX, BIDX> const & l,
946 RGBValue<V, RIDX, GIDX, BIDX> const & r)
948 typedef typename detail::LoopType<3>::type ltype;
949 RGBValue<V, RIDX, GIDX, BIDX> res(l);
950 ltype::min(res.begin(), r.begin());
954 template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
956 RGBValue<V, RIDX, GIDX, BIDX>
957 max(RGBValue<V, RIDX, GIDX, BIDX> const & l,
958 RGBValue<V, RIDX, GIDX, BIDX> const & r)
960 typedef typename detail::LoopType<3>::type ltype;
961 RGBValue<V, RIDX, GIDX, BIDX> res(l);
962 ltype::max(res.begin(), r.begin());
985 template <class RGBVALUE>
987 : public VectorAccessor<RGBVALUE>
991 typedef typename RGBVALUE::value_type component_type;
995 template <class RGBIterator>
996 component_type const & red(RGBIterator const & rgb) const
1001 template <class V, class RGBIterator>
1002 void setRGB(V r, V g, V b, RGBIterator const & rgb) const
1004 (*rgb).setRGB( r, g, b );
1011 template <class V, class RGBIterator>
1012 void setRed(V value, RGBIterator const & rgb) const
1014 (*rgb).setRed(value);
1019 template <class RGBIterator, class DIFFERENCE>
1020 component_type const & red(RGBIterator const & rgb, DIFFERENCE diff) const
1022 return rgb[diff].red();
1028 template <class V, class RGBIterator, class DIFFERENCE>
1029 void setRed(V value, RGBIterator const & rgb, DIFFERENCE diff) const
1031 rgb[diff].setRed(value);
1036 template <class RGBIterator>
1037 component_type const & green(RGBIterator const & rgb) const
1039 return (*rgb).green();
1045 template <class V, class RGBIterator>
1046 void setGreen(V value, RGBIterator const & rgb) const
1048 (*rgb).setGreen(value);
1053 template <class RGBIterator, class DIFFERENCE>
1054 component_type const & green(RGBIterator const & rgb, DIFFERENCE d) const
1056 return rgb[d].green();
1062 template <class V, class RGBIterator, class DIFFERENCE>
1063 void setGreen(V value, RGBIterator const & rgb, DIFFERENCE d) const
1065 rgb[d].setGreen(value);
1070 template <class RGBIterator>
1071 component_type const & blue(RGBIterator const & rgb) const
1073 return (*rgb).blue();
1079 template <class V, class RGBIterator>
1080 void setBlue(V value, RGBIterator const & rgb) const
1082 (*rgb).setBlue(value);
1087 template <class RGBIterator, class DIFFERENCE>
1088 component_type const & blue(RGBIterator const & rgb, DIFFERENCE d) const
1090 return rgb[d].blue();
1096 template <class V, class RGBIterator, class DIFFERENCE>
1097 void setBlue(V value, RGBIterator const & rgb, DIFFERENCE d) const
1099 rgb[d].setBlue(value);
1116 template <class RGBVALUE>
1120 typedef typename RGBVALUE::value_type value_type;
1124 template <class ITERATOR>
1125 value_type const & operator()(ITERATOR const & i) const {
1131 template <class ITERATOR, class DIFFERENCE>
1132 value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
1140 template <class V, class ITERATOR>
1141 void set(V value, ITERATOR const & i) const {
1149 template <class V, class ITERATOR, class DIFFERENCE>
1150 void set(V value, ITERATOR const & i, DIFFERENCE d) const
1167 template <class RGBVALUE>
1171 typedef typename RGBVALUE::value_type value_type;
1175 template <class ITERATOR>
1176 value_type const & operator()(ITERATOR const & i) const {
1177 return (*i).green();
1182 template <class ITERATOR, class DIFFERENCE>
1183 value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
1185 return i[d].green();
1191 template <class V, class ITERATOR>
1192 void set(V value, ITERATOR const & i) const {
1193 (*i).setGreen(value);
1200 template <class V, class ITERATOR, class DIFFERENCE>
1201 void set(V value, ITERATOR const & i, DIFFERENCE d) const
1203 i[d].setGreen(value);
1218 template <class RGBVALUE>
1222 typedef typename RGBVALUE::value_type value_type;
1226 template <class ITERATOR>
1227 value_type const & operator()(ITERATOR const & i) const {
1233 template <class ITERATOR, class DIFFERENCE>
1234 value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
1242 template <class V, class ITERATOR>
1243 void set(V value, ITERATOR const & i) const {
1244 (*i).setBlue(value);
1251 template <class V, class ITERATOR, class DIFFERENCE>
1252 void set(V value, ITERATOR const & i, DIFFERENCE d) const
1254 i[d].setBlue(value);
1269 template <class RGBVALUE>
1270 class RGBToGrayAccessor
1273 typedef typename RGBVALUE::value_type value_type;
1277 template <class ITERATOR>
1278 value_type operator()(ITERATOR const & i) const {
1279 return (*i).luminance(); }
1283 template <class ITERATOR, class DIFFERENCE>
1284 value_type operator()(ITERATOR const & i, DIFFERENCE d) const
1286 return i[d].luminance();
1303 template <class VALUETYPE>
1304 class GrayToRGBAccessor
1307 typedef typename vigra::RGBValue<VALUETYPE> value_type;
1311 template <class ITERATOR>
1312 value_type operator()(ITERATOR const & i) const {
1313 return value_type(*i,*i,*i); }
1317 template <class ITERATOR, class DIFFERENCE>
1318 value_type operator()(ITERATOR const & i, DIFFERENCE d) const
1320 return value_type(i[d],i[d],i[d]);