Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vidl2_color.h

Go to the documentation of this file.
00001 // This is brl/bbas/vidl2/vidl2_color.h
00002 #ifndef vidl2_color_h_
00003 #define vidl2_color_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Color space conversions and related functions
00010 //
00011 // \author Matt Leotta
00012 // \date 23 Jan 2006
00013 //
00014 
00015 #include "vidl2_pixel_format.h"
00016 #include <vcl_cstring.h>
00017 
00018 //-----------------------------------------------------------------------------
00019 // Color space conversions
00020 //-----------------------------------------------------------------------------
00021 
00022 
00023 // ITU-R BT.601 (formerly CCIR 601) standard conversion
00024 template <class outT>
00025 inline void vidl2_color_convert_yuv2rgb( vxl_byte y, vxl_byte u, vxl_byte v,
00026                                             outT& r,    outT& g,    outT& b )
00027 {
00028   double dy = y/255.0;       // 0.0 to 1.0
00029   double du = (u-128)/255.0; //-0.5 to 0.5
00030   double dv = (v-128)/255.0; //-0.5 to 0.5
00031   r = dy + 1.1402 * dv;
00032   g = dy - 0.34413628620102 * du - 0.71413628620102 * dv;
00033   b = dy + 1.772 * du;
00034 }
00035 
00036 
00037 //: faster integer-based conversion from YUV to RGB
00038 // Based on conversion used in libdc1394
00039 VCL_DEFINE_SPECIALIZATION
00040 inline void vidl2_color_convert_yuv2rgb( vxl_byte  y, vxl_byte  u, vxl_byte  v,
00041                                          vxl_byte& r, vxl_byte& g, vxl_byte& b )
00042 {
00043   register int iy = y, iu = u-128, iv = v-128, ir, ib, ig;
00044   r = ir = iy + ((iv*1436) >> 10);
00045   g = ig = iy - ((iu*352 + iv*731) >> 10);
00046   b = ib = iy + ((iu*1814) >> 10);
00047   r = ir < 0 ? 0 : r;
00048   g = ig < 0 ? 0 : g;
00049   b = ib < 0 ? 0 : b;
00050   r = ir > 255 ? 255 : r;
00051   g = ig > 255 ? 255 : g;
00052   b = ib > 255 ? 255 : b;
00053 }
00054 
00055 
00056 // ITU-R BT.601 (formerly CCIR 601) standard conversion
00057 template <class outT>
00058 inline void vidl2_color_convert_rgb2yuv( vxl_byte r, vxl_byte g, vxl_byte b,
00059                                             outT& y,    outT& u,    outT& v )
00060 {
00061   double dr = r/255.0; // 0.0 to 1.0
00062   double dg = g/255.0; // 0.0 to 1.0
00063   double db = b/255.0; // 0.0 to 1.0
00064   y = 0.299*dr + 0.587*dg + 0.114*db;
00065   u = (db-y)/1.772;
00066   v = (dr-y)/1.402;
00067 }
00068 
00069 
00070 //: faster integer-based conversion from RGB to YUV
00071 // Based on conversion used in libdc1394
00072 VCL_DEFINE_SPECIALIZATION
00073 inline void vidl2_color_convert_rgb2yuv( vxl_byte  r, vxl_byte  g, vxl_byte  b,
00074                                          vxl_byte& y, vxl_byte& u, vxl_byte& v )
00075 {
00076   register int ir = r, ib = b, ig = g, iy, iu, iv;
00077   y = iy = (306*ir + 601*ig + 117*ib)  >> 10;
00078   u = iu = ((-172*ir - 340*ig + 512*ib) >> 10) + 128;
00079   v = iv = ((512*ir - 429*ig - 83*ib) >> 10) + 128;
00080   y = iy < 0 ? 0 : y;
00081   u = iu < 0 ? 0 : u;
00082   v = iv < 0 ? 0 : v;
00083   y = iy > 255 ? 255 : y;
00084   u = iu > 255 ? 255 : u;
00085   v = iv > 255 ? 255 : v;
00086 }
00087 
00088 //-----------------------------------------------------------------------------
00089 // Generic interface to conversion routines
00090 //-----------------------------------------------------------------------------
00091 
00092 //: Define the function pointer for pixel format conversion functions
00093 typedef void (*vidl2_color_conv_fptr)(const vxl_byte* in, vxl_byte* out);
00094 
00095 //: Returns a color conversion function based on runtime values
00096 // The function returned is always a vidl2_color_conv_fptr which
00097 // converts const vxl_byte* to vxl_byte*.  Some of these function
00098 // may actually reinterpret the data as other types (i.e. bool* or
00099 // vxl_uint_16*) via reinterpret_cast
00100 vidl2_color_conv_fptr
00101 vidl2_color_converter_func( vidl2_pixel_color in_C, unsigned in_bpp,
00102                             vidl2_pixel_color out_C, unsigned out_bpp);
00103 
00104 
00105 template <vidl2_pixel_color in_C, vidl2_pixel_color out_C>
00106 struct vidl2_color_converter;
00107 
00108 VCL_DEFINE_SPECIALIZATION
00109 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_RGB>
00110 {
00111   static inline void convert(const vxl_byte in[3], vxl_byte out[3])
00112   {
00113     out[0] = in[0];
00114     out[1] = in[1];
00115     out[2] = in[2];
00116   }
00117 };
00118 
00119 
00120 VCL_DEFINE_SPECIALIZATION
00121 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_RGBA>
00122 {
00123   static inline void convert(const vxl_byte in[4], vxl_byte out[4])
00124   {
00125     out[0] = in[0];
00126     out[1] = in[1];
00127     out[2] = in[2];
00128     out[3] = in[3];
00129   }
00130 };
00131 
00132 
00133 VCL_DEFINE_SPECIALIZATION
00134 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_RGB>
00135 {
00136   static inline void convert(const vxl_byte in[4], vxl_byte out[3])
00137   {
00138     out[0] = in[0];
00139     out[1] = in[1];
00140     out[2] = in[2];
00141   }
00142 };
00143 
00144 
00145 VCL_DEFINE_SPECIALIZATION
00146 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_RGBA>
00147 {
00148   static inline void convert(const vxl_byte in[3], vxl_byte out[4])
00149   {
00150     out[0] = in[0];
00151     out[1] = in[1];
00152     out[2] = in[2];
00153     out[3] = 0xFF;
00154   }
00155 };
00156 
00157 VCL_DEFINE_SPECIALIZATION
00158 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_YUV>
00159 {
00160   static inline void convert(const vxl_byte in[3], vxl_byte out[3])
00161   {
00162     out[0] = in[0];
00163     out[1] = in[1];
00164     out[2] = in[2];
00165   }
00166 };
00167 
00168 
00169 VCL_DEFINE_SPECIALIZATION
00170 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>
00171 {
00172   template <class T>
00173   static inline void convert(const T in[1], T out[1])
00174   {
00175     out[0] = in[0];
00176   }
00177 
00178   static inline void convert(const vxl_byte in[1], bool out[1])
00179   {
00180     out[0] = (in[0]&0x80) > 0; // threshold
00181   }
00182 
00183   static inline void convert(const vxl_uint_16 in[1], bool out[1])
00184   {
00185     out[0] = (in[0]&0x8000) > 0; // threshold
00186   }
00187 
00188   static inline void convert(const bool in[1], vxl_byte out[1])
00189   {
00190     out[0] = in[0]?0xFF:0x00;
00191   }
00192 
00193   static inline void convert(const bool in[1], vxl_uint_16 out[1])
00194   {
00195     out[0] = in[0]?0xFFFF:0x0000;
00196   }
00197 
00198   static inline void convert(const vxl_byte in[1], vxl_uint_16 out[1])
00199   {
00200     out[0] = in[0]<<8;
00201   }
00202 
00203   static inline void convert(const vxl_uint_16 in[1], vxl_byte out[1])
00204   {
00205     out[0] = in[0]>>8;
00206   }
00207 };
00208 
00209 
00210 VCL_DEFINE_SPECIALIZATION
00211 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_YUV>
00212 {
00213   template <class outT>
00214   static inline void convert(const vxl_byte in[3], outT out[3])
00215   {
00216     vidl2_color_convert_rgb2yuv(in[0],in[1],in[2],
00217                                 out[0],out[1],out[2]);
00218   }
00219 };
00220 
00221 
00222 VCL_DEFINE_SPECIALIZATION
00223 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_YUV>
00224 {
00225   template <class outT>
00226   static inline void convert(const vxl_byte in[4], outT out[3])
00227   {
00228     vidl2_color_convert_rgb2yuv(in[0],in[1],in[2],
00229                                 out[0],out[1],out[2]);
00230   }
00231 };
00232 
00233 
00234 VCL_DEFINE_SPECIALIZATION
00235 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_RGB>
00236 {
00237   template <class outT>
00238   static inline void convert(const vxl_byte in[3], outT out[3])
00239   {
00240     vidl2_color_convert_yuv2rgb(in[0],in[1],in[2],
00241                                 out[0],out[1],out[2]);
00242   }
00243 };
00244 
00245 
00246 VCL_DEFINE_SPECIALIZATION
00247 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_RGBA>
00248 {
00249   template <class outT>
00250   static inline void convert(const vxl_byte in[3], outT out[4])
00251   {
00252     vidl2_color_convert_yuv2rgb(in[0],in[1],in[2],
00253                                 out[0],out[1],out[2]);
00254     out[3] = vidl2_pixel_limits<outT>::max();
00255   }
00256 };
00257 
00258 
00259 VCL_DEFINE_SPECIALIZATION
00260 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_MONO>
00261 {
00262   template <class T>
00263   static inline void convert(const vxl_byte in[3], T out[1])
00264   {
00265     // The Y channel is the greyscale value
00266     vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00267   }
00268 };
00269 
00270 
00271 VCL_DEFINE_SPECIALIZATION
00272 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_YUV>
00273 {
00274   template <class T>
00275   static inline void convert(const T in[1], vxl_byte out[3])
00276   {
00277     // The Y channel is the greyscale value
00278     vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00279     out[1] = 128;
00280     out[2] = 128;
00281   }
00282 };
00283 
00284 VCL_DEFINE_SPECIALIZATION
00285 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_MONO>
00286 {
00287   template <class T>
00288   static inline void convert(const vxl_byte in[3], T out[1])
00289   {
00290     //: FIXME this is probably wrong
00291     vxl_byte grey = (306*in[0] + 601*in[1] + 117*in[2]) >> 10;
00292     vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(&grey,out);
00293   }
00294 };
00295 
00296 VCL_DEFINE_SPECIALIZATION
00297 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_MONO>
00298 {
00299   template <class T>
00300   static inline void convert(const vxl_byte in[4], T out[1])
00301   {
00302     //: FIXME this is probably wrong
00303     vxl_byte grey = (306*in[0] + 601*in[1] + 117*in[2]) >> 10;
00304     vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(&grey,out);
00305   }
00306 };
00307 
00308 VCL_DEFINE_SPECIALIZATION
00309 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_RGB>
00310 {
00311   template <class T>
00312   static inline void convert(const T in[1], vxl_byte out[3])
00313   {
00314     // Set all channels to the same value
00315     vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00316     out[2] = out[1] = out[0];
00317   }
00318 };
00319 
00320 VCL_DEFINE_SPECIALIZATION
00321 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_RGBA>
00322 {
00323   template <class T>
00324   static inline void convert(const T in[1], vxl_byte out[4])
00325   {
00326     // Set all channels to the same value
00327     vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00328     out[2] = out[1] = out[0];
00329     out[3] = 0xFF;
00330   }
00331 };
00332 
00333 
00334 //-----------------------------------------------------------------------------
00335 // Access to color components
00336 //-----------------------------------------------------------------------------
00337 
00338 
00339 //: Component color encoding
00340 // These functions indicate how to extract a byte for each
00341 // color channel given a pointer to the pixel memory
00342 // This is only meant for non-planar non-packed formats
00343 template <vidl2_pixel_format FMT>
00344 struct vidl2_color_component
00345 {
00346   typedef typename vidl2_pixel_traits_of<FMT>::type cmp_type;
00347   static inline
00348   cmp_type get(const cmp_type * ptr, unsigned int i)
00349   {
00350     return ptr[i];
00351   }
00352 
00353   // it may be more efficient to access all color channels at once
00354   static inline
00355   void get_all(const cmp_type * ptr, cmp_type * data)
00356   {
00357     vcl_memcpy(data, ptr, sizeof(cmp_type)*vidl2_pixel_traits_of<FMT>::num_channels);
00358   }
00359 
00360   static inline
00361   void set(cmp_type * ptr, unsigned int i, cmp_type val)
00362   {
00363     ptr[i] = val;
00364   }
00365 
00366   // it may be more efficient to access all color channels at once
00367   static inline
00368   void set_all(cmp_type * ptr, const cmp_type * data)
00369   {
00370     vcl_memcpy(ptr, data, sizeof(cmp_type)*vidl2_pixel_traits_of<FMT>::num_channels);
00371   }
00372 };
00373 
00374 
00375 VCL_DEFINE_SPECIALIZATION
00376 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_BGR_24>
00377 {
00378   // 0 -> 2
00379   // 1 -> 1
00380   // 2 -> 0
00381   static inline
00382   vxl_byte get(const vxl_byte * ptr, unsigned int i)
00383   {
00384     return ptr[2-i];
00385   }
00386 
00387   static inline
00388   void get_all(const vxl_byte * ptr, vxl_byte * data)
00389   {
00390     data[0] = ptr[2];
00391     data[1] = ptr[1];
00392     data[2] = ptr[0];
00393   }
00394 
00395   static inline
00396   void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00397   {
00398     ptr[2-i] = val;
00399   }
00400 
00401   static inline
00402   void set_all(vxl_byte * ptr, const vxl_byte * data)
00403   {
00404     ptr[2] = data[0];
00405     ptr[1] = data[1];
00406     ptr[0] = data[2];
00407   }
00408 };
00409 
00410 
00411 VCL_DEFINE_SPECIALIZATION
00412 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_RGB_555>
00413 {
00414   static inline
00415   vxl_byte get(const vxl_byte * ptr, unsigned int i)
00416   {
00417     const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00418     return static_cast<vxl_byte>(*p >> (2-i)*5)<<3;
00419   }
00420 
00421   static inline
00422   void get_all(const vxl_byte * ptr, vxl_byte * data)
00423   {
00424     const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00425     data[0] = static_cast<vxl_byte>(*p >>10)<<3;
00426     data[1] = static_cast<vxl_byte>(*p >>5)<<3;
00427     data[2] = static_cast<vxl_byte>(*p)<<3;
00428   }
00429 
00430   static inline
00431   void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00432   {
00433     vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00434     vxl_uint_16 v = static_cast<vxl_uint_16>(val>>3)<<(2-i)*5;
00435     vxl_uint_16 mask = ~(31<<(2-i)*5);
00436     *p  = (*p & mask) | v;
00437   }
00438 
00439   static inline
00440   void set_all(vxl_byte * ptr, const vxl_byte * data)
00441   {
00442     vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00443     *p = ((data[0]>>3) << 10) | ((data[1]>>3) << 5) | (data[2]>>3);
00444   }
00445 };
00446 
00447 
00448 VCL_DEFINE_SPECIALIZATION
00449 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_RGB_565>
00450 {
00451   static inline
00452   vxl_byte get(const vxl_byte * ptr, unsigned int i)
00453   {
00454     const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00455     switch (i) {
00456       case 0: return vxl_byte((*p & 0xF800) >> 8); // R
00457       case 1: return vxl_byte((*p & 0x07E0) >> 3); // G
00458       case 2: return vxl_byte((*p & 0x001F) << 3); // B
00459     }
00460     return 0;
00461   }
00462 
00463   static inline
00464   void get_all(const vxl_byte * ptr, vxl_byte * data)
00465   {
00466     const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00467     data[0] = static_cast<vxl_byte>(*p >>11)<<3;
00468     data[1] = static_cast<vxl_byte>(*p >>5)<<2;
00469     data[2] = static_cast<vxl_byte>(*p)<<3;
00470   }
00471 
00472   static inline
00473   void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00474   {
00475     vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00476     vxl_uint_16 v = static_cast<vxl_uint_16>(val>>3);
00477     switch (i) {
00478       case 0: *p &= 0x07FF; *p |= (v<<11); break; // R
00479       case 1: *p &= 0xF81F; *p |= (v<<5); break;  // G
00480       case 2: *p &= 0xFFE0; *p |= v; break;       // B
00481     }
00482   }
00483 
00484   static inline
00485   void set_all(vxl_byte * ptr, const vxl_byte * data)
00486   {
00487     vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00488     *p = ((data[0]>>3) << 11) | ((data[1]>>2) << 5) | (data[2]>>3);
00489   }
00490 };
00491 
00492 
00493 VCL_DEFINE_SPECIALIZATION
00494 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_UYV_444>
00495 {
00496   // 0 -> 1
00497   // 1 -> 0
00498   // 2 -> 2
00499   static inline
00500   vxl_byte get(const vxl_byte * ptr, unsigned int i)
00501   {
00502     return ptr[i^((i>>1)^1)];
00503   }
00504 
00505   static inline
00506   void get_all(const vxl_byte * ptr, vxl_byte * data)
00507   {
00508     data[0] = ptr[1];
00509     data[1] = ptr[0];
00510     data[2] = ptr[2];
00511   }
00512 
00513   static inline
00514   void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00515   {
00516     ptr[i^((i>>1)^1)] = val;
00517   }
00518 
00519   static inline
00520   void set_all(vxl_byte * ptr, const vxl_byte * data)
00521   {
00522     ptr[1] = data[0];
00523     ptr[0] = data[1];
00524     ptr[2] = data[2];
00525   }
00526 };
00527 
00528 #endif // vidl2_color_h_
00529 

Generated on Thu Jan 10 14:51:31 2008 for contrib/brl/bbas/vidl2 by  doxygen 1.4.4