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

vidl2_convert.cxx

Go to the documentation of this file.
00001 // This is brl/bbas/vidl2/vidl2_convert.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author Matt Leotta
00008 // \date   20 Jan 2006
00009 //
00010 //-----------------------------------------------------------------------------
00011 
00012 #include "vidl2_convert.h"
00013 #include "vidl2_frame.h"
00014 #include "vidl2_pixel_format.h"
00015 #include "vidl2_pixel_iterator.txx"
00016 #include "vidl2_color.h"
00017 #include <vil/vil_convert.h>
00018 #include <vil/vil_memory_chunk.h>
00019 #include <vcl_cstring.h>
00020 #include <vcl_cassert.h>
00021 #include <vcl_memory.h>
00022 
00023 //--------------------------------------------------------------------------------
00024 
00025 
00026 namespace {
00027 
00028 //: Define the function pointer for pixel format conversion functions
00029 typedef bool (*converter_func)(const vidl2_frame& in_frame, vidl2_frame& out_frame);
00030 
00031 
00032 //: Default pixel format conversion - it fails
00033 bool default_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame)
00034 {
00035   vcl_cerr << "No routine to convert " << in_frame.pixel_format()
00036            << " to " << out_frame.pixel_format() << vcl_endl;
00037   return false;
00038 }
00039 
00040 
00041 //: Use memcpy when the formats are the same
00042 bool copy_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame)
00043 {
00044   assert(in_frame.pixel_format() == out_frame.pixel_format());
00045   assert(in_frame.size() == out_frame.size());
00046   vcl_memcpy(out_frame.data(), in_frame.data(), in_frame.size());
00047   return true;
00048 }
00049 
00050 
00051 //: Convert to an intermediate RGB_24 frame
00052 // This is inefficient, but will provide the functionality until
00053 // an optimized version is written
00054 // defined later because it uses conversion_table
00055 bool intermediate_rgb24_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame);
00056 
00057 
00058 // Default pixel format conversion - it fails
00059 template <vidl2_pixel_format in_Fmt, vidl2_pixel_format out_Fmt>
00060 struct convert
00061 {
00062   enum { defined = false };
00063   static inline bool apply(const vidl2_frame& /*in_frame*/,
00064                            vidl2_frame& /*out_frame*/)
00065   {
00066     return false;
00067   }
00068 };
00069 
00070 //=============================================================================
00071 // Start of generic pixel conversions
00072 
00073 
00074 //: The generic pixel conversion function
00075 bool convert_generic(const vidl2_frame& in_frame,
00076                      vidl2_frame& out_frame)
00077 {
00078   // create pixel iterators for each frame
00079   vcl_auto_ptr<vidl2_pixel_iterator> in_pitr(vidl2_make_pixel_iterator(in_frame));
00080   if(!in_pitr.get())
00081     return false;
00082   vcl_auto_ptr<vidl2_pixel_iterator> out_pitr(vidl2_make_pixel_iterator(out_frame));
00083   if(!out_pitr.get())
00084     return false;
00085 
00086   vidl2_pixel_iterator& in_itr = *in_pitr;
00087   vidl2_pixel_iterator& out_itr = *out_pitr;
00088 
00089   vidl2_pixel_traits in_t = vidl2_pixel_format_traits(in_frame.pixel_format());
00090   vidl2_pixel_traits out_t = vidl2_pixel_format_traits(out_frame.pixel_format());
00091 
00092   // find the color conversion function
00093   vidl2_color_conv_fptr color_conv =
00094       vidl2_color_converter_func( in_t.color,  in_t.bits_per_pixel,
00095                                   out_t.color, out_t.bits_per_pixel);
00096   if(!color_conv)
00097     return false;
00098 
00099   const unsigned int num_pix = in_frame.ni() * in_frame.nj();
00100   vxl_byte in_pixel[4], out_pixel[4]; // assume pixels are no more than 4 bytes
00101   for (unsigned int c=0; c<num_pix; ++c, ++in_itr, ++out_itr){
00102     in_itr.get_data(in_pixel);
00103     color_conv(in_pixel, out_pixel);
00104     out_itr.set_data(out_pixel);
00105   }
00106   return true;
00107 }
00108 
00109 
00110 //=============================================================================
00111 // Start of pixel conversion specializations
00112 // Write optimized conversion specializations below
00113 
00114 // RGB_24 to UYVY_422
00115 VCL_DEFINE_SPECIALIZATION
00116 struct convert<VIDL2_PIXEL_FORMAT_RGB_24, VIDL2_PIXEL_FORMAT_UYVY_422>
00117 {
00118   enum { defined = true };
00119   static inline bool apply(const vidl2_frame& in_frame,
00120                            vidl2_frame& out_frame)
00121   {
00122     assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24);
00123     assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_UYVY_422);
00124     const vxl_byte* rgb = reinterpret_cast<const vxl_byte*>(in_frame.data());
00125     vxl_byte* uyvy = reinterpret_cast<vxl_byte*>(out_frame.data());
00126     unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00127     for (unsigned int c=0; c<num_half_pix; ++c){
00128       const vxl_byte& r1 = *(rgb++);
00129       const vxl_byte& g1 = *(rgb++);
00130       const vxl_byte& b1 = *(rgb++);
00131       const vxl_byte& r2 = *(rgb++);
00132       const vxl_byte& g2 = *(rgb++);
00133       const vxl_byte& b2 = *(rgb++);
00134       vxl_byte y1,u1,v1,y2,u2,v2;
00135       vidl2_color_convert_rgb2yuv(r1,g1,b1,y1,u1,v1);
00136       vidl2_color_convert_rgb2yuv(r2,g2,b2,y2,u2,v2);
00137       *(uyvy++) = (u1+u2)/2;
00138       *(uyvy++) = y1;
00139       *(uyvy++) = (v1+v2)/2;
00140       *(uyvy++) = y2;
00141     }
00142     return true;
00143   }
00144 };
00145 
00146 
00147 // UYVY_422 to RGB_24
00148 VCL_DEFINE_SPECIALIZATION
00149 struct convert<VIDL2_PIXEL_FORMAT_UYVY_422, VIDL2_PIXEL_FORMAT_RGB_24>
00150 {
00151   enum { defined = true };
00152   static inline bool apply(const vidl2_frame& in_frame,
00153                            vidl2_frame& out_frame)
00154   {
00155     assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_UYVY_422);
00156     assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24);
00157     const vxl_byte* uyvy = reinterpret_cast<const vxl_byte*>(in_frame.data());
00158     vxl_byte* rgb = reinterpret_cast<vxl_byte*>(out_frame.data());
00159     unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00160     for (unsigned int c=0; c<num_half_pix; ++c){
00161       const vxl_byte& u1 = *(uyvy++);
00162       const vxl_byte& y1 = *(uyvy++);
00163       const vxl_byte& v1 = *(uyvy++);
00164       const vxl_byte& y2 = *(uyvy++);
00165       vxl_byte r,g,b;
00166       vidl2_color_convert_yuv2rgb(y1,u1,v1,r,g,b);
00167       *(rgb++) = r;
00168       *(rgb++) = g;
00169       *(rgb++) = b;
00170       vidl2_color_convert_yuv2rgb(y2,u1,v1,r,g,b);
00171       *(rgb++) = r;
00172       *(rgb++) = g;
00173       *(rgb++) = b;
00174     }
00175     return true;
00176   }
00177 };
00178 
00179 
00180 // UYVY_422 to MONO_8
00181 VCL_DEFINE_SPECIALIZATION
00182 struct convert<VIDL2_PIXEL_FORMAT_UYVY_422, VIDL2_PIXEL_FORMAT_MONO_8>
00183 {
00184   enum { defined = true };
00185   static inline bool apply(const vidl2_frame& in_frame,
00186                            vidl2_frame& out_frame)
00187   {
00188     assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_UYVY_422);
00189     assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_MONO_8);
00190     const vxl_byte* uyvy = reinterpret_cast<const vxl_byte*>(in_frame.data());
00191     vxl_byte* mono = reinterpret_cast<vxl_byte*>(out_frame.data());
00192     unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00193     for (unsigned int c=0; c<num_half_pix; ++c){
00194       ++uyvy;
00195       const vxl_byte& y1 = *(uyvy++);
00196       ++uyvy;
00197       const vxl_byte& y2 = *(uyvy++);
00198       *(mono++) = y1;
00199       *(mono++) = y2;
00200     }
00201     return true;
00202   }
00203 };
00204 
00205 
00206 
00207 // End of pixel conversion specializations
00208 //=============================================================================
00209 
00210 
00211 //: Generates an entry into the table of pixel format conversions functions
00212 // This is called for every pair for pixel formats to build the table
00213 template <vidl2_pixel_format in_Fmt, vidl2_pixel_format out_Fmt>
00214 struct table_entry_init
00215 {
00216   static inline void set_entry(converter_func& table_entry)
00217   {
00218     // This should be done at compile time with partial specialization
00219     // This run time code generates many functions that are never actually used
00220     if (in_Fmt == out_Fmt)
00221       table_entry = &copy_conversion;
00222     else if (convert<in_Fmt,out_Fmt>::defined)
00223       table_entry = &convert<in_Fmt,out_Fmt>::apply;
00224     else if (vidl2_pixel_iterator_valid<in_Fmt>::value &&
00225             vidl2_pixel_iterator_valid<out_Fmt>::value)
00226       table_entry = &convert_generic;
00227     else
00228       table_entry = &default_conversion;
00229   }
00230 };
00231 
00232 //: Recursive template metaprogram to generate conditionals for converting each pair of pixel types
00233 template <int Fmt_Code>
00234 struct table_init
00235 {
00236   static inline void populate(converter_func table[VIDL2_PIXEL_FORMAT_ENUM_END][VIDL2_PIXEL_FORMAT_ENUM_END])
00237   {
00238     const vidl2_pixel_format in_fmt = vidl2_pixel_format(Fmt_Code/VIDL2_PIXEL_FORMAT_ENUM_END);
00239     const vidl2_pixel_format out_fmt = vidl2_pixel_format(Fmt_Code%VIDL2_PIXEL_FORMAT_ENUM_END);
00240     table_entry_init<in_fmt,out_fmt>::set_entry(table[in_fmt][out_fmt]);
00241     table_init<Fmt_Code-1>::populate(table);
00242   }
00243 };
00244 
00245 
00246 //: The base case
00247 VCL_DEFINE_SPECIALIZATION
00248 struct table_init<0>
00249 {
00250   static inline void populate(converter_func table[VIDL2_PIXEL_FORMAT_ENUM_END][VIDL2_PIXEL_FORMAT_ENUM_END])
00251   {
00252     const vidl2_pixel_format in_fmt = vidl2_pixel_format(0);
00253     const vidl2_pixel_format out_fmt = vidl2_pixel_format(0);
00254     table_entry_init<in_fmt,out_fmt>::set_entry(table[in_fmt][out_fmt]);
00255   }
00256 };
00257 
00258 
00259 //: A table of all conversion functions
00260 class converter
00261 {
00262  public:
00263   //: Constructor - generate the table
00264   converter()
00265   {
00266     // generate the table of function pointers
00267     table_init<VIDL2_PIXEL_FORMAT_ENUM_END*VIDL2_PIXEL_FORMAT_ENUM_END-1>::populate(table);
00268   }
00269 
00270   //: Apply the conversion
00271   bool operator()(const vidl2_frame& in_frame, vidl2_frame& out_frame) const
00272   {
00273     return (*table[in_frame.pixel_format()][out_frame.pixel_format()])(in_frame, out_frame);
00274   }
00275  private:
00276   //: Table of conversion functions
00277   converter_func table[VIDL2_PIXEL_FORMAT_ENUM_END][VIDL2_PIXEL_FORMAT_ENUM_END];
00278 };
00279 
00280 //: Instantiate a global conversion function table
00281 converter conversion_table;
00282 
00283 //: Convert to an intermediate RGB_24 frame
00284 // Defined here because it uses conversion_table
00285 bool intermediate_rgb24_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame)
00286 {
00287   unsigned int ni = in_frame.ni(), nj = in_frame.nj();
00288   vil_memory_chunk_sptr memory = new vil_memory_chunk(ni*nj*3, VIL_PIXEL_FORMAT_BYTE);
00289   vidl2_memory_chunk_frame temp_frame(ni,nj,VIDL2_PIXEL_FORMAT_RGB_24,memory);
00290   return conversion_table(in_frame, temp_frame) &&
00291       conversion_table(temp_frame, out_frame);
00292 }
00293 
00294 } // end anonymous namespace
00295 
00296 //--------------------------------------------------------------------------------
00297 
00298 //: Convert the pixel format of a frame
00299 //
00300 // The \p in_frame->data() is converted from \p in_frame->pixel_format()
00301 // to \p out_frame->pixel_format() and stored in \p out_frame->data()
00302 // \returns false if the output frame data is not the correct size.
00303 bool vidl2_convert_frame(const vidl2_frame& in_frame,
00304                                vidl2_frame& out_frame)
00305 {
00306   vidl2_pixel_format in_fmt = in_frame.pixel_format();
00307   vidl2_pixel_format out_fmt = out_frame.pixel_format();
00308 
00309   if (in_fmt == VIDL2_PIXEL_FORMAT_UNKNOWN ||
00310      out_fmt == VIDL2_PIXEL_FORMAT_UNKNOWN)
00311     return false;
00312 
00313   unsigned ni = in_frame.ni();
00314   unsigned nj = in_frame.nj();
00315   unsigned out_size = vidl2_pixel_format_buffer_size(ni,nj,out_fmt);
00316 
00317   if (out_frame.size() != out_size ||
00318      out_frame.ni() != ni ||
00319      out_frame.nj() != nj ||
00320      !out_frame.data() )
00321     return false;
00322 
00323   // call the appropriate function in the conversion table
00324   return conversion_table(in_frame, out_frame);
00325 }
00326 
00327 
00328 //: Convert the pixel format of a frame
00329 //
00330 // The convert \p in_frame to a \p format by allocating
00331 // a new frame buffer
00332 vidl2_frame_sptr vidl2_convert_frame(const vidl2_frame_sptr& in_frame,
00333                                      vidl2_pixel_format format)
00334 {
00335   if (format == VIDL2_PIXEL_FORMAT_UNKNOWN)
00336     return NULL;
00337 
00338   unsigned ni = in_frame->ni();
00339   unsigned nj = in_frame->nj();
00340   unsigned size = vidl2_pixel_format_buffer_size(ni,nj,format);
00341   vil_memory_chunk_sptr memory = new vil_memory_chunk(size, VIL_PIXEL_FORMAT_BYTE);
00342   vidl2_frame_sptr out_frame = new vidl2_memory_chunk_frame(ni, nj, format, memory);
00343 
00344   if (vidl2_convert_frame(*in_frame, *out_frame))
00345     return out_frame;
00346 
00347   return NULL;
00348 }
00349 
00350 
00351 //: Convert the image view to a frame
00352 // Will wrap the memory if possible, if not the image is converted to
00353 // the closest vidl2_pixel_format
00354 vidl2_frame_sptr vidl2_convert_to_frame(const vil_image_view_base_sptr& image)
00355 {
00356   if(!image)
00357     return NULL;
00358 
00359   // try to wrap the image memory in a frame
00360   vidl2_frame_sptr frame = new vidl2_memory_chunk_frame(*image);
00361   if(frame->pixel_format() != VIDL2_PIXEL_FORMAT_UNKNOWN)
00362     return frame;
00363 
00364   // if the image could not be wrapped convert it
00365   unsigned ni = image->ni(), nj = image->nj(), np = image->nplanes();
00366 
00367   // special case for 16 bit images
00368   if(image->pixel_format() == VIL_PIXEL_FORMAT_UINT_16)
00369   {
00370     if(np != 1)
00371       return NULL;
00372     vil_image_view<vxl_uint_16> img(ni,nj);
00373     img.deep_copy(vil_image_view<vxl_uint_16>(*image));
00374     return new vidl2_memory_chunk_frame(ni, nj, VIDL2_PIXEL_FORMAT_MONO_16,
00375                                         img.memory_chunk());
00376   }
00377 
00378   vidl2_pixel_format format = VIDL2_PIXEL_FORMAT_UNKNOWN;
00379   if(np == 1)
00380     format = VIDL2_PIXEL_FORMAT_MONO_8;
00381   else if(np == 3)
00382     format = VIDL2_PIXEL_FORMAT_RGB_24P;
00383   else if(np == 4)
00384     format = VIDL2_PIXEL_FORMAT_RGBA_32P;
00385   else
00386     return NULL;
00387 
00388   vil_image_view<vxl_byte> img;
00389   if(image->pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00390     img.deep_copy(vil_image_view<vxl_byte>(*image));
00391   else
00392   {
00393     vil_image_view_base_sptr bimage = vil_convert_cast(vxl_byte(),image);
00394     if(!bimage)
00395       return NULL;
00396     img = *bimage;
00397   }
00398   return new vidl2_memory_chunk_frame(ni, nj, format,
00399                                       img.memory_chunk());
00400 
00401 }
00402 
00403 
00404 //: convert the frame into an image view
00405 // possibly converts the pixel data type
00406 // always create a deep copy of the data
00407 bool vidl2_convert_to_view(const vidl2_frame& frame,
00408                            vil_image_view_base& image,
00409                            vidl2_pixel_color require_color)
00410 {
00411   if (frame.pixel_format() == VIDL2_PIXEL_FORMAT_UNKNOWN ||
00412       frame.data() == NULL)
00413     return false;
00414 
00415   vidl2_pixel_color in_color = vidl2_pixel_format_color(frame.pixel_format());
00416   if(require_color == VIDL2_PIXEL_COLOR_UNKNOWN)
00417     require_color = in_color;
00418 
00419   unsigned ni = frame.ni(), nj = frame.nj();
00420   unsigned np = vidl2_pixel_color_num_channels(require_color);
00421 
00422   // resize the image if necessary
00423   image.set_size(ni,nj,np);
00424 
00425   // special case for MONO_16
00426   if(frame.pixel_format() == VIDL2_PIXEL_FORMAT_MONO_16){
00427     vil_image_view<vxl_uint_16> wrapper(static_cast<const vxl_uint_16*>(frame.data()),
00428                                         ni,nj,1,1,ni,ni*nj);
00429     if(image.pixel_format() == VIL_PIXEL_FORMAT_UINT_16){
00430       vil_image_view<vxl_uint_16>& img = static_cast<vil_image_view<vxl_uint_16>&>(image);
00431       img.deep_copy(vil_image_view<vxl_uint_16>(wrapper));
00432       return true;
00433     }
00434 
00435     switch ( vil_pixel_format_component_format(image.pixel_format()) ){
00436 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00437 #define macro(F , T) \
00438     case F: {\
00439       vil_image_view<T> & dest_ref = static_cast<vil_image_view<T> &>(image); \
00440       vil_convert_cast( wrapper, dest_ref); break;}
00441 
00442 #if VXL_HAS_INT_64
00443     macro( VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64 );
00444     macro( VIL_PIXEL_FORMAT_INT_64, vxl_int_64 );
00445 #endif
00446     macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 );
00447     macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 );
00448     macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 );
00449     macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte );
00450     macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte );
00451     macro( VIL_PIXEL_FORMAT_FLOAT, float );
00452     macro( VIL_PIXEL_FORMAT_DOUBLE, double );
00453     macro( VIL_PIXEL_FORMAT_BOOL, bool );
00454 #undef macro
00455 #endif // DOXYGEN_SHOULD_SKIP_THIS
00456       default:
00457         return false;
00458     }
00459     return true;
00460   }
00461 
00462 
00463 
00464   vidl2_pixel_format default_format = VIDL2_PIXEL_FORMAT_UNKNOWN;
00465   if(image.pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00466   {
00467     vil_image_view<vxl_byte>& img = static_cast<vil_image_view<vxl_byte>&>(image);
00468     bool interleaved = (img.planestep() == 1);
00469 
00470     switch(require_color){
00471       case VIDL2_PIXEL_COLOR_MONO:
00472         default_format = VIDL2_PIXEL_FORMAT_MONO_8; break;
00473       case VIDL2_PIXEL_COLOR_RGB:
00474         default_format = interleaved?VIDL2_PIXEL_FORMAT_RGB_24
00475                                     :VIDL2_PIXEL_FORMAT_RGB_24P; break;
00476       case VIDL2_PIXEL_COLOR_RGBA:
00477         default_format = interleaved?VIDL2_PIXEL_FORMAT_RGBA_32
00478                                     :VIDL2_PIXEL_FORMAT_RGBA_32P; break;
00479       case VIDL2_PIXEL_COLOR_YUV:
00480         default_format = interleaved?VIDL2_PIXEL_FORMAT_UYV_444
00481                                     :VIDL2_PIXEL_FORMAT_YUV_444P; break;
00482       default:
00483         break;
00484     }
00485   }
00486 
00487 
00488   vidl2_frame_sptr out_frame = new vidl2_memory_chunk_frame(image,default_format);
00489   // if the image can be wrapped as a frame
00490   if(out_frame->pixel_format() != VIDL2_PIXEL_FORMAT_UNKNOWN){
00491     vidl2_convert_frame(frame, *out_frame);
00492     return true;
00493   }
00494 
00495   // use an intermediate format
00496   vidl2_pixel_format out_fmt;
00497   switch(in_color){
00498     case VIDL2_PIXEL_COLOR_MONO:
00499       out_fmt = VIDL2_PIXEL_FORMAT_MONO_8; break;
00500     case VIDL2_PIXEL_COLOR_RGB:
00501       out_fmt = VIDL2_PIXEL_FORMAT_RGB_24P; break;
00502     case VIDL2_PIXEL_COLOR_RGBA:
00503       out_fmt = VIDL2_PIXEL_FORMAT_RGBA_32P; break;
00504     case VIDL2_PIXEL_COLOR_YUV:
00505       out_fmt = VIDL2_PIXEL_FORMAT_YUV_444P; break;
00506     default:
00507       return false;
00508   }
00509 
00510   vil_image_view<vxl_byte> temp(ni,nj,np);
00511   out_frame = new vidl2_memory_chunk_frame(ni,nj,out_fmt,temp.memory_chunk());
00512   vidl2_convert_frame(frame, *out_frame);
00513 
00514   switch ( vil_pixel_format_component_format(image.pixel_format()) ){
00515 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00516 #define macro(F , T) \
00517     case F: {\
00518       vil_image_view<T> & dest_ref = static_cast<vil_image_view<T> &>(image); \
00519       vil_convert_cast( temp, dest_ref); break;}
00520 
00521 #if VXL_HAS_INT_64
00522     macro( VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64 );
00523     macro( VIL_PIXEL_FORMAT_INT_64, vxl_int_64 );
00524 #endif
00525     macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 );
00526     macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 );
00527     macro( VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16 );
00528     macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 );
00529     macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte );
00530     macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte );
00531     macro( VIL_PIXEL_FORMAT_FLOAT, float );
00532     macro( VIL_PIXEL_FORMAT_DOUBLE, double );
00533     macro( VIL_PIXEL_FORMAT_BOOL, bool );
00534 #undef macro
00535 #endif // DOXYGEN_SHOULD_SKIP_THIS
00536     default:
00537       return false;
00538   }
00539   return true;
00540 }
00541 
00542 
00543 //: Wrap the frame buffer in an image view if supported
00544 // Returns a null pointer if not possible
00545 vil_image_view_base_sptr
00546 vidl2_convert_wrap_in_view(const vidl2_frame& frame)
00547 {
00548   vidl2_pixel_format format = frame.pixel_format();
00549   vidl2_pixel_traits pt =  vidl2_pixel_format_traits(format);
00550   if( pt.chroma_shift_x != 0 || pt.chroma_shift_y != 0 ||
00551       pt.bits_per_pixel % pt.num_channels != 0)
00552     return NULL;
00553 
00554   unsigned ni = frame.ni(), nj = frame.nj();
00555   unsigned np = pt.num_channels;
00556   vcl_ptrdiff_t i_step, j_step, p_step;
00557   switch(pt.arrangement){
00558     case VIDL2_PIXEL_ARRANGE_SINGLE:
00559       i_step = np;
00560       j_step = np*ni;
00561       p_step = 1;
00562       break;
00563     case VIDL2_PIXEL_ARRANGE_PLANAR:
00564       i_step = 1;
00565       j_step = ni;
00566       p_step = ni*nj;
00567       break;
00568     default:
00569       // Cannot wrap other pixel arrangements
00570       return NULL;
00571   }
00572   vcl_ptrdiff_t top_left_offset = 0;
00573 
00574   if(format == VIDL2_PIXEL_FORMAT_BGR_24){
00575     top_left_offset = 3;
00576     p_step = -1;
00577   }
00578 
00579   // Create a view of a memory chunk frame
00580   if( const vidl2_memory_chunk_frame* cf =
00581       dynamic_cast<const vidl2_memory_chunk_frame*>(&frame) )
00582   {
00583     vil_memory_chunk_sptr chunk = cf->memory_chunk();
00584     if(format == VIDL2_PIXEL_FORMAT_MONO_16){
00585       const vxl_uint_16* top_left = static_cast<const vxl_uint_16*>(cf->data()) + top_left_offset;
00586       return new vil_image_view<vxl_uint_16>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00587     }
00588     else if(format == VIDL2_PIXEL_FORMAT_MONO_1){
00589       const bool* top_left = static_cast<const bool*>(cf->data()) + top_left_offset;
00590       return new vil_image_view<bool>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00591     }
00592     const vxl_byte* top_left = static_cast<const vxl_byte*>(cf->data()) + top_left_offset;
00593     return new vil_image_view<vxl_byte>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00594   }
00595 
00596   // Create a view of a frame (without ownership of the data)
00597   if(format == VIDL2_PIXEL_FORMAT_MONO_16){
00598     const vxl_uint_16* top_left = static_cast<const vxl_uint_16*>(frame.data()) + top_left_offset;
00599     return new vil_image_view<vxl_uint_16>(top_left, ni,nj,np, i_step,j_step,p_step);
00600   }
00601   else if(format == VIDL2_PIXEL_FORMAT_MONO_1){
00602     const bool* top_left = static_cast<const bool*>(frame.data()) + top_left_offset;
00603     return new vil_image_view<bool>(top_left, ni,nj,np, i_step,j_step,p_step);
00604   }
00605   const vxl_byte* top_left = static_cast<const vxl_byte*>(frame.data()) + top_left_offset;
00606   return new vil_image_view<vxl_byte>(top_left, ni,nj,np, i_step,j_step,p_step);
00607 }

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