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

vidl2_pixel_format.cxx

Go to the documentation of this file.
00001 // This is brl/bbas/vidl2/vidl2_pixel_format.cxx
00002 #include "vidl2_pixel_format.h"
00003 //:
00004 // \file
00005 // \author Matt Leotta
00006 //
00007 #include <vcl_iostream.h>
00008 
00009 #define vidl2_ppi_mac(FMT)\
00010 const vcl_ptrdiff_t vidl2_pixel_pack_of<VIDL2_PIXEL_FORMAT_##FMT>::offset[macro_pix_size][num_channels]
00011 
00012 // Define the packing order for each packed vidl2_pixel_format
00013 // The main purpose of this struct is to define a static
00014 // array of pointer offsets to describe the packing.
00015 //
00016 // The array vidl2_pixel_pack_of<format>::offset is a 2D array
00017 // of pointer offsets from the start of the macro pixel.  The
00018 // size of the array is macro-pixel-size by number-of-channels.
00019 // The value offset[i][j] gives the offset to the jth channel
00020 // of the ith pixel in the current macro-pixel.  For example,
00021 // offset[1][0] gives the 'Y' channel (if YUV) or 'R' channel
00022 // (if RGB) of the second pixel in the macro pixel
00023 
00024 vidl2_ppi_mac(YUYV_422) = {{0,1,3},{2,1,3}};
00025 vidl2_ppi_mac(UYVY_422) = {{1,0,2},{3,0,2}};
00026 vidl2_ppi_mac(UYVY_411) = {{1,0,3},{2,0,3},{4,0,3},{5,0,3}};
00027 
00028 #undef vidl2_ppi_mac
00029 
00030 
00031 //=============================================================================
00032 
00033 //: Recursive template metaprogram to generate conditionals for checking the traits of each defined pixel type
00034 template <vidl2_pixel_format pix_type>
00035 struct check_types
00036 {
00037   static inline
00038   void traits(vidl2_pixel_format f, vidl2_pixel_traits& t)
00039   {
00040     if (f == pix_type){
00041       t.name           = vidl2_pixel_traits_of<pix_type>::name();
00042       t.bits_per_pixel = vidl2_pixel_traits_of<pix_type>::bits_per_pixel;
00043       t.num_channels   = vidl2_pixel_traits_of<pix_type>::num_channels;
00044       t.color          = vidl2_pixel_traits_of<pix_type>::color();
00045       t.arrangement    = vidl2_pixel_traits_of<pix_type>::arrangement();
00046       t.chroma_shift_x = vidl2_pixel_traits_of<pix_type>::chroma_shift_x;
00047       t.chroma_shift_y = vidl2_pixel_traits_of<pix_type>::chroma_shift_y;
00048     }
00049     else
00050       check_types<vidl2_pixel_format(pix_type-1)>::traits(f,t);
00051   }
00052 
00053   static inline vidl2_pixel_format from_string(const vcl_string& s)
00054   {
00055     if (s == vidl2_pixel_traits_of<pix_type>::name())
00056       return pix_type;
00057     return check_types<vidl2_pixel_format(pix_type-1)>::from_string(s);
00058   }
00059 
00060 };
00061 
00062 
00063 //: The base case: unknown pixel type
00064 VCL_DEFINE_SPECIALIZATION
00065 struct check_types<VIDL2_PIXEL_FORMAT_UNKNOWN>
00066 {
00067   static inline
00068   void traits(vidl2_pixel_format f, vidl2_pixel_traits& t)
00069   {
00070     t.name           = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::name();
00071     t.bits_per_pixel = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::bits_per_pixel;
00072     t.num_channels   = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::num_channels;
00073     t.color          = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::color();
00074     t.arrangement    = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::arrangement();
00075     t.chroma_shift_x = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::chroma_shift_x;
00076     t.chroma_shift_y = vidl2_pixel_traits_of<VIDL2_PIXEL_FORMAT_UNKNOWN>::chroma_shift_y;
00077   }
00078 
00079   static inline vidl2_pixel_format from_string(const vcl_string& s)
00080   {
00081     return VIDL2_PIXEL_FORMAT_UNKNOWN;
00082   }
00083 
00084 };
00085 
00086 
00087 //=============================================================================
00088 
00089 //: Return the number of channels needed in a color mode
00090 unsigned
00091     vidl2_pixel_color_num_channels(vidl2_pixel_color c)
00092 {
00093   switch(c){
00094     case VIDL2_PIXEL_COLOR_MONO:
00095       return vidl2_color_traits_of<VIDL2_PIXEL_COLOR_MONO>::num_channels;
00096     case VIDL2_PIXEL_COLOR_RGB:
00097       return vidl2_color_traits_of<VIDL2_PIXEL_COLOR_RGB>::num_channels;
00098     case VIDL2_PIXEL_COLOR_YUV:
00099       return vidl2_color_traits_of<VIDL2_PIXEL_COLOR_YUV>::num_channels;
00100     case VIDL2_PIXEL_COLOR_RGBA:
00101       return vidl2_color_traits_of<VIDL2_PIXEL_COLOR_RGBA>::num_channels;
00102     default:
00103       break;
00104   }
00105   return vidl2_color_traits_of<VIDL2_PIXEL_COLOR_UNKNOWN>::num_channels;
00106 }
00107 
00108 
00109 //: Return the set of traits for pixel format f
00110 vidl2_pixel_traits
00111 vidl2_pixel_format_traits(vidl2_pixel_format f)
00112 {
00113   // Template metaprogramming automatically generates the conditions
00114   // to check each enum value from VIDL2_PIXEL_FORMAT_UNKNOWN
00115   // to VIDL2_PIXEL_FORMAT_ENUM_END-1
00116   vidl2_pixel_traits t;
00117   check_types<vidl2_pixel_format(VIDL2_PIXEL_FORMAT_ENUM_END-1)>::traits(f,t);
00118   return t;
00119 }
00120 
00121 
00122 //: Output a pretty string representing the pixel format.
00123 vcl_ostream & operator << (vcl_ostream &os, vidl2_pixel_format f)
00124 {
00125   // Template metaprogramming automatically generates the conditions
00126   // to check each enum value from VIDL2_PIXEL_FORMAT_UNKNOWN
00127   // to VIDL2_PIXEL_FORMAT_ENUM_END-1
00128   os << vidl2_pixel_format_traits(f).name;
00129   return os;
00130 }
00131 
00132 
00133 //: Convert a string into a pixel format.
00134 // This uses the same encoding as operator<<.
00135 vidl2_pixel_format vidl2_pixel_format_from_string(const vcl_string& s)
00136 {
00137   // Template metaprogramming automatically generates the conditions
00138   // to check each enum value from VIDL2_PIXEL_FORMAT_UNKNOWN
00139   // to VIDL2_PIXEL_FORMAT_ENUM_END-1
00140   return check_types<vidl2_pixel_format(VIDL2_PIXEL_FORMAT_ENUM_END-1)>::from_string(s);
00141 }
00142 
00143 
00144 //: Compute the size (in bytes) of a \a ni x \a nj image buffer of pixel format \a f
00145 unsigned
00146 vidl2_pixel_format_buffer_size(unsigned ni, unsigned nj, vidl2_pixel_format f)
00147 {
00148   // FIXME This may be incorrect for some formats that require blocks
00149   // of macro pixels when the size of the image is not evenly divisible
00150   // by the size of the block.
00151   unsigned long bits = ((unsigned long)ni)*nj*vidl2_pixel_format_bpp(f);
00152   return (bits + 7)/8;
00153 }

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