contrib/mul/vimt3d/vimt3d_vil3d_v3m.cxx
Go to the documentation of this file.
00001 // This is mul/vimt3d/vimt3d_vil3d_v3m.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \brief Reader/Writer for v3m format images.
00008 // \author Ian Scott - Manchester
00009 
00010 #include "vimt3d_vil3d_v3m.h"
00011 //
00012 #include <vcl_cstdlib.h> // for vcl_abort()
00013 #include <vcl_cstring.h> // for vcl_strcmp()
00014 #include <vcl_sstream.h>
00015 #include <vcl_cassert.h>
00016 #include <vcl_ios.h>
00017 #include <vcl_algorithm.h>
00018 #include <vsl/vsl_binary_loader.h>
00019 #include <vsl/vsl_block_binary_rle.h>
00020 #include <vgl/vgl_point_3d.h>
00021 #include <vgl/vgl_vector_3d.h>
00022 #include <vil3d/vil3d_image_view.h>
00023 #include <vil3d/vil3d_copy.h>
00024 #include <vil3d/vil3d_property.h>
00025 #include <vimt3d/vimt3d_image_3d_of.h>
00026 #include <vil/vil_exception.h>
00027 
00028 //: The magic number to identify a vsl stream as a v3m image.
00029 unsigned vimt3d_vil3d_v3m_format::magic_number()
00030 {
00031   return 987123875U;
00032 }
00033 
00034 vil3d_image_resource_sptr vimt3d_vil3d_v3m_format::make_input_image(const char *filename) const
00035 {
00036   vcl_auto_ptr<vcl_fstream> file(new vcl_fstream(filename, vcl_ios_in | vcl_ios_binary ));
00037   if (!file.get() || !file->is_open())
00038     return 0;
00039 
00040   // Check file is a v3m file
00041   {
00042     vsl_b_istream is(file.get());
00043     if (!is) return 0;
00044     unsigned magic;
00045     vsl_b_read(is, magic);
00046     if (magic != vimt3d_vil3d_v3m_format::magic_number()) return 0;
00047   }
00048   return new vimt3d_vil3d_v3m_image(file);
00049 }
00050 
00051 
00052 //: Make a "generic_image" on which put_section may be applied.
00053 // The file may be opened immediately for writing so that a header can be written.
00054 // The width/height etc are explicitly specified, so that file_format implementors
00055 // know what they need to do...
00056 vil3d_image_resource_sptr vimt3d_vil3d_v3m_format::make_output_image
00057                    (const char* filename, unsigned ni, unsigned nj,
00058                     unsigned nk, unsigned nplanes, vil_pixel_format format) const
00059 {
00060   if ( format != VIL_PIXEL_FORMAT_BYTE && format != VIL_PIXEL_FORMAT_SBYTE &&
00061        format != VIL_PIXEL_FORMAT_UINT_32 && format != VIL_PIXEL_FORMAT_INT_32 &&
00062        format != VIL_PIXEL_FORMAT_UINT_16 && format != VIL_PIXEL_FORMAT_INT_16 &&
00063        format != VIL_PIXEL_FORMAT_FLOAT && format != VIL_PIXEL_FORMAT_DOUBLE &&
00064        format != VIL_PIXEL_FORMAT_BOOL)
00065   {
00066     vcl_cerr << "vimt3d_vil3d_v3m_format::make_output_image() WARNING\n"
00067              << "  Unable to deal with file format : " << format << vcl_endl;
00068     return 0;
00069   }
00070 
00071   vcl_auto_ptr<vcl_fstream> of(
00072     new vcl_fstream(filename, vcl_ios_out | vcl_ios_binary | vcl_ios_trunc) );
00073   if (!of.get() || !of->is_open())
00074   {
00075     vcl_cerr << "vimt3d_vil3d_v3m_format::make_output_image() WARNING\n"
00076              << "  Unable to open file: " << filename << vcl_endl;
00077     return 0;
00078   }
00079 
00080   return new vimt3d_vil3d_v3m_image(of, ni, nj, nk, nplanes, format);
00081 }
00082 
00083 
00084 bool vimt3d_vil3d_v3m_image::header_t::operator==(const header_t& rhs) const
00085 {
00086   return this->ni == rhs.ni
00087     && this->nj == rhs.nj
00088     && this->nk == rhs.nk
00089     && this->nplanes == rhs.nplanes
00090     && this->pixel_format == rhs.pixel_format
00091     && this->w2i == rhs.w2i;
00092 }
00093 
00094 //: Load full image on demand.
00095 void vimt3d_vil3d_v3m_image::load_full_image() const
00096 {
00097   file_->seekg(0);
00098   vsl_b_istream is(file_);
00099   unsigned magic;
00100   vsl_b_read(is, magic);
00101   if (magic != vimt3d_vil3d_v3m_format::magic_number())
00102   {
00103     im_ =0;
00104     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00105     vil_exception_warning(vil_exception_corrupt_image_file(
00106       "vimt3d_vil3d_v3m_image::load_full_image", "vimt3d_vil3d_v3m_image", "", "Incorrect v3m magic number detected"));
00107     return;
00108   }
00109   short version;
00110   vsl_b_read(is, version);
00111 
00112   switch (version)
00113   {
00114    case 1:
00115     {
00116       vsl_b_read(is, header_.ni);
00117       vsl_b_read(is, header_.nj);
00118       vsl_b_read(is, header_.nk);
00119       vsl_b_read(is, header_.nplanes);
00120       int v;
00121       vsl_b_read(is, v);
00122       header_.pixel_format = static_cast<vil_pixel_format>(v);
00123       vsl_b_read(is, header_.w2i);
00124       vcl_size_t size = static_cast<vcl_size_t>(header_.ni) * header_.nj *
00125         header_.nk * header_.nplanes;
00126       vil_memory_chunk_sptr chunk_ptr( new vil_memory_chunk(
00127         size * vil_pixel_format_sizeof_components(header_.pixel_format), header_.pixel_format) );
00128 
00129       switch (header_.pixel_format)
00130       {
00131 #define macro( F , T ) \
00132        case F : \
00133         { \
00134           vcl_ptrdiff_t istep=0, jstep=0, kstep=0, pstep=0; \
00135           T* origin_ptr=static_cast<T*>(chunk_ptr->data()); \
00136           if (size) \
00137           { \
00138             vsl_block_binary_rle_read(is, static_cast<T *>(chunk_ptr->data()), size); \
00139             vsl_b_read(is, istep); \
00140             vsl_b_read(is, jstep); \
00141             vsl_b_read(is, kstep); \
00142             vsl_b_read(is, pstep); \
00143             vcl_ptrdiff_t offset; \
00144             vsl_b_read(is, offset); \
00145             origin_ptr += offset; \
00146           } \
00147           im_ = new vimt3d_image_3d_of<T>( \
00148                       vil3d_image_view<T>(chunk_ptr, origin_ptr, \
00149                                           header_.ni, header_.nj, header_.nk, header_.nplanes, \
00150                                           istep, jstep, kstep, pstep), header_.w2i ); \
00151          } \
00152         break;
00153 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00154 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00155 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00156 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00157 /*macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )*/
00158 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00159 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00160 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00161 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00162 #undef macro
00163        case  VIL_PIXEL_FORMAT_INT_32 :
00164         {
00165           vxl_int_32* origin_ptr=static_cast<vxl_int_32*>(chunk_ptr->data());
00166           vcl_ptrdiff_t istep=0, jstep=0, kstep=0, pstep=0;
00167           if (size)
00168           {
00169             vsl_block_binary_rle_read(is, static_cast<vxl_int_32 *>(chunk_ptr->data()), size);
00170             vsl_b_read(is, istep);
00171             vsl_b_read(is, jstep);
00172             vsl_b_read(is, kstep);
00173             vsl_b_read(is, pstep);
00174             vcl_ptrdiff_t offset;
00175             vsl_b_read(is, offset);
00176             origin_ptr += offset;
00177           }
00178           im_ = new vimt3d_image_3d_of<vxl_int_32>(
00179                       vil3d_image_view<vxl_int_32>(chunk_ptr, origin_ptr,
00180                                                    header_.ni, header_.nj, header_.nk, header_.nplanes,
00181                                                    istep, jstep, kstep, pstep),
00182                       header_.w2i );
00183          }
00184         break;
00185        default:
00186         vil_exception_error(vil_exception_unsupported_pixel_format(
00187           im_->image_base().pixel_format(), "vimt3d_vil3d_v3m_image constructor"));
00188       }
00189     }
00190     break;
00191 
00192    default:
00193     im_ =0;
00194     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00195     vcl_ostringstream oss;
00196     oss << "I/O ERROR: vimt3d_vil3d_v3m_image::load_full_image()\n"
00197         << "           Unknown version number "<< version << '\n';
00198     vil_exception_warning(vil_exception_invalid_version(
00199       "vimt3d_vil3d_v3m_image::load_full_image", "vimt3d_vil3d_v3m_image", "", oss.str()));
00200     return;
00201   }
00202   if (!is)
00203   {
00204     vil_exception_warning(vil_exception_corrupt_image_file(
00205       "vimt3d_vil3d_v3m_image::load_full_image", "vimt3d_vil3d_v3m_image", "", "Failed to read all expected values."));
00206     im_=0;
00207   }
00208 }
00209 
00210 
00211 //: Private constructor, use vil3d_load instead.
00212 // This object takes ownership of the file, for reading.
00213 vimt3d_vil3d_v3m_image::vimt3d_vil3d_v3m_image(vcl_auto_ptr<vcl_fstream> file):
00214   file_(file.release()), im_(0), dirty_(false)
00215 {
00216   file_->seekg(0);
00217   vsl_b_istream is(file_);
00218 
00219   unsigned magic;
00220   vsl_b_read(is, magic);
00221   if (magic != vimt3d_vil3d_v3m_format::magic_number())
00222   {
00223     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00224     vil_exception_warning(vil_exception_corrupt_image_file(
00225       "vimt3d_vil3d_v3m_image constructor", "vimt3d_vil3d_v3m_image", "", "Incorrect v3m magic number detected"));
00226     return;
00227   }
00228 
00229   short version;
00230   vsl_b_read(is, version);
00231 
00232   switch (version)
00233   {
00234     case 1:
00235       {
00236         vsl_b_read(is, header_.ni);
00237         vsl_b_read(is, header_.nj);
00238         vsl_b_read(is, header_.nk);
00239         vsl_b_read(is, header_.nplanes);
00240         int v;
00241         vsl_b_read(is, v);
00242         header_.pixel_format = static_cast<vil_pixel_format>(v);
00243         vsl_b_read(is, header_.w2i);
00244 
00245         break;
00246       }
00247     default:
00248       vcl_ostringstream oss;
00249       oss << "I/O ERROR: vimt3d_vil3d_v3m_image::vimt3d_vil3d_v3m_image()\n"
00250           << "           Unknown version number "<< version << '\n';
00251       vil_exception_warning(vil_exception_invalid_version("vimt3d_vil3d_v3m_image constructor", "vimt3d_vil3d_v3m_image", "", oss.str()));
00252       return;
00253   }
00254   if (!is)
00255   {
00256     vil_exception_warning(vil_exception_image_io(
00257       "vimt3d_vil3d_v3m_image constructor", "vimt3d_vil3d_v3m_image", ""));
00258   }
00259   return;
00260 }
00261 
00262 //: Private constructor, use vil3d_save instead.
00263 // This object takes ownership of the file, for writing.
00264 vimt3d_vil3d_v3m_image::vimt3d_vil3d_v3m_image(vcl_auto_ptr<vcl_fstream> file, unsigned ni,
00265                                                unsigned nj, unsigned nk,
00266                                                unsigned nplanes,
00267                                                vil_pixel_format format):
00268   file_(file.release()), im_(0), dirty_(true)
00269 {
00270   header_.ni = ni;
00271   header_.nj = nj;
00272   header_.nk = nk;
00273   header_.nplanes = nplanes;
00274   header_.pixel_format = format;
00275   switch (format)
00276   {
00277 #define macro( F , T ) \
00278    case F : \
00279     im_ = new vimt3d_image_3d_of< T > (ni, nj, nk, nplanes); \
00280     break;
00281 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00282 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00283 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00284 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00285 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00286 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00287 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00288 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00289 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00290 #undef macro
00291    default:
00292     vil_exception_error(vil_exception_unsupported_pixel_format(
00293       format, "vimt3d_vil3d_v3m_image constructor"));
00294   }
00295 }
00296 
00297 
00298 vimt3d_vil3d_v3m_image::~vimt3d_vil3d_v3m_image()
00299 {
00300   if (dirty_)
00301   {
00302     file_->seekp(0);
00303     vsl_b_ostream os(file_);
00304 
00305     vsl_b_write(os, vimt3d_vil3d_v3m_format::magic_number());
00306 
00307     const short version = 1;
00308     vsl_b_write(os, version);
00309 
00310     vsl_b_write(os, im_->image_base().ni());
00311     vsl_b_write(os, im_->image_base().nj());
00312     vsl_b_write(os, im_->image_base().nk());
00313     vsl_b_write(os, im_->image_base().nplanes());
00314     vsl_b_write(os, im_->image_base().pixel_format());
00315     vsl_b_write(os, im_->world2im());
00316 
00317     switch (im_->image_base().pixel_format())
00318     {
00319 #define macro( F , T ) \
00320      case F : \
00321       { \
00322         const vil3d_image_view<T> &image = static_cast<vil3d_image_view<T> >(im_->image_base()); \
00323         if (image.size()) \
00324         { \
00325           /* Data should be stored compactly, since this class controls im_ */ \
00326           assert(!image || image.size()*sizeof(T) == image.memory_chunk()->size()); \
00327           /* Data should be stored with non-compound type, since this class controls im_ */ \
00328           assert(!image || image.pixel_format() == image.memory_chunk()->pixel_format()); \
00329           vsl_block_binary_rle_write(os, static_cast<const T *>(image.memory_chunk()->const_data()), \
00330                                      image.size()); \
00331           vsl_b_write(os, image.istep()); \
00332           vsl_b_write(os, image.jstep()); \
00333           vsl_b_write(os, image.kstep()); \
00334           vsl_b_write(os, image.planestep()); \
00335           vcl_ptrdiff_t offset = (image.origin_ptr() - \
00336                                   reinterpret_cast<const T*>(image.memory_chunk()->data())); \
00337           vsl_b_write(os, offset); \
00338         } \
00339        } \
00340       break;
00341 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00342 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00343 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00344 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00345 /*macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )*/
00346 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00347 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00348 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00349 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00350 #undef macro
00351      case VIL_PIXEL_FORMAT_INT_32 :
00352       {
00353         const vil3d_image_view<vxl_int_32> &image = static_cast<vil3d_image_view<vxl_int_32> >(im_->image_base());
00354         if (image.size())
00355         {
00356           /* Data should be stored compactly, since this class controls im_ */
00357           assert(!image || image.size()*sizeof(vxl_int_32) == image.memory_chunk()->size());
00358           /* Data should be stored with non-compound type, since this class controls im_ */
00359           assert(!image || image.pixel_format() == image.memory_chunk()->pixel_format());
00360           vsl_block_binary_rle_write(os, static_cast<const vxl_int_32 *>(image.memory_chunk()->const_data()),
00361             image.size());
00362           vsl_b_write(os, image.istep());
00363           vsl_b_write(os, image.jstep());
00364           vsl_b_write(os, image.kstep());
00365           vsl_b_write(os, image.planestep());
00366           vcl_ptrdiff_t offset = (image.origin_ptr() -
00367                                   reinterpret_cast<const vxl_int_32*>(image.memory_chunk()->data()));
00368           vsl_b_write(os, offset);
00369         }
00370        }
00371       break;
00372      default:
00373       vil_exception_error(vil_exception_unsupported_pixel_format(
00374         im_->image_base().pixel_format(), "vimt3d_vil3d_v3m_image constructor"));
00375     }
00376 
00377 // Write view properties.
00378   }
00379   delete file_;
00380   delete im_;
00381 }
00382 
00383 
00384 //: Dimensions:  nplanes x ni x nj x nk.
00385 // This concept is treated as a synonym to components.
00386 unsigned vimt3d_vil3d_v3m_image::nplanes() const
00387 {
00388   return header_.nplanes;
00389 }
00390 
00391 //: Dimensions:  nplanes x ni x nj x nk.
00392 // The number of pixels in each row.
00393 unsigned vimt3d_vil3d_v3m_image::ni() const
00394 {
00395   return header_.ni;
00396 }
00397 
00398 //: Dimensions:  nplanes x ni x nj x nk.
00399 // The number of pixels in each column.
00400 unsigned vimt3d_vil3d_v3m_image::nj() const
00401 {
00402   return header_.nj;
00403 }
00404 
00405 //: Dimensions:  nplanes x ni x nj x nk.
00406 // The number of slices per image.
00407 unsigned vimt3d_vil3d_v3m_image::nk() const
00408 {
00409   return header_.nk;
00410 }
00411 
00412 //: Pixel Format.
00413 enum vil_pixel_format vimt3d_vil3d_v3m_image::pixel_format() const
00414 {
00415   return header_.pixel_format;
00416 }
00417 
00418 
00419 //: Get the properties (of the first slice)
00420 bool vimt3d_vil3d_v3m_image::get_property(char const *key, void * value) const
00421 {
00422   if (vcl_strcmp(vil3d_property_voxel_size, key)==0)
00423   {
00424     vgl_vector_3d<double> p111 = header_.w2i.inverse()(1.0, 1.0, 1.0) - header_.w2i.inverse().origin();
00425     //Assume no rotation or shearing.
00426 
00427     float* array =  static_cast<float*>(value);
00428     array[0] = (float) p111.x();
00429     array[1] = (float) p111.y();
00430     array[2] = (float) p111.z();
00431     return true;
00432   }
00433 
00434   if (vcl_strcmp(vil3d_property_origin_offset, key)==0)
00435   {
00436     vgl_point_3d<double> origin = header_.w2i.origin();
00437     float* array =  static_cast<float*>(value);
00438     array[0] = (float)(origin.x());
00439     array[1] = (float)(origin.y());
00440     array[2] = (float)(origin.z());
00441     return true;
00442   }
00443 
00444   return false;
00445 }
00446 
00447 
00448 //: Set the size of the each pixel in the i,j,k directions.
00449 // Return false if underlying image doesn't store pixel sizes.
00450 bool vimt3d_vil3d_v3m_image::set_voxel_size(float si, float sj, float sk)
00451 {
00452   const vimt3d_transform_3d &tr = im_->world2im();
00453 
00454 // Try to adjust pixel size without modifying rest of transform
00455   vgl_vector_3d<double> w111 = header_.w2i(1.0, 1.0, 1.0) - header_.w2i.origin();
00456 
00457   vimt3d_transform_3d zoom;
00458   zoom.set_zoom_only (w111.x()/si, w111.y()/sj, w111.z()/sk, 0.0, 0.0, 0.0);
00459 
00460   header_.w2i = header_.w2i * zoom;
00461   if (im_)
00462     im_->set_world2im(tr*zoom);
00463   dirty_ = true;
00464 
00465   return true;
00466 }
00467 
00468 const vimt3d_transform_3d & vimt3d_vil3d_v3m_image::world2im() const
00469 {
00470   return header_.w2i;
00471 }
00472 
00473 void vimt3d_vil3d_v3m_image::set_world2im(const vimt3d_transform_3d & tr)
00474 {
00475   header_.w2i=tr;
00476   if (im_)
00477     im_->set_world2im(header_.w2i);
00478   dirty_ = true;
00479 }
00480 
00481 
00482 //: Create a read/write view of a copy of this data.
00483 // Currently not yet implemented.
00484 // \return 0 if unable to get view of correct size.
00485 vil3d_image_view_base_sptr vimt3d_vil3d_v3m_image::get_copy_view(unsigned i0, unsigned ni,
00486                                                                  unsigned j0, unsigned nj,
00487                                                                  unsigned k0, unsigned nk) const
00488 {
00489   if (!im_)
00490     load_full_image();
00491   if (!im_) return 0; // If load full image failed then im_ will remain null
00492 
00493   const vil3d_image_view_base &view = im_->image_base();
00494 
00495   if (i0 + ni > view.ni() || j0 + nj > view.nj() ||
00496       k0 + nk > view.nk()) return 0;
00497 
00498   switch (view.pixel_format())
00499   {
00500 #define macro( F , T ) \
00501    case F : { \
00502     const vil3d_image_view< T > &v = \
00503       static_cast<const vil3d_image_view< T > &>(view); \
00504     vil3d_image_view< T > w(v.memory_chunk(), &v(i0,j0,k0), \
00505                             ni, nj, nk, v.nplanes(), \
00506                             v.istep(), v.jstep(), v.kstep(), v.planestep()); \
00507     return new vil3d_image_view< T >(vil3d_copy_deep(w)); }
00508 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00509 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00510 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00511 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00512 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00513 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00514 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00515 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00516 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00517 #undef macro
00518    default:
00519      vil_exception_warning(vil_exception_unsupported_pixel_format(
00520        view.pixel_format(), "vimt3d_vil3d_v3m_image::get_copy_view"));
00521     return 0;
00522   }
00523 }
00524 
00525 //: Create a read/write view of a copy of this data.
00526 // \return 0 if unable to get view of correct size.
00527 vil3d_image_view_base_sptr vimt3d_vil3d_v3m_image::get_view(unsigned i0, unsigned ni,
00528                                                             unsigned j0, unsigned nj,
00529                                                             unsigned k0, unsigned nk) const
00530 {
00531   if (!im_)
00532     load_full_image();
00533   if (!im_) return 0; // If load full image failed then im_ will remain null
00534 
00535   const vil3d_image_view_base &view = im_->image_base();
00536 
00537   if (i0 + ni > view.ni() || j0 + nj > view.nj() ||
00538       k0 + nk > view.nk()) return 0;
00539 
00540   switch (view.pixel_format())
00541   {
00542 #define macro( F , T ) \
00543    case F : { \
00544     const vil3d_image_view< T > &v = \
00545       static_cast<const vil3d_image_view< T > &>(view); \
00546       return new vil3d_image_view< T >(v.memory_chunk(), (!v)?0:&v(i0,j0,k0), \
00547                                        ni, nj, nk, v.nplanes(), \
00548                                        v.istep(), v.jstep(), v.kstep(), \
00549                                        v.planestep()); }
00550 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00551 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00552 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00553 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00554 /*macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )*/
00555 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00556 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00557 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00558 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00559 #undef macro
00560    case VIL_PIXEL_FORMAT_INT_32 : {
00561     const vil3d_image_view< vxl_int_32 > &v =
00562       static_cast<const vil3d_image_view< vxl_int_32 > &>(view);
00563     return new vil3d_image_view< vxl_int_32 >(v.memory_chunk(), v.size()?&v(i0,j0,k0):0,
00564                                               ni, nj, nk, v.nplanes(),
00565                                               v.istep(), v.jstep(), v.kstep(),
00566                                               v.planestep()); }
00567    default:
00568      vil_exception_warning(vil_exception_unsupported_pixel_format(
00569        view.pixel_format(), "vimt3d_vil3d_v3m_image::get_view"));
00570     return 0;
00571   }
00572 }
00573 
00574 
00575 //: Set the contents of the volume.
00576 bool vimt3d_vil3d_v3m_image::put_view(const vil3d_image_view_base& vv,
00577                                       unsigned i0, unsigned j0, unsigned k0)
00578 {
00579   if (!im_)
00580     load_full_image();
00581   if (!im_) return false; // If load full image failed then im_ will remain null
00582 
00583   if (!view_fits(vv, i0, j0, k0))
00584   {
00585     vil_exception_warning(vil_exception_out_of_bounds("vimt3d_vil3d_v3m_image::put_view"));
00586     return false;
00587   }
00588 
00589   if (vv.pixel_format() != im_->image_base().pixel_format())
00590   {
00591     vil_exception_warning(vil_exception_pixel_formats_incompatible(
00592       vv.pixel_format(), im_->image_base().pixel_format(), "vimt3d_vil3d_v3m_image::put_view"));
00593     return false;
00594   }
00595 
00596   dirty_ = true;
00597 
00598   switch (vv.pixel_format())
00599   {
00600 #define macro( F , T ) \
00601    case F : \
00602     vil3d_copy_to_window(static_cast<vil3d_image_view<T >const&>(vv), \
00603                          static_cast<vimt3d_image_3d_of<T >&>(*im_).image(), \
00604                          i0, j0, k0); \
00605     return true;
00606 
00607     macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00608 //  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00609 //  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00610 //  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00611     macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00612     macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00613 //  macro(VIL_PIXEL_FORMAT_BOOL , bool )
00614     macro(VIL_PIXEL_FORMAT_FLOAT , float )
00615     macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00616 #undef macro
00617    default:
00618      vil_exception_warning(vil_exception_unsupported_pixel_format(
00619        vv.pixel_format(), "vimt3d_vil3d_v3m_image::put_view"));
00620     return false;
00621   }
00622 }