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

vimt_vil_v2i.cxx

Go to the documentation of this file.
00001 //:
00002 // \file
00003 
00004 #include "vimt_vil_v2i.h"
00005 
00006 #include <vcl_cassert.h>
00007 #include <vcl_cstring.h>
00008 #include <vcl_fstream.h>
00009 
00010 #include <vxl_config.h> // for VXL_BIG_ENDIAN and vxl_byte
00011 
00012 #include <vil/vil_exception.h>
00013 #include <vil/vil_property.h>
00014 #include <vil/vil_copy.h>
00015 #include <vil/vil_stream.h>
00016 #include <vil/vil_stream_fstream.h>
00017 #include <vil/vil_image_resource.h>
00018 #include <vil/vil_image_view.h>
00019 #include <vsl/vsl_binary_io.h>
00020 #include <vsl/vsl_binary_loader.h>
00021 #include <vimt/vimt_image_2d_of.h>
00022 
00023 // v2i magic number
00024 const unsigned V2I_MAGIC = 987123872U;
00025 
00026 
00027 class vimt_vil_fstream: vil_stream_fstream
00028 {
00029 protected:
00030   vcl_fstream& underlying_stream() { return vil_stream_fstream::underlying_stream(); }
00031   friend class vimt_vil_v2i_format;
00032   friend class vimt_vil_v2i_image;
00033 private:
00034   vimt_vil_fstream(): vil_stream_fstream("", "") {} // Will never be constructed
00035 };
00036 
00037 
00038 
00039 vil_image_resource_sptr vimt_vil_v2i_format::make_input_image(vil_stream* vs)
00040 {
00041   // First of all hack an vil_stream to get at the underlying
00042   // vcl_stream, in order to create a vsl_b_stream
00043   if (typeid(*vs) != typeid(vil_stream_fstream))
00044   {
00045     vcl_cerr << "vimt_vil_v2i_format::make_input_image() WARNING\n"
00046              << "  Unable to deal with stream type" << vcl_endl;
00047 
00048     return 0;
00049   }
00050   vsl_b_istream vslstream( &reinterpret_cast<vimt_vil_fstream *>(vs)->underlying_stream() );
00051   if (!vslstream) return 0; // Not even a vsl file.
00052   unsigned magic;
00053   vil_streampos start = vs->tell();
00054   vsl_b_read(vslstream, magic);
00055   if (magic == V2I_MAGIC)
00056     return new vimt_vil_v2i_image(vs);
00057 
00058   // This vsl stream may hav been created with vsl_b_wrte(vimt_image) - with no
00059   //  v2i magic number. Check if that is true.
00060   vs->seek(start);
00061   int v_i;
00062   bool v_b;
00063   vsl_b_read(vslstream, v_i);  // vimt_image_2d_of.version
00064   vsl_b_read(vslstream, v_i);  // vil_image_view.version
00065   if (v_i != 1) return 0; // can only handle version 1.
00066   vsl_b_read(vslstream, v_i);  // vil_image_view.ni
00067   if (v_i == 0) return 0; // can't handle empty images.
00068   vsl_b_read(vslstream, v_i);  // vil_image_view.nj
00069   if (v_i == 0) return 0; // can't handle empty images.
00070   vsl_b_read(vslstream, v_i);  // vil_image_view.nplanes
00071   if (v_i == 0) return 0; // can't handle empty images.
00072   vsl_b_read(vslstream, v_i);  // vil_image_view.istep
00073   vsl_b_read(vslstream, v_i);  // vil_image_view.jstep
00074   vsl_b_read(vslstream, v_i);  // vil_image_view.planestep
00075   vsl_b_read(vslstream, v_i);  // vil_smart_ptr.version
00076   if (v_i != 2) return 0; // can only handle version 2.
00077   vsl_b_read(vslstream, v_b);  // vil_smart_ptr.firsttime
00078   if (!v_b) return 0; // can't handle multiple images.
00079   vsl_b_read(vslstream, v_i);  // vil_smart_ptr.id
00080   if (v_i != 1) return 0; // can't handle multiple images.
00081   vsl_b_read(vslstream, v_b);  // vil_memory_chunk*.nonnull
00082   if (!v_b) return 0; // can't handle empty images.
00083   vsl_b_read(vslstream, v_i);  // vil_memory_chunk.version
00084   if (v_i != 2) return 0; // can only handle version 2.
00085   vsl_b_read(vslstream, v_i);  //  chunk.pixel_format
00086 
00087   vil_pixel_format f = static_cast<vil_pixel_format>(v_i);
00088   vs->seek(start);
00089   switch(f)
00090   {
00091 #define macro( F , T ) \
00092     case  F : \
00093     { vimt_image_2d_of< T > im; vsl_b_read(vslstream, im); if (!vslstream) return 0; } \
00094     break;
00095 // Don't include versions for which there is no template instantian of vimt_image_2d_of.
00096 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00097 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00098 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00099 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00100 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00101 //macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00102 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00103 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00104 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00105 #undef macro
00106     default: return 0; // Unknown pixel type - or more likely not a v2i image.
00107   }
00108   vs->seek(start);
00109   return new vimt_vil_v2i_image(vs, f);
00110 }
00111 
00112 vil_image_resource_sptr vimt_vil_v2i_format::make_output_image(vil_stream* vs,
00113                                                                unsigned ni,
00114                                                                unsigned nj,
00115                                                                unsigned nplanes,
00116                                                                vil_pixel_format format)
00117 {
00118   // First of all hack an vil_stream to get at the underlying
00119   // ccl_stream, in order to create a vsl_b_stream
00120   if (typeid(*vs) != typeid(vil_stream_fstream))
00121   {
00122     vcl_cerr << "vimt_vil_v2i_format::make_output_image() WARNING\n"
00123              << "  Unable to deal with stream type" << vcl_endl;
00124 
00125     return 0;
00126   }
00127   if ( format != VIL_PIXEL_FORMAT_BYTE && format != VIL_PIXEL_FORMAT_SBYTE &&
00128        format != VIL_PIXEL_FORMAT_UINT_32 && format != VIL_PIXEL_FORMAT_INT_32 &&
00129        format != VIL_PIXEL_FORMAT_UINT_16 && format != VIL_PIXEL_FORMAT_INT_16 &&
00130        format != VIL_PIXEL_FORMAT_FLOAT && format != VIL_PIXEL_FORMAT_DOUBLE &&
00131        format != VIL_PIXEL_FORMAT_BOOL)
00132   {
00133     vcl_cerr << "vimt_vil_v2i_format::make_output_image() WARNING\n"
00134              << "  Unable to deal with file format : " << format << vcl_endl;
00135     return 0;
00136   }
00137   return new vimt_vil_v2i_image(vs, ni, nj, nplanes, format);
00138 }
00139 
00140 
00141 /////////////////////////////////////////////////////////////////////////////
00142 
00143 vimt_vil_v2i_image::vimt_vil_v2i_image(vil_stream* vs):
00144   vs_(vs), im_(0), dirty_(false)
00145 {
00146   vs_->ref();
00147   vs_->seek(0L);
00148   vsl_b_istream vslstream(& reinterpret_cast<vimt_vil_fstream *>(vs_)->underlying_stream());
00149 
00150   unsigned magic;
00151   vsl_b_read(vslstream, magic);
00152   assert(magic == V2I_MAGIC);
00153 
00154   short version;
00155   vsl_b_read(vslstream, version);
00156 
00157   switch (version)
00158   {
00159   case 1:
00160     {
00161       vimt_image *p_im=0;
00162       vsl_b_read(vslstream, p_im);
00163       im_ = dynamic_cast<vimt_image_2d *>(p_im);
00164       break;
00165     }
00166   default:
00167     vcl_cerr << "I/O ERROR: vimt_vil_v2i_image::vimt_vil_v2i_image()\n"
00168       << "           Unknown version number "<< version << '\n';
00169     return;
00170   }
00171 }
00172 
00173 
00174 //: Constructor to deal with directly created v2i files.
00175 vimt_vil_v2i_image::vimt_vil_v2i_image(vil_stream* vs, vil_pixel_format f):
00176   vs_(vs), im_(0), dirty_(false)
00177 {
00178   vs_->ref();
00179   vs_->seek(0L);
00180   vsl_b_istream vslstream(& reinterpret_cast<vimt_vil_fstream *>(vs_)->underlying_stream());
00181 
00182   
00183   switch(f)
00184   {
00185 #define macro( F , T ) \
00186     case  F : \
00187     im_ = new vimt_image_2d_of< T >(); \
00188     vsl_b_read(vslstream, *static_cast<vimt_image_2d_of< T >*>(im_)); \
00189     break;
00190 // Don't include versions for which there is no template instantian of vimt_image_2d_of.
00191 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00192 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00193 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00194 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00195 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00196 //macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00197 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00198 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00199 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00200 #undef macro
00201     default: throw vil_exception_image_io("vimt_vil_v2i_image::vimt_vil_v2i_image",
00202       "v2i", "");
00203   }
00204 
00205   // Fiddle factor - most directly created vsl files have transforms in mm.
00206   vimt_transform_2d tr;
00207   tr.set_zoom_only(1000.0, 0.0, 0.0);
00208   im_->world2im() = im_->world2im() * tr;
00209   assert(! !vslstream);
00210   
00211 }
00212 
00213 bool vimt_vil_v2i_image::get_property(char const * key, void * value) const
00214 {
00215   const vimt_transform_2d &tr = im_->world2im();
00216 
00217   if (vcl_strcmp(vil_property_pixel_size, key)==0)
00218   {
00219     vgl_vector_2d<double> p11 = tr.inverse()(1.0, 1.0) - tr.inverse().origin();
00220     //Assume no rotation or shearing.
00221 
00222     float* array =  static_cast<float*>(value);
00223     array[0] = (float) p11.x();
00224     array[1] = (float) p11.y();
00225     return true;
00226   }
00227 
00228   if (vcl_strcmp(vil_property_offset, key)==0)
00229   {
00230     vgl_point_2d<double> origin = tr.origin();
00231     float* array =  static_cast<float*>(value);
00232     array[0] = (float)(origin.x());
00233     array[1] = (float)(origin.y());
00234     return true;
00235   }
00236 
00237   return false;
00238 }
00239 
00240 vimt_vil_v2i_image::vimt_vil_v2i_image(vil_stream* vs, unsigned ni, unsigned nj,
00241                                        unsigned nplanes, vil_pixel_format format):
00242   vs_(vs), im_(0), dirty_(true)
00243 {
00244   vs_->ref();
00245   switch (format)
00246   {
00247 #define macro( F , T ) \
00248    case  F : \
00249     im_ = new vimt_image_2d_of< T > (ni, nj, nplanes); \
00250     break;
00251 // Don't include versions for which there is no template instantian of vimt_image_2d_of.
00252 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00253 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00254 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00255 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00256 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00257 //macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00258 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00259 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00260 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00261 #undef macro
00262    default:
00263     vcl_cerr << "I/O ERROR: vimt_vil_v2i_image::vimt_vil_v2i_image()\n"
00264              << "           Unknown vil_pixel_format "<< format << '\n';
00265     vcl_abort();
00266   }
00267 }
00268 
00269 
00270 vimt_vil_v2i_image::~vimt_vil_v2i_image()
00271 {
00272   if (dirty_)
00273   {
00274     vs_->seek(0l);
00275     vsl_b_ostream vslstream(& reinterpret_cast<vimt_vil_fstream *>(vs_)->underlying_stream());
00276  
00277     vsl_b_write(vslstream, V2I_MAGIC);
00278 
00279     const short version = 1;
00280     vsl_b_write(vslstream, version);
00281 
00282 
00283     vimt_image *p_im=im_;
00284     vsl_b_write(vslstream, p_im);
00285   }
00286   //delete vs_;
00287   vs_->unref();
00288   delete im_;
00289 }
00290 
00291 //: Dimensions:  nplanes x ni x nj.
00292 // This concept is treated as a synonym to components.
00293 unsigned vimt_vil_v2i_image::nplanes() const
00294 {
00295   return im_->image_base().nplanes();
00296 }
00297 
00298 //: Dimensions:  nplanes x ni x nj.
00299 // The number of pixels in each row.
00300 unsigned vimt_vil_v2i_image::ni() const
00301 {
00302   return im_->image_base().ni();
00303 }
00304 
00305 //: Dimensions:  nplanes x ni x nj.
00306 // The number of pixels in each column.
00307 unsigned vimt_vil_v2i_image::nj() const
00308 {
00309   return im_->image_base().nj();
00310 }
00311 
00312 //: Pixel Format.
00313 enum vil_pixel_format vimt_vil_v2i_image::pixel_format() const
00314 {
00315   return im_->image_base().pixel_format();
00316 }
00317 
00318 
00319 const vimt_transform_2d & vimt_vil_v2i_image::world2im() const
00320 {
00321   return im_->world2im();
00322 }
00323 
00324 void vimt_vil_v2i_image::set_world2im(const vimt_transform_2d & tr)
00325 {
00326   im_->set_world2im(tr);
00327   dirty_ = true;
00328 }
00329 
00330 //: Set the size of the each pixel in the i,j,k directions.
00331 void vimt_vil_v2i_image::set_pixel_size(float si, float sj)
00332 {
00333   const vimt_transform_2d &tr = im_->world2im();
00334 
00335 // Try to adjust pixel size without modifying rest of transform
00336   vgl_vector_2d<double> w11 = tr(1.0, 1.0) - tr.origin();
00337 
00338   vimt_transform_2d zoom;
00339   zoom.set_zoom_only (w11.x()/si, w11.y()/sj, 0.0, 0.0);
00340 
00341   im_->set_world2im(tr*zoom);
00342 }
00343 
00344 
00345 //: Create a read/write view of a copy of this data.
00346 // Currently not yet implemented.
00347 // \return 0 if unable to get view of correct size.
00348 vil_image_view_base_sptr vimt_vil_v2i_image::get_copy_view(unsigned i0, unsigned ni,
00349                                                            unsigned j0, unsigned nj) const
00350 {
00351   const vil_image_view_base &view = im_->image_base();
00352 
00353   if (i0 + ni > view.ni() || j0 + nj > view.nj() ) return 0;
00354 
00355   switch (view.pixel_format())
00356   {
00357 #define macro( F , T ) \
00358    case  F : { \
00359     const vil_image_view< T > &v = \
00360       static_cast<const vil_image_view< T > &>(view); \
00361     vil_image_view< T > w(v.memory_chunk(), &v(i0,j0), \
00362                           ni, nj, v.nplanes(), \
00363                           v.istep(), v.jstep(), v.planestep()); \
00364     return new vil_image_view< T >(vil_copy_deep(w)); }
00365 // Don't include versions for which there is no template instantian of vimt_image_2d_of.
00366 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00367 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00368 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00369 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00370 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00371 //macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00372 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00373 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00374 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00375 #undef macro
00376    default:
00377     return 0;
00378   }
00379 }
00380 
00381 //: Create a read/write view of a copy of this data.
00382 // \return 0 if unable to get view of correct size.
00383 vil_image_view_base_sptr vimt_vil_v2i_image::get_view(unsigned i0, unsigned ni,
00384                                                       unsigned j0, unsigned nj) const
00385 {
00386   const vil_image_view_base &view = im_->image_base();
00387 
00388 
00389   if (i0 + ni > view.ni() || j0 + nj > view.nj()) return 0;
00390 
00391   switch (view.pixel_format())
00392   {
00393 #define macro( F , T ) \
00394    case  F : { \
00395     const vil_image_view< T > &v = \
00396       static_cast<const vil_image_view< T > &>(view); \
00397     return new vil_image_view< T >(v.memory_chunk(), &v(i0,j0), \
00398                                    ni, nj, v.nplanes(), \
00399                                    v.istep(), v.jstep(), v.planestep()); }
00400 // Don't include versions for which there is no template instantian of vimt_image_2d_of.
00401 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00402 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00403 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00404 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00405 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00406 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00407 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00408 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00409 //macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00410 #undef macro
00411    default:
00412     return 0;
00413   }
00414 }
00415 
00416 
00417 //: Set the contents of the volume.
00418 bool vimt_vil_v2i_image::put_view(const vil_image_view_base& vv,
00419                                   unsigned i0, unsigned j0)
00420 {
00421   if (!view_fits(vv, i0, j0))
00422   {
00423     vcl_cerr << "ERROR: " << __FILE__ << ":\n view does not fit\n";
00424     return false;
00425   }
00426 
00427   if (vv.pixel_format() != im_->image_base().pixel_format())
00428   {
00429     vcl_cerr << "ERROR: vimt_vil_v2i_image::put_view(). Pixel formats do not match\n";
00430     return false;
00431   }
00432 
00433 
00434   dirty_ = true;
00435 
00436   switch (vv.pixel_format())
00437   {
00438 #define macro( F , T ) \
00439    case  F : \
00440     vil_copy_to_window(static_cast<vil_image_view< T >const&>(vv), \
00441                        static_cast<vimt_image_2d_of< T >&>(*im_).image(), i0, j0); \
00442     return true;
00443 
00444 // Don't include versions for which there is no template instantian of vimt_image_2d_of.
00445     macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00446 //  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00447 //  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00448 //  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00449     macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00450     macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00451 //  macro(VIL_PIXEL_FORMAT_BOOL , bool )
00452     macro(VIL_PIXEL_FORMAT_FLOAT , float )
00453 //  macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00454 #undef macro
00455    default:
00456     return false;
00457   }
00458 }

Generated on Thu Jan 10 14:43:58 2008 for contrib/mul/vimt by  doxygen 1.4.4