core/vil/vil_rgb.h

Go to the documentation of this file.
00001 // This is core/vil/vil_rgb.h
00002 #ifndef vil_rgb_h_
00003 #define vil_rgb_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Pixel type for 24 bit images
00010 //
00011 //  Currently also includes the following `utilities':
00012 //   - conversion to ubyte (luminance of vil_rgb: weights (0.299,0.587,0.114)).
00013 //   - min and max of vil_rgbcell values, useful for morphological operations.
00014 //   - arithmetic operations
00015 //
00016 // \author Peter Vanroose, K.U.Leuven, ESAT/VISICS
00017 // \date   15 nov. 1997
00018 //
00019 //\verbatim
00020 //  Modifications:
00021 //    250198 AWF Templated.
00022 //    250198 AWF Modified to make POD struct until gcc inlines when debugging.
00023 //    160298 PCP Removed underscore from public members.
00024 //    290798 AWF Member templates for fancy compilers
00025 //    220598 PVr moved instantiations files to Templates subdirectory.
00026 //    050598 PVr added several operators ( + += - -= (T) ).
00027 //    140898 David Capel added clamping functions to ensure 0-255 range on bytes and vil_rgb<byte>
00028 //    090600 David Capel made clamping functions inline and removed all that partial specialization nonsense from the .txx file.
00029 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
00030 //\endverbatim
00031 
00032 #include <vcl_iostream.h>
00033 
00034 #ifdef VCL_SUNPRO_CC
00035 # define InLine inline
00036 #else
00037 # define InLine
00038 #endif
00039 
00040 //: This is the appropriate pixel type for 24-bit colour images.
00041 //
00042 //    Currently also includes the following `utilities':
00043 //    -  conversion to ubyte (luminance of vil_rgb: weights (0.299,0.587,0.114)).
00044 //    -  min and max of vil_rgbcell values, useful for morphological operations.
00045 //    -  arithmetic operations
00046 template <class T>
00047 struct vil_rgb
00048 {
00049   typedef T value_type;
00050 
00051   inline vil_rgb() { }
00052 
00053   //:Create grey (v,v,v) vil_rgb cell from value v.
00054   // This provides a conversion from T to vil_rgb<T>
00055 
00056   inline vil_rgb(T v):
00057     r(v), g(v), b(v) {}
00058 
00059   //:Construct an vil_rgb value.
00060   inline vil_rgb(T red, T green, T blue):
00061     r(red), g(green), b(blue) {}
00062 
00063   // The rgb values
00064   T r, g, b;
00065   inline T R() const { return r; }
00066   inline T G() const { return g; }
00067   inline T B() const { return b; }
00068 
00069   //:Convert vil_rgb to gray using standard (.299, .587, .114) weighting.
00070   inline T grey() const { return T(r*0.299+0.587*g+0.114*b); }
00071 
00072   // Who wants this? It's a pain in the ass.
00073   // ImageProcessing/IIFOperators use this a lot!
00074   // Why can we not use .gray()?  This adds ambiguities.
00075 #if 0
00076   inline operator T() const { return T(0.5+r*0.299+0.587*g+0.114*b); }
00077 #endif
00078 
00079   //: equality
00080   inline bool operator== (vil_rgb<T> const&) const;
00081 
00082   // operators
00083   inline vil_rgb<T>  operator+  (vil_rgb<T> const& A) const { return vil_rgb<T>(r+A.r,g+A.g,b+A.b); }
00084   inline vil_rgb<T>  operator-  (vil_rgb<T> const& A) const { return vil_rgb<T>(r-A.r,g-A.g,b-A.b); }
00085   inline vil_rgb<T>  operator/  (vil_rgb<T> const& A) const { return vil_rgb<T>(r/A.r,g/A.g,b/A.b);}
00086   inline vil_rgb<T>& operator+= (vil_rgb<T> const& A) { r+=A.r,g+=A.g,b+=A.b; return *this; }
00087   inline vil_rgb<T>& operator-= (vil_rgb<T> const& A) { r-=A.r,g-=A.g,b-=A.b; return *this; }
00088   inline vil_rgb<T>  operator*  (T A) const { return vil_rgb<T>(r*A,g*A,b*A); }
00089   inline vil_rgb<T>  operator/  (T A) const { return vil_rgb<T>(r/A,g/A,b/A); }
00090   inline vil_rgb<T>& operator*= (T A) { r*=A,g*=A,b*=A; return *this; }
00091   inline vil_rgb<T>& operator/= (T A) { r/=A,g/=A,b/=A; return *this; }
00092 
00093 #define vil_rgb_call(m) \
00094 m(unsigned char) \
00095 m(int) \
00096 m(long) \
00097 m(double)
00098 
00099 // VC50 bombs with INTERNAL COMPILER ERROR on template member functions.
00100 #if VCL_HAS_MEMBER_TEMPLATES
00101   template <class S> inline
00102   vil_rgb(vil_rgb<S> const& that):
00103     r(T(that.r)),
00104     g(T(that.g)),
00105     b(T(that.b)) { }
00106   template <class S> inline
00107   vil_rgb<T>& operator=(vil_rgb<S> const& that) {
00108     r=T(that.r);
00109     g=T(that.g);
00110     b=T(that.b);
00111     return *this;
00112   }
00113 #else
00114   // For dumb compilers, just special-case the commonly used types.
00115 # define macro(S) \
00116   inline vil_rgb(vil_rgb<S > const& that) : \
00117   r(T(that.r)), \
00118   g(T(that.g)), \
00119   b(T(that.b)) {}
00120 vil_rgb_call(macro)
00121 # undef macro
00122 
00123 # define macro(S) \
00124   InLine vil_rgb<T>& operator=(vil_rgb<S > const& that);
00125 vil_rgb_call(macro)
00126 # undef macro
00127 #endif
00128 };
00129 
00130 // see above
00131 #if VCL_HAS_MEMBER_TEMPLATES
00132 #else
00133 # define macro(S) \
00134 template <class T> inline \
00135 vil_rgb<T>& vil_rgb<T>::operator=(vil_rgb<S > const& that) { \
00136   r=T(that.r); \
00137   g=T(that.g); \
00138   b=T(that.b); \
00139   return *this; \
00140 }
00141 
00142 vil_rgb_call(macro)
00143 # undef macro
00144 #endif
00145 
00146 #undef vil_rgb_call
00147 
00148 template <class T>
00149 inline
00150 vcl_ostream& operator<<(vcl_ostream& s, vil_rgb<T> const& rgb)
00151 {
00152   return s << '[' << rgb.r << ' ' << rgb.g << ' ' << rgb.b << ']';
00153 }
00154 
00155 VCL_DEFINE_SPECIALIZATION
00156 vcl_ostream& operator<<(vcl_ostream& s, vil_rgb<unsigned char> const& rgb);
00157 
00158 
00159 // ** Arithmetic operators
00160 
00161 template <class T>
00162 inline
00163 bool vil_rgb<T>::operator== (vil_rgb<T> const& o) const
00164 {
00165   return r==o.r && g==o.g && b==o.b;
00166 }
00167 
00168 template <class T>
00169 inline
00170 bool operator!= (vil_rgb<T> const& a, vil_rgb<T> const& b) 
00171 {
00172   return !(a==b);
00173 }
00174 
00175 template <class T>
00176 inline
00177 vil_rgb<T> average(vil_rgb<T> const& a, vil_rgb<T> const& b)
00178 {
00179   return vil_rgb<T>((a.r + b.r)/2, (a.g + b.g)/2, (a.b + b.b)/2);
00180 }
00181 
00182 template <class T>
00183 inline
00184 vil_rgb<T> operator+(vil_rgb<T> const& a, vil_rgb<T> const& b)
00185 {
00186   return vil_rgb<T>(a.r + b.r, a.g + b.g, a.b + b.b);
00187 }
00188 
00189 template <class T>
00190 inline
00191 vil_rgb<double> operator*(double b, vil_rgb<T> const& a)
00192 {
00193   return vil_rgb<double>(a.r * b, a.g * b, a.b * b);
00194 }
00195 
00196 template <class T>
00197 inline
00198 vil_rgb<double> operator*(vil_rgb<T> const& a, double b)
00199 {
00200   return vil_rgb<double>(a.r * b, a.g * b, a.b * b);
00201 }
00202 
00203 template <class T>
00204 inline
00205 vil_rgb<double> operator/(vil_rgb<T> const& a, double b)
00206 {
00207   return vil_rgb<double>(a.r / b, a.g / b, a.b / b);
00208 }
00209 
00210 #define VIL_RGB_INSTANTIATE(T) \
00211 extern "you must include vil/vil_rgb.txx first."
00212 #define VIL_RGB_INSTANTIATE_LS(T) \
00213 extern "you must include vil/vil_rgb.txx first."
00214 
00215 #endif // vil_rgb_h_

Generated on Sat Nov 22 05:07:54 2008 for core/vil by  doxygen 1.5.1