core/vil1/vil1_rgb.h

Go to the documentation of this file.
00001 // This is core/vil1/vil1_rgb.h
00002 #ifndef vil1_rgb_h_
00003 #define vil1_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 vil1_rgb: weights (0.299,0.587,0.114)).
00013 //   - min and max of vil1_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 //   220598 PVr moved instantiations files to Templates subdirectory.
00025 //   050598 PVr added several operators ( + += - -= (T) ).
00026 //   290798 AWF Member templates for fancy compilers
00027 //   140898 David Capel added clamping functions to ensure 0-255 range on bytes and vil1_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 #include <vil1/vil1_clamp.h>
00034 
00035 #ifdef VCL_SUNPRO_CC
00036 # define InLine inline
00037 #else
00038 # define InLine
00039 #endif
00040 
00041 //: This is the appropriate pixel type for 24-bit colour images.
00042 //
00043 //    Currently also includes the following `utilities':
00044 //    -  conversion to ubyte (luminance of vil1_rgb: weights (0.299,0.587,0.114)).
00045 //    -  min and max of vil1_rgbcell values, useful for morphological operations.
00046 //    -  arithmetic operations
00047 template <class T>
00048 struct vil1_rgb
00049 {
00050   typedef T value_type;
00051 
00052   inline vil1_rgb() { }
00053 
00054   //:Create grey (v,v,v) vil1_rgb cell from value v.
00055   // This provides a conversion from T to vil1_rgb<T>, needed by e.g. two constructors in vil1_filter.h.
00056 
00057   inline vil1_rgb(T v):
00058     r(v), g(v), b(v) {}
00059 
00060   //:Construct an vil1_rgb value.
00061   inline vil1_rgb(T red, T green, T blue):
00062     r(red), g(green), b(blue) {}
00063 
00064   // The rgb values
00065   T r, g, b;
00066   inline T R() const { return r; }
00067   inline T G() const { return g; }
00068   inline T B() const { return b; }
00069 
00070   //:Convert vil1_rgb to gray using standard (.299, .587, .114) weighting.
00071   inline T grey() const { return T(r*0.299+0.587*g+0.114*b); }
00072 
00073   // Who wants this? It's a pain in the ass.
00074   // ImageProcessing/IIFOperators use this a lot!
00075   // Why can we not use .gray()?  This adds ambiguities.
00076 #if 0
00077   inline operator T() const { return T(0.5+r*0.299+0.587*g+0.114*b); }
00078 #endif
00079 
00080   //: equality
00081   inline bool operator== (vil1_rgb<T> const&) const;
00082 
00083   // operators
00084   inline vil1_rgb<T>  operator+  (vil1_rgb<T> const& A) const { return vil1_rgb<T>(r+A.r,g+A.g,b+A.b); }
00085   inline vil1_rgb<T>  operator-  (vil1_rgb<T> const& A) const { return vil1_rgb<T>(r-A.r,g-A.g,b-A.b); }
00086   inline vil1_rgb<T>  operator/  (vil1_rgb<T> const& A) const { return vil1_rgb<T>(r/A.r,g/A.g,b/A.b);}
00087   inline vil1_rgb<T>& operator+= (vil1_rgb<T> const& A) { r+=A.r,g+=A.g,b+=A.b; return *this; }
00088   inline vil1_rgb<T>& operator-= (vil1_rgb<T> const& A) { r-=A.r,g-=A.g,b-=A.b; return *this; }
00089   inline vil1_rgb<T>  operator*  (T A) const { return vil1_rgb<T>(r*A,g*A,b*A); }
00090   inline vil1_rgb<T>  operator/  (T A) const { return vil1_rgb<T>(r/A,g/A,b/A); }
00091   inline vil1_rgb<T>& operator*= (T A) { r*=A,g*=A,b*=A; return *this; }
00092   inline vil1_rgb<T>& operator/= (T A) { r/=A,g/=A,b/=A; return *this; }
00093 
00094 #define vil1_rgb_call(m) \
00095 m(unsigned char) \
00096 m(int) \
00097 m(long) \
00098 m(double)
00099 
00100 // VC50 bombs with INTERNAL COMPILER ERROR on template member functions.
00101 #if VCL_HAS_MEMBER_TEMPLATES
00102   template <class S> inline
00103   vil1_rgb(vil1_rgb<S> const& that):
00104     r(T(that.r)),
00105     g(T(that.g)),
00106     b(T(that.b)) { }
00107   template <class S> inline
00108   vil1_rgb<T>& operator=(vil1_rgb<S> const& that) {
00109     r=T(that.r);
00110     g=T(that.g);
00111     b=T(that.b);
00112     return *this;
00113   }
00114 #else
00115   // For dumb compilers, just special-case the commonly used types.
00116 # define macro(S) \
00117   inline vil1_rgb(vil1_rgb<S > const& that) : \
00118   r(T(that.r)), \
00119   g(T(that.g)), \
00120   b(T(that.b)) {}
00121 vil1_rgb_call(macro)
00122 # undef macro
00123 
00124 # define macro(S) \
00125   InLine vil1_rgb<T>& operator=(vil1_rgb<S > const& that);
00126 vil1_rgb_call(macro)
00127 # undef macro
00128 #endif
00129 };
00130 
00131 // see above
00132 #if VCL_HAS_MEMBER_TEMPLATES
00133 #else
00134 # define macro(S) \
00135 vil1_rgb<S > vil1_rgb_gcc_272_pump_prime(S const *); \
00136 template <class T> inline \
00137 vil1_rgb<T>& vil1_rgb<T>::operator=(vil1_rgb<S > const& that) { \
00138   r=T(that.r); \
00139   g=T(that.g); \
00140   b=T(that.b); \
00141   return *this; \
00142 }
00143 
00144 vil1_rgb_call(macro)
00145 # undef macro
00146 #endif
00147 
00148 #undef vil1_rgb_call
00149 
00150 
00151 // Assorted hackery for busted compilers
00152 typedef vil1_rgb<double> vil1_rgb_double;
00153 
00154 #ifdef __GNUC__
00155 extern vil1_rgb<double> tickle_mi_fancy;
00156 #endif
00157 
00158 
00159 template <class T>
00160 inline
00161 vcl_ostream& operator<<(vcl_ostream& s, vil1_rgb<T> const& rgb)
00162 {
00163   return s << '[' << rgb.r << ' ' << rgb.g << ' ' << rgb.b << ']';
00164 }
00165 
00166 
00167 // ** Arithmetic operators
00168 
00169 template <class T>
00170 inline
00171 bool vil1_rgb<T>::operator== (vil1_rgb<T> const& o) const
00172 {
00173   return r==o.r && g==o.g && b==o.b;
00174 }
00175 
00176 
00177 // the following cause compilation errors under Microsoft Visual C++
00178 // is there some conflict with min and max from the std library ?
00179 #if 0
00180 template <class T>
00181 inline
00182 vil1_rgb<T> max(vil1_rgb<T> const& a, vil1_rgb<T> const& b)
00183 {
00184   return vil1_rgb<T>((a.r>b.r)?a.r:b.r,
00185                      (a.g>b.g)?a.g:b.g,
00186                      (a.b>b.b)?a.b:b.b);
00187 }
00188 
00189 template <class T>
00190 inline
00191 vil1_rgb<T> min(vil1_rgb<T> const& a, vil1_rgb<T> const& b)
00192 {
00193   return vil1_rgb<T>((a.r<b.r)?a.r:b.r,
00194                      (a.g<b.g)?a.g:b.g,
00195                      (a.b<b.b)?a.b:b.b);
00196 }
00197 #endif
00198 
00199 template <class T>
00200 inline
00201 vil1_rgb<T> average(vil1_rgb<T> const& a, vil1_rgb<T> const& b)
00202 {
00203   return vil1_rgb<T>((a.r + b.r)/2, (a.g + b.g)/2, (a.b + b.b)/2);
00204 }
00205 
00206 template <class T>
00207 inline
00208 vil1_rgb<T> operator+(vil1_rgb<T> const& a, vil1_rgb<T> const& b)
00209 {
00210   return vil1_rgb<T>(a.r + b.r, a.g + b.g, a.b + b.b);
00211 }
00212 
00213 template <class T>
00214 inline
00215 vil1_rgb<double> operator*(double b, vil1_rgb<T> const& a)
00216 {
00217   return vil1_rgb<double>(a.r * b, a.g * b, a.b * b);
00218 }
00219 
00220 template <class T>
00221 inline
00222 vil1_rgb<double> operator*(vil1_rgb<T> const& a, double b)
00223 {
00224   return vil1_rgb<double>(a.r * b, a.g * b, a.b * b);
00225 }
00226 
00227 template <class T>
00228 inline
00229 vil1_rgb<double> operator/(vil1_rgb<T> const& a, double b)
00230 {
00231   return vil1_rgb<double>(a.r / b, a.g / b, a.b / b);
00232 }
00233 
00234 #if VCL_CAN_DO_PARTIAL_SPECIALIZATION
00235 template <class T>
00236 inline
00237 vil1_rgb<T> vil1_clamp_pixel(vil1_rgb<T> const& b, double range_min , double range_max)
00238 {
00239   return vil1_rgb<double>(vil1_clamp_pixel(b.r, range_min , range_max),
00240                           vil1_clamp_pixel(b.g, range_min , range_max),
00241                           vil1_clamp_pixel(b.b, range_min , range_max));
00242 }
00243 #endif
00244 
00245 #if 0 // capes@robots : These vil1_clamp functions are deprecated. See vil1_clamp.h
00246 inline
00247 vil1_rgb<unsigned char> vil1_clamp(vil1_rgb<double> const & d, vil1_rgb<unsigned char>* dummy)
00248 {
00249   return vil1_rgb<unsigned char>(vil1_clamp(d.r, &dummy->r),
00250                                  vil1_clamp(d.g, &dummy->g),
00251                                  vil1_clamp(d.b, &dummy->b));
00252 }
00253 
00254 inline
00255 vil1_rgb<unsigned char> vil1_clamp(vil1_rgb<float> const& d, vil1_rgb<unsigned char>* dummy)
00256 {
00257   return vil1_rgb<unsigned char>(vil1_clamp(d.r, &dummy->r),
00258                                  vil1_clamp(d.g, &dummy->g),
00259                                  vil1_clamp(d.b, &dummy->b));
00260 }
00261 #endif
00262 
00263 #define VIL1_RGB_INSTANTIATE(T) \
00264 extern "you must include vil1/vil1_rgb.txx first."
00265 #define VIL1_RGB_INSTANTIATE_LS(T) \
00266 extern "you must include vil1/vil1_rgb.txx first."
00267 
00268 #endif // vil1_rgb_h_

Generated on Sat Nov 22 05:08:29 2008 for core/vil1 by  doxygen 1.5.1