core/vidl/vidl_pixel_format.h
Go to the documentation of this file.
00001 // This is core/vidl/vidl_pixel_format.h
00002 #ifndef vidl_pixel_format_h_
00003 #define vidl_pixel_format_h_
00004 //:
00005 // \file
00006 // \brief Supported pixel formats for video frames
00007 //
00008 // \author Matt Leotta
00009 // \date  13 Jan 2006
00010 //
00011 // This file defines the set of known video frame pixel formats.
00012 // The enum vidl_pixel_format enumerates the types while the
00013 // template specializations of vidl_pixel_traits define their
00014 // basic traits.  These specializations are defined using the
00015 // macro vidl_pt_mac.  The pixel traits are:
00016 //  - <b>name</b> a string representation for the format
00017 //  - <b>type</b> the VXL C++ type used to return a pixel component
00018 //  - <b>bits per pixel</b> the number of bits used to represent a pixel
00019 //  - <b>number of channels</b> the number of color channels encoded
00020 //                              (now determined by color)
00021 //  - <b>color</b> the color encoding of the pixels (i.e. RGB, YUV)
00022 //  - <b>arrangement</b> the way pixels are arranged in memory.  This
00023 //       could be in single file, packed into macropixels, or in planes.
00024 //  - <b>chroma shift X</b> the chroma subsampling factor is 2 ^ shift
00025 //       in the horizontal direction.
00026 //  - <b>chroma shift Y</b> the chroma subsampling factor is 2 ^ shift
00027 //       in the vertical direction.
00028 //
00029 // vidl_pixel_format differs from vil_pixel_format in that the
00030 // vidl formats are representations typically used by video
00031 // hardware and in video codecs to encode a frame.  The vil pixel
00032 // formats are more useful for image processing and are related
00033 // to the C++ data types that may be arranged in a regular array
00034 // to make an image.  A vidl_pixel_format may have components
00035 // in multiple planes of different sizes or may have data from
00036 // multiple image pixels encoded as a single macro pixel.
00037 //
00038 // This file also contains several functions to check the traits
00039 // of a pixel format at runtime.  These functions use template
00040 // metaprogramming to generate conditionals that probe the formats
00041 // defined in this file.  So you don't need to modify these functions
00042 // when you add a new pixel format into this header file.
00043 
00044 #include <vcl_string.h>
00045 #include <vcl_cstddef.h>
00046 #include <vcl_iosfwd.h>
00047 #include <vcl_typeinfo.h>
00048 #include <vxl_config.h>
00049 
00050 //: Describes the format of pixel encoding in a video frame buffer
00051 enum vidl_pixel_format
00052 {
00053   VIDL_PIXEL_FORMAT_UNKNOWN = -1,
00054 
00055   VIDL_PIXEL_FORMAT_RGB_24,
00056   VIDL_PIXEL_FORMAT_RGB_24P,
00057   VIDL_PIXEL_FORMAT_BGR_24,
00058   VIDL_PIXEL_FORMAT_RGBA_32,
00059   VIDL_PIXEL_FORMAT_RGBA_32P,
00060   VIDL_PIXEL_FORMAT_RGB_565,
00061   VIDL_PIXEL_FORMAT_RGB_555,
00062 
00063   VIDL_PIXEL_FORMAT_YUV_444P,
00064   VIDL_PIXEL_FORMAT_YUV_422P,
00065   VIDL_PIXEL_FORMAT_YUV_420P,
00066   VIDL_PIXEL_FORMAT_YVU_420P,
00067   VIDL_PIXEL_FORMAT_YUV_411P,
00068   VIDL_PIXEL_FORMAT_YUV_410P,
00069   VIDL_PIXEL_FORMAT_UYV_444,
00070   VIDL_PIXEL_FORMAT_YUYV_422,
00071   VIDL_PIXEL_FORMAT_UYVY_422,
00072   VIDL_PIXEL_FORMAT_UYVY_411,
00073 
00074   VIDL_PIXEL_FORMAT_MONO_1,
00075   VIDL_PIXEL_FORMAT_MONO_8,
00076   VIDL_PIXEL_FORMAT_MONO_16,
00077   VIDL_PIXEL_FORMAT_MONO_F32,
00078   VIDL_PIXEL_FORMAT_RGB_F32,
00079   VIDL_PIXEL_FORMAT_RGB_F32P,
00080 
00081   // Add values here
00082   VIDL_PIXEL_FORMAT_ENUM_END
00083 };
00084 
00085 
00086 //: Describes the color encoding of a pixel format
00087 enum vidl_pixel_color
00088 {
00089   VIDL_PIXEL_COLOR_UNKNOWN = -1,
00090 
00091   VIDL_PIXEL_COLOR_MONO,
00092   VIDL_PIXEL_COLOR_RGB,
00093   VIDL_PIXEL_COLOR_RGBA,
00094   VIDL_PIXEL_COLOR_YUV,
00095 
00096   // Add values here
00097 
00098   VIDL_PIXEL_COLOR_ENUM_END
00099 };
00100 
00101 
00102 //: Describes the arrangement of pixels in a pixel format
00103 enum vidl_pixel_arrangement
00104 {
00105   VIDL_PIXEL_ARRANGE_UNKNOWN = -1,
00106 
00107   VIDL_PIXEL_ARRANGE_SINGLE,
00108   VIDL_PIXEL_ARRANGE_PACKED,
00109   VIDL_PIXEL_ARRANGE_PLANAR,
00110   VIDL_PIXEL_ARRANGE_PALETTE,
00111 
00112   // Add values here
00113 
00114   VIDL_PIXEL_ARRANGE_ENUM_END
00115 };
00116 
00117 
00118 //: Traits of the pixel formats
00119 // - name a string name for the format
00120 // - bits_per_pixel the effective number of bits per pixel
00121 // - color the color mode used
00122 // - planar are the pixel components arranged on multiple planes
00123 // - packed are the pixels packed into macro pixels
00124 struct vidl_pixel_traits
00125 {
00126   vcl_string name;
00127   const vcl_type_info* type;
00128   unsigned bits_per_pixel;
00129   unsigned num_channels;
00130   vidl_pixel_color color;
00131   vidl_pixel_arrangement arrangement;
00132   unsigned chroma_shift_x;
00133   unsigned chroma_shift_y;
00134 };
00135 
00136 // ***** Start: temporary hack to avoid conflict *****
00137 #ifdef min
00138 #undef min
00139 #endif
00140 #ifdef max
00141 #undef max
00142 #endif
00143 // ***** End: temporary hack to avoid conflict *****
00144 
00145 //: Define limits on the minimum and maximum pixel values
00146 // Also define \a chroma_zero as the U and V value to represent
00147 // gray (no color) in YUV encoding
00148 template <class T>
00149 struct vidl_pixel_limits;
00150 
00151 VCL_DEFINE_SPECIALIZATION
00152 struct vidl_pixel_limits<vxl_byte>
00153 {
00154   static inline vxl_byte min() {return 0x00;}
00155   static inline vxl_byte max() {return 0xFF;}
00156   static inline vxl_byte chroma_zero() {return 0x80;}
00157 };
00158 
00159 VCL_DEFINE_SPECIALIZATION
00160 struct vidl_pixel_limits<bool>
00161 {
00162   static inline bool min() {return false;}
00163   static inline bool max() {return true;}
00164   // chroma zero is not well defined, YUV can't be boolean
00165   static inline bool chroma_zero() {return false;}
00166 };
00167 
00168 VCL_DEFINE_SPECIALIZATION
00169 struct vidl_pixel_limits<vxl_uint_16>
00170 {
00171   static inline vxl_uint_16 min() {return 0x0000;}
00172   static inline vxl_uint_16 max() {return 0xFFFF;}
00173   static inline vxl_uint_16 chroma_zero() {return 0x8000;}
00174 };
00175 
00176 VCL_DEFINE_SPECIALIZATION
00177 struct vidl_pixel_limits<float>
00178 {
00179   static inline float min() {return 0.0f;}
00180   static inline float max() {return 1.0f;}
00181   static inline float chroma_zero() {return 0.0f;}
00182 };
00183 
00184 VCL_DEFINE_SPECIALIZATION
00185 struct vidl_pixel_limits<double>
00186 {
00187   static inline double min() {return 0.0;}
00188   static inline double max() {return 1.0;}
00189   static inline double chroma_zero() {return 0.0f;}
00190 };
00191 
00192 
00193 //: Define the color traits for each vidl_pixel_color
00194 // For now this is just the number of channels
00195 template <vidl_pixel_color color_type>
00196     struct vidl_color_traits_of;
00197 #define vidl_ct_mac(COL,NC)\
00198 VCL_DEFINE_SPECIALIZATION \
00199 struct vidl_color_traits_of<VIDL_PIXEL_COLOR_##COL> \
00200 {\
00201   enum { num_channels = NC }; \
00202 }
00203 
00204 vidl_ct_mac( UNKNOWN,  0 );
00205 vidl_ct_mac( MONO,     1 );
00206 vidl_ct_mac( RGB,      3 );
00207 vidl_ct_mac( RGBA,     4 );
00208 vidl_ct_mac( YUV,      3 );
00209 
00210 #undef vidl_ct_mac
00211 
00212 
00213 //: Define traits for a given vidl_pixel_format
00214 // All pixel traits should be defined using the macro below
00215 // The anonymous enums allow the values available to the
00216 // compiler to for use in generic programming.  For values
00217 // that are already enums, a function is provided so the
00218 // user does not need to worry about enum type clashes.
00219 template <vidl_pixel_format pix_type>
00220 struct vidl_pixel_traits_of;
00221 #define vidl_pt_mac(FMT,NAME,T,BPP,CLR,ARNG,XCS,YCS)\
00222 VCL_DEFINE_SPECIALIZATION \
00223 struct vidl_pixel_traits_of<VIDL_PIXEL_FORMAT_##FMT> \
00224 {\
00225   static inline vcl_string name() { return NAME; }\
00226   typedef T type;\
00227   enum { bits_per_pixel = BPP };\
00228   enum { num_channels = vidl_color_traits_of<VIDL_PIXEL_COLOR_##CLR>::num_channels };\
00229   static inline vidl_pixel_color color() { return VIDL_PIXEL_COLOR_##CLR; }\
00230   enum { color_idx = VIDL_PIXEL_COLOR_##CLR };\
00231   static inline vidl_pixel_arrangement arrangement() { return VIDL_PIXEL_ARRANGE_##ARNG; }\
00232   enum { arrangement_idx = VIDL_PIXEL_ARRANGE_##ARNG };\
00233   enum { chroma_shift_x = XCS };\
00234   enum { chroma_shift_y = YCS };\
00235 }
00236 
00237 //            format    name             type         bpp  color    arrange  xcs  ycs
00238 //            ------    ---------        ----         ---  -------  -------  ---  ---
00239 vidl_pt_mac( UNKNOWN,  "unknown",       void,        0,   UNKNOWN, UNKNOWN, 0,   0  );
00240 
00241 vidl_pt_mac( RGB_24,   "RGB 24",        vxl_byte,    24,  RGB,     SINGLE,  0,   0  );
00242 vidl_pt_mac( RGB_24P,  "RGB 24P",       vxl_byte,    24,  RGB,     PLANAR,  0,   0  );
00243 vidl_pt_mac( BGR_24,   "BGR 24",        vxl_byte,    24,  RGB,     SINGLE,  0,   0  );
00244 vidl_pt_mac( RGBA_32,  "RGBA 32",       vxl_byte,    32,  RGBA,    SINGLE,  0,   0  );
00245 vidl_pt_mac( RGBA_32P, "RGBA 32P",      vxl_byte,    32,  RGBA,    PLANAR,  0,   0  );
00246 vidl_pt_mac( RGB_565,  "RGB 565",       vxl_byte,    16,  RGB,     SINGLE,  0,   0  );
00247 vidl_pt_mac( RGB_555,  "RGB 555",       vxl_byte,    16,  RGB,     SINGLE,  0,   0  );
00248 
00249 vidl_pt_mac( YUV_444P, "YUV 444P",      vxl_byte,    24,  YUV,     PLANAR,  0,   0  );
00250 vidl_pt_mac( YUV_422P, "YUV 422P",      vxl_byte,    16,  YUV,     PLANAR,  1,   0  );
00251 vidl_pt_mac( YUV_420P, "YUV 420P",      vxl_byte,    12,  YUV,     PLANAR,  1,   1  );
00252 vidl_pt_mac( YVU_420P, "YVU 420P",      vxl_byte,    12,  YUV,     PLANAR,  1,   1  );
00253 vidl_pt_mac( YUV_411P, "YUV 411P",      vxl_byte,    12,  YUV,     PLANAR,  2,   0  );
00254 vidl_pt_mac( YUV_410P, "YUV 410P",      vxl_byte,    10,  YUV,     PLANAR,  2,   1  );
00255 vidl_pt_mac( UYV_444,  "UYV 444",       vxl_byte,    24,  YUV,     SINGLE,  0,   0  );
00256 vidl_pt_mac( YUYV_422, "YUYV 422",      vxl_byte,    16,  YUV,     PACKED,  1,   0  );
00257 vidl_pt_mac( UYVY_422, "UYVY 422",      vxl_byte,    16,  YUV,     PACKED,  1,   0  );
00258 vidl_pt_mac( UYVY_411, "UYVY 411",      vxl_byte,    12,  YUV,     PACKED,  2,   0  );
00259 
00260 vidl_pt_mac( MONO_1,   "Mono 1",        bool,        1,   MONO,    SINGLE,  0,   0  );
00261 vidl_pt_mac( MONO_8,   "Mono 8",        vxl_byte,    8,   MONO,    SINGLE,  0,   0  );
00262 vidl_pt_mac( MONO_16,  "Mono 16",       vxl_uint_16, 16,  MONO,    SINGLE,  0,   0  );
00263 vidl_pt_mac( MONO_F32, "Mono float 32", vxl_ieee_32, 32,  MONO,    SINGLE,  0,   0  );
00264 vidl_pt_mac( RGB_F32,  "RGB float 32",  vxl_ieee_32, 96,  RGB,     SINGLE,  0,   0  );
00265 vidl_pt_mac( RGB_F32P, "RGB float 32P", vxl_ieee_32, 96,  RGB,     PLANAR,  0,   0  );
00266 
00267 #undef vidl_pt_mac
00268 
00269 
00270 //: Define the packing order for each packed vidl_pixel_format
00271 // The main purpose of this struct is to define a static
00272 // array of pointer offsets to describe the packing.
00273 //
00274 // The array vidl_pixel_pack_of<format>::offset is a 2D array
00275 // of pointer offsets from the start of the macro pixel.  The
00276 // size of the array is macro-pixel-size by number-of-channels.
00277 // The value offset[i][j] gives the offset to the jth channel
00278 // of the ith pixel in the current macro-pixel.  For example,
00279 // offset[1][0] gives the 'Y' channel (if YUV) or 'R' channel
00280 // (if RGB) of the second pixel in the macro pixel
00281 //
00282 // \note the offset arrays are defined in vidl_pixel_format.cxx
00283 template <vidl_pixel_format pix_type>
00284 struct vidl_pixel_pack_of;
00285 #define vidl_pp_mac(FMT)\
00286 VCL_DEFINE_SPECIALIZATION \
00287 struct vidl_pixel_pack_of<VIDL_PIXEL_FORMAT_##FMT> \
00288 {\
00289   enum { macro_pix_size = 1<<vidl_pixel_traits_of<VIDL_PIXEL_FORMAT_##FMT>::chroma_shift_x }; \
00290   enum { num_channels = vidl_pixel_traits_of<VIDL_PIXEL_FORMAT_##FMT>::num_channels }; \
00291   static const vcl_ptrdiff_t offset[macro_pix_size][num_channels]; \
00292 }
00293 
00294 vidl_pp_mac( YUYV_422 );
00295 vidl_pp_mac( UYVY_422 );
00296 vidl_pp_mac( UYVY_411 );
00297 
00298 #undef vidl_pp_mac
00299 
00300 
00301 //=============================================================================
00302 // The following functions provide runtime lookup of pixel traits
00303 // These use template metaprogramming to generate the conditionals to
00304 // check the traits of each vidl_pixel_format.  You do not need to
00305 // modify the function definitions when adding new types.
00306 
00307 
00308 //: Return the number of channels needed in a color mode
00309 unsigned
00310 vidl_pixel_color_num_channels(vidl_pixel_color c);
00311 
00312 
00313 //: Return the set of traits for pixel format f
00314 vidl_pixel_traits
00315 vidl_pixel_format_traits(vidl_pixel_format f);
00316 
00317 
00318 //: Return the typeid of the pixel format datatype
00319 inline const vcl_type_info&
00320 vidl_pixel_format_typeid(vidl_pixel_format f)
00321 {
00322   return *vidl_pixel_format_traits(f).type;
00323 }
00324 
00325 //: Return the effective number of bits per image pixel in pixel format f
00326 inline unsigned
00327 vidl_pixel_format_bpp(vidl_pixel_format f)
00328 {
00329   return vidl_pixel_format_traits(f).bits_per_pixel;
00330 }
00331 
00332 
00333 //: Return the number of color channels encoded in pixel format f
00334 inline unsigned
00335 vidl_pixel_format_num_channels(vidl_pixel_format f)
00336 {
00337   return vidl_pixel_format_traits(f).num_channels;
00338 }
00339 
00340 
00341 //: Return the color encoding for the pixel format
00342 inline vidl_pixel_color
00343 vidl_pixel_format_color(vidl_pixel_format f)
00344 {
00345   return vidl_pixel_format_traits(f).color;
00346 }
00347 
00348 
00349 //: Return the pixel arrangement for a given format
00350 inline vidl_pixel_arrangement
00351 vidl_pixel_format_arrangement(vidl_pixel_format f)
00352 {
00353   return vidl_pixel_format_traits(f).arrangement;
00354 }
00355 
00356 
00357 //: Return the chroma shift in the horizontal direction
00358 inline unsigned
00359 vidl_pixel_format_chroma_shift_x(vidl_pixel_format f)
00360 {
00361   return vidl_pixel_format_traits(f).chroma_shift_x;
00362 }
00363 
00364 
00365 //: Return the chroma shift in the vertical direction
00366 inline unsigned
00367 vidl_pixel_format_chroma_shift_y(vidl_pixel_format f)
00368 {
00369   return vidl_pixel_format_traits(f).chroma_shift_y;
00370 }
00371 
00372 
00373 //: Output a pretty string representing the pixel format.
00374 vcl_ostream &
00375 operator << (vcl_ostream &os, vidl_pixel_format f);
00376 
00377 
00378 //: Convert a string into a pixel format.
00379 inline vcl_string
00380 vidl_pixel_format_to_string(vidl_pixel_format f)
00381 {
00382   return vidl_pixel_format_traits(f).name;
00383 }
00384 
00385 
00386 //: Convert a string into a pixel format.
00387 vidl_pixel_format
00388 vidl_pixel_format_from_string(const vcl_string& s);
00389 
00390 
00391 //: Compute the size (in bytes) of a \a ni x \a nj image buffer of pixel format \a f
00392 unsigned
00393 vidl_pixel_format_buffer_size(unsigned ni, unsigned nj, vidl_pixel_format f);
00394 
00395 #endif // vidl_pixel_format_h_