contrib/mul/vimt3d/vimt3d_vil3d_v3i.cxx
Go to the documentation of this file.
00001 // This is mul/vimt3d/vimt3d_vil3d_v3i.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \brief Reader/Writer for v3i format images.
00008 // \author Ian Scott - Manchester
00009 
00010 #include "vimt3d_vil3d_v3i.h"
00011 #include <vcl_cstdlib.h> // for vcl_abort()
00012 #include <vcl_cstring.h> // for vcl_strcmp()
00013 #include <vcl_cassert.h>
00014 #include <vcl_ios.h>
00015 #include <vcl_algorithm.h>
00016 #include <vsl/vsl_binary_loader.h>
00017 #include <vsl/vsl_block_binary.h>
00018 #include <vgl/vgl_point_3d.h>
00019 #include <vgl/vgl_vector_3d.h>
00020 #include <vil3d/vil3d_image_view.h>
00021 #include <vil3d/vil3d_copy.h>
00022 #include <vil3d/vil3d_property.h>
00023 #include <vimt3d/vimt3d_image_3d_of.h>
00024 #include <vil/vil_exception.h>
00025 
00026 //: The magic number to identify a vsl stream as a v3i image.
00027 // You can create/read a v3i image using vsl by opening the stream,
00028 // reading/writing magic_number(), then reading/writing a pointer to a vimt_image.
00029 unsigned vimt3d_vil3d_v3i_format::magic_number()
00030 {
00031   return 987123873U;
00032 }
00033 
00034 vil3d_image_resource_sptr vimt3d_vil3d_v3i_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 v3i 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_v3i_format::magic_number()) return 0;
00047   }
00048   return new vimt3d_vil3d_v3i_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_v3i_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_v3i_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_v3i_format::make_output_image() WARNING\n"
00076              << "  Unable to open file: " << filename << vcl_endl;
00077     return 0;
00078   }
00079 
00080   return new vimt3d_vil3d_v3i_image(of, ni, nj, nk, nplanes, format);
00081 }
00082 
00083 
00084 //: Skip the reading of a vil_memory_chunk
00085 bool vimt3d_vil3d_v3i_image::skip_b_read_vil_memory_chunk(vsl_b_istream& is, unsigned sizeof_T) const
00086 { // Copy of vsl_b_read(vsl_b_istream &is, vil_memory_chunk& chunk)
00087   short vil_memory_chunk_version;
00088   vsl_b_read(is, vil_memory_chunk_version);
00089   int int_format;
00090   vsl_b_read(is, int_format);
00091   if (vil_pixel_format_component_format(header_.pixel_format) != vil_pixel_format(int_format))
00092   {
00093     vcl_cerr << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00094              << "           chunk pixel format is incompatible with image\n";
00095     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00096     return false;
00097   }
00098   unsigned n;
00099   vsl_b_read(is, n);
00100   switch (vil_memory_chunk_version)
00101   {
00102    case 1:
00103     if (vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_DOUBLE ||
00104       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_FLOAT)
00105       is.is().seekg(n*sizeof_T, vcl_ios_cur); // skip image pixel data.
00106     else
00107       // Give up trying to load header - it can't be done efficiently.
00108       return false;
00109     break;
00110    case 2:
00111     if (vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_SBYTE ||
00112         vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_BYTE )
00113       vsl_block_binary_read_confirm_specialisation(is, false);
00114     else
00115       vsl_block_binary_read_confirm_specialisation(is, true);
00116     if (!is) return false;
00117     if (vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_DOUBLE ||
00118       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_FLOAT ||
00119       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_SBYTE ||
00120       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_BYTE )
00121       is.is().seekg(n*sizeof_T, vcl_ios_cur); // skip image pixel data.
00122     else
00123     {
00124       vcl_size_t n_bytes;
00125       vsl_b_read(is, n_bytes);
00126       is.is().seekg(n_bytes, vcl_ios_cur); // skip image pixel data.
00127     }
00128     break;
00129    case 3:
00130     vsl_block_binary_read_confirm_specialisation(is, true);
00131     if (!is) return false;
00132     if (vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_DOUBLE ||
00133       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_FLOAT ||
00134       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_SBYTE ||
00135       vil_pixel_format_component_format(header_.pixel_format) == VIL_PIXEL_FORMAT_BYTE )
00136       is.is().seekg(n*sizeof_T, vcl_ios_cur); // skip image pixel data.
00137     else
00138     {
00139       vcl_size_t n_bytes;
00140       vsl_b_read(is, n_bytes);
00141       is.is().seekg(n_bytes, vcl_ios_cur); // skip image pixel data.
00142     }
00143     break;
00144    default:
00145     vcl_cerr << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image\n"
00146              << "           Unknown vil_memory_chunk version number "<< vil_memory_chunk_version << '\n';
00147     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00148     return false;
00149   }
00150   return true;
00151 }
00152 
00153 
00154 bool vimt3d_vil3d_v3i_image::header_t::operator==(const header_t& rhs) const
00155 {
00156   return this->ni == rhs.ni
00157     && this->nj == rhs.nj
00158     && this->nk == rhs.nk
00159     && this->nplanes == rhs.nplanes
00160     && this->pixel_format == rhs.pixel_format
00161     && this->w2i == rhs.w2i;
00162 }
00163 
00164 //: Load full image on demand.
00165 void vimt3d_vil3d_v3i_image::load_full_image() const
00166 {
00167   file_->seekg(0);
00168   vsl_b_istream is(file_);
00169   unsigned magic;
00170   vsl_b_read(is, magic);
00171   if (magic != vimt3d_vil3d_v3i_format::magic_number())
00172   {
00173     im_ =0;
00174     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00175     vil_exception_warning(vil_exception_corrupt_image_file(
00176       "vimt3d_vil3d_v3i_image::load_full_image", "vimt3d_vil3d_v3i_image", "", "Incorrect V3I magic number detected"));
00177     return;
00178   }
00179   short version;
00180   vsl_b_read(is, version);
00181   vimt_image *p_im=0;
00182 
00183   switch (version)
00184   {
00185     case 1:
00186 
00187     vsl_b_read(is, p_im);
00188     im_ = dynamic_cast<vimt3d_image_3d *>(p_im);
00189     break;
00190 
00191     default:
00192     im_ =0;
00193     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00194     vcl_ostringstream oss;
00195     oss << "I/O ERROR: vimt3d_vil3d_v3i_image::load_full_image()\n"
00196              << "           Unknown version number "<< version << '\n';
00197     vil_exception_warning(vil_exception_invalid_version(
00198       "vimt3d_vil3d_v3i_image::load_full_image", "vimt3d_vil3d_v3i_image", "", oss.str()));
00199     return;
00200   }
00201 
00202   header_t my_header;
00203   my_header.pixel_format = im_->image_base().pixel_format();
00204   my_header.ni = im_->image_base().ni();
00205   my_header.nj = im_->image_base().nj();
00206   my_header.nk = im_->image_base().nk();
00207   my_header.nplanes = im_->image_base().nplanes();
00208   my_header.w2i = im_->world2im();
00209   if (!(my_header == header_) && ! dirty_)
00210   {
00211     im_ =0;
00212     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00213     vcl_ostringstream oss;
00214     oss << "I/O ERROR: vimt3d_vil3d_v3i_image::load_full_image\n"
00215              << "           Header is not consistent with previously calculated version.";
00216     vil_exception_warning(vil_exception_corrupt_image_file(
00217       "vimt3d_vil3d_v3i_image::load_full_image", "vimt3d_vil3d_v3i_image", "", oss.str()));
00218     return;
00219   }
00220 }
00221 
00222 
00223 //: Private constructor, use vil3d_load instead.
00224 // This object takes ownership of the file, for reading.
00225 vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image(vcl_auto_ptr<vcl_fstream> file):
00226   file_(file.release()), im_(0), dirty_(false)
00227 {
00228   file_->seekg(0);
00229   vsl_b_istream is(file_);
00230 
00231   unsigned magic;
00232   vsl_b_read(is, magic);
00233   if (magic != vimt3d_vil3d_v3i_format::magic_number())
00234   {
00235     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00236     vil_exception_warning(vil_exception_corrupt_image_file(
00237       "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", "Incorrect V3I magic number detected"));
00238     return;
00239   }
00240 
00241   short version;
00242   vsl_b_read(is, version);
00243 
00244   switch (version)
00245   {
00246     case 1:
00247 #if 0
00248     {
00249       vimt_image *p_im=0;
00250       vsl_b_read(is, p_im);
00251       im_ = dynamic_cast<vimt3d_image_3d *>(p_im);
00252     }
00253 #else
00254     { // Copy vimt_image* loader
00255       vsl_binary_loader<vimt_image>& instance = vsl_binary_loader<vimt_image>::instance();
00256 
00257 
00258       if (!is) return;
00259 
00260       vcl_string name;
00261       vsl_b_read(is,name);
00262 
00263       if (name=="VSL_NULL_PTR")
00264       {
00265         // a v3i image should never have a null pointer.
00266         is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00267         vcl_ostringstream oss;
00268         oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00269                  << "           vimt_image ptr load failure\n";
00270         vil_exception_warning(vil_exception_corrupt_image_file(
00271           "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00272         return;
00273       }
00274 
00275       unsigned int i = 0;
00276       while (i<instance.object().size() && !(instance.object()[i]->is_a()==name)) ++i;
00277 
00278       if (i>=instance.object().size())
00279       {
00280         vcl_ostringstream oss;
00281         oss << "\n I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00282                  << "class name <" << name << "> not in list of loaders\n"
00283                  << instance.object().size()<<" valid loaders:\n";
00284         for (unsigned int j=0; j<instance.object().size(); ++j)
00285           vcl_cerr << instance.object()[j]->is_a() << vcl_endl;
00286         is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00287         vil_exception_warning(vil_exception_corrupt_image_file(
00288           "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00289         return;
00290       }
00291 
00292       header_.pixel_format = dynamic_cast<vimt3d_image_3d&>(*instance.object()[i]).image_base().pixel_format();
00293 
00294       unsigned sizeof_T = vil_pixel_format_sizeof_components(header_.pixel_format);
00295       
00296       { // Copy vimt3d_image_3d loader
00297         short vimt3d_image_3d_of_version;
00298         vsl_b_read(is, vimt3d_image_3d_of_version);
00299         switch (vimt3d_image_3d_of_version)
00300         {
00301           case 1:
00302           { // Copy of vil3d_image_view loader.
00303             vcl_ptrdiff_t dummy_step;
00304             vil_memory_chunk_sptr chunk;
00305 
00306             short vil3d_image_view_version;
00307             vsl_b_read(is, vil3d_image_view_version);
00308             switch(vil3d_image_view_version)
00309             {
00310               case 1:
00311 
00312               vsl_b_read(is, header_.ni);
00313               vsl_b_read(is, header_.nj);
00314               vsl_b_read(is, header_.nk);
00315               vsl_b_read(is, header_.nplanes);
00316               vsl_b_read(is, dummy_step /*istep*/);
00317               vsl_b_read(is, dummy_step /*jstep*/);
00318               vsl_b_read(is, dummy_step /*kstep*/);
00319               vsl_b_read(is, dummy_step /*pstep*/);
00320               if (header_.ni*header_.nj*header_.nk!=0)
00321               { // Copy of smart_ptr loader
00322                 short vil_smart_ptr_version;
00323                 vsl_b_read(is, vil_smart_ptr_version);
00324                 switch (vil_smart_ptr_version)
00325                 {
00326                   case 1:
00327                   case 2:
00328                   {
00329                     bool first_time; // true if the object is about to be loaded
00330                     vsl_b_read(is, first_time);
00331                     unsigned long id; // Unique serial number indentifying object
00332                     vsl_b_read(is, id);
00333                     if (!first_time || id == 0)
00334                     {
00335                       // We are in a v3i file there should only be one image, and it should not be a null ptr
00336                       vcl_ostringstream oss;
00337                       oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00338                                << "           Smart ptr De-serialisation failure\n";
00339                       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00340                       vil_exception_warning(vil_exception_corrupt_image_file(
00341                         "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00342                       return;
00343                     }
00344                     { // Copy of vsl_b_read(vsl_b_istream &is, vil_memory_chunk*& p)
00345                       bool not_null_ptr;
00346                       vsl_b_read(is, not_null_ptr);
00347                       if (!not_null_ptr)
00348                       {
00349                         // We are in a v3i file there should not be a null ptr
00350                         vcl_ostringstream oss;
00351                         oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00352                                  << "           Ptr read failure\n";
00353                         is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00354                         vil_exception_warning(vil_exception_corrupt_image_file(
00355                           "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00356                         return;
00357                       }
00358                       bool success = skip_b_read_vil_memory_chunk(is, sizeof_T);
00359                       if (!is)
00360                       {
00361                         vil_exception_warning(vil_exception_image_io(
00362                           "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", ""));
00363                         return;
00364                       }
00365                       if (!success)
00366                       {
00367                         // Give up trying to load just the header, and load the whole image.
00368                         load_full_image();
00369                         return;
00370                       }
00371                     }
00372                     break;
00373                   }
00374                   default:
00375                   vcl_ostringstream oss;
00376                   oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00377                            << "           Unknown vil_smart_ptr version number "<< vil_smart_ptr_version << '\n';
00378                   is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00379                   vil_exception_warning(vil_exception_invalid_version(
00380                     "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00381                   return;
00382                 }
00383               }
00384               vsl_b_read(is, dummy_step /*offset*/);
00385               break;
00386 
00387               default:
00388               vcl_ostringstream oss;
00389               oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00390                        << "           Unknown vil3d_image_view version number "<< vil3d_image_view_version << "\n";
00391               is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00392               vil_exception_warning(vil_exception_invalid_version(
00393                 "vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00394               return;
00395             }
00396             vsl_b_read(is, header_.w2i);
00397           } // end of vil3d_image_view loader
00398           break;
00399 
00400           default:
00401           vcl_ostringstream oss;
00402           oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00403                    << "           Unknown vimt3d_image_3d_of version number "<< vimt3d_image_3d_of_version << '\n';
00404           is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00405           vil_exception_warning(vil_exception_invalid_version("vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00406           return;
00407         }
00408       } // End of  vimt3d_image_3d loader
00409     }
00410 
00411 #endif
00412     break;
00413 
00414     default:
00415     vcl_ostringstream oss;
00416     oss << "I/O ERROR: vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image()\n"
00417              << "           Unknown version number "<< version << '\n';
00418     vil_exception_warning(vil_exception_invalid_version("vimt3d_vil3d_v3i_image constructor", "vimt3d_vil3d_v3i_image", "", oss.str()));
00419     return;
00420   }
00421 }
00422 
00423 //: Private constructor, use vil3d_save instead.
00424 // This object takes ownership of the file, for writing.
00425 vimt3d_vil3d_v3i_image::vimt3d_vil3d_v3i_image(vcl_auto_ptr<vcl_fstream> file, unsigned ni,
00426                                                unsigned nj, unsigned nk,
00427                                                unsigned nplanes,
00428                                                vil_pixel_format format):
00429   file_(file.release()), im_(0), dirty_(true)
00430 {
00431   header_.ni = ni;
00432   header_.nj = nj;
00433   header_.nk = nk;
00434   header_.nplanes = nplanes;
00435   header_.pixel_format = format;
00436   switch (format)
00437   {
00438 #define macro( F , T ) \
00439    case  F : \
00440     im_ = new vimt3d_image_3d_of< T > (ni, nj, nk, nplanes); \
00441     break;
00442 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00443 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00444 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00445 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00446 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00447 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00448 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00449 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00450 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00451 #undef macro
00452    default:
00453     vil_exception_error(vil_exception_unsupported_pixel_format(
00454       format, "vimt3d_vil3d_v3i_image constructor"));
00455   }
00456 }
00457 
00458 vimt3d_vil3d_v3i_image::~vimt3d_vil3d_v3i_image()
00459 {
00460   if (dirty_)
00461   {
00462     file_->seekp(0);
00463     vsl_b_ostream os(file_);
00464 
00465     vsl_b_write(os, vimt3d_vil3d_v3i_format::magic_number());
00466 
00467     const short version = 1;
00468     vsl_b_write(os, version);
00469 
00470 
00471     vimt_image *p_im=im_;
00472     vsl_b_write(os, p_im);
00473   }
00474   delete file_;
00475   delete im_;
00476 }
00477 
00478 
00479 //: Dimensions:  nplanes x ni x nj x nk.
00480 // This concept is treated as a synonym to components.
00481 unsigned vimt3d_vil3d_v3i_image::nplanes() const
00482 {
00483   return header_.nplanes;
00484 }
00485 
00486 //: Dimensions:  nplanes x ni x nj x nk.
00487 // The number of pixels in each row.
00488 unsigned vimt3d_vil3d_v3i_image::ni() const
00489 {
00490   return header_.ni;
00491 }
00492 
00493 //: Dimensions:  nplanes x ni x nj x nk.
00494 // The number of pixels in each column.
00495 unsigned vimt3d_vil3d_v3i_image::nj() const
00496 {
00497   return header_.nj;
00498 }
00499 
00500 //: Dimensions:  nplanes x ni x nj x nk.
00501 // The number of slices per image.
00502 unsigned vimt3d_vil3d_v3i_image::nk() const
00503 {
00504   return header_.nk;
00505 }
00506 
00507 //: Pixel Format.
00508 enum vil_pixel_format vimt3d_vil3d_v3i_image::pixel_format() const
00509 {
00510   return header_.pixel_format;
00511 }
00512 
00513 
00514 //: Get the properties (of the first slice)
00515 bool vimt3d_vil3d_v3i_image::get_property(char const *key, void * value) const
00516 {
00517   if (vcl_strcmp(vil3d_property_voxel_size, key)==0)
00518   {
00519     vgl_vector_3d<double> p111 = header_.w2i.inverse()(1.0, 1.0, 1.0) - header_.w2i.inverse().origin();
00520     //Assume no rotation or shearing.
00521 
00522     float* array =  static_cast<float*>(value);
00523     array[0] = (float) p111.x();
00524     array[1] = (float) p111.y();
00525     array[2] = (float) p111.z();
00526     return true;
00527   }
00528 
00529   if (vcl_strcmp(vil3d_property_origin_offset, key)==0)
00530   {
00531     vgl_point_3d<double> origin = header_.w2i.origin();
00532     float* array =  static_cast<float*>(value);
00533     array[0] = (float)(origin.x());
00534     array[1] = (float)(origin.y());
00535     array[2] = (float)(origin.z());
00536     return true;
00537   }
00538 
00539   return false;
00540 }
00541 
00542 
00543 //: Set the size of the each pixel in the i,j,k directions.
00544 // Return false if underlying image doesn't store pixel sizes.
00545 bool vimt3d_vil3d_v3i_image::set_voxel_size(float si, float sj, float sk)
00546 {
00547   const vimt3d_transform_3d &tr = im_->world2im();
00548 
00549 // Try to adjust pixel size without modifying rest of transform
00550   vgl_vector_3d<double> w111 = header_.w2i(1.0, 1.0, 1.0) - header_.w2i.origin();
00551 
00552   vimt3d_transform_3d zoom;
00553   zoom.set_zoom_only (w111.x()/si, w111.y()/sj, w111.z()/sk, 0.0, 0.0, 0.0);
00554 
00555   header_.w2i = header_.w2i * zoom;
00556   if (im_)
00557     im_->set_world2im(tr*zoom);
00558   dirty_ = true;
00559 
00560   return true;
00561 }
00562 
00563 const vimt3d_transform_3d & vimt3d_vil3d_v3i_image::world2im() const
00564 {
00565   return header_.w2i;
00566 }
00567 
00568 void vimt3d_vil3d_v3i_image::set_world2im(const vimt3d_transform_3d & tr)
00569 {
00570   header_.w2i=tr;
00571   if (im_)
00572     im_->set_world2im(header_.w2i);
00573   dirty_ = true;
00574 }
00575 
00576 
00577 //: Create a read/write view of a copy of this data.
00578 // Currently not yet implemented.
00579 // \return 0 if unable to get view of correct size.
00580 vil3d_image_view_base_sptr vimt3d_vil3d_v3i_image::get_copy_view(unsigned i0, unsigned ni,
00581                                                                  unsigned j0, unsigned nj,
00582                                                                  unsigned k0, unsigned nk) const
00583 {
00584   if (!im_)
00585     load_full_image();
00586   if (!im_) return 0; // If load full image failed then im_ will remain null
00587 
00588   const vil3d_image_view_base &view = im_->image_base();
00589 
00590   if (i0 + ni > view.ni() || j0 + nj > view.nj() ||
00591       k0 + nk > view.nk()) return 0;
00592 
00593   switch (view.pixel_format())
00594   {
00595 #define macro( F , T ) \
00596    case  F : { \
00597     const vil3d_image_view< T > &v = \
00598       static_cast<const vil3d_image_view< T > &>(view); \
00599     vil3d_image_view< T > w(v.memory_chunk(), &v(i0,j0,k0), \
00600                             ni, nj, nk, v.nplanes(), \
00601                             v.istep(), v.jstep(), v.kstep(), v.planestep()); \
00602     return new vil3d_image_view< T >(vil3d_copy_deep(w)); }
00603 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00604 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00605 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00606 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00607 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00608 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00609 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00610 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00611 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00612 #undef macro
00613    default:
00614      vil_exception_warning(vil_exception_unsupported_pixel_format(
00615        view.pixel_format(), "vimt3d_vil3d_v3i_image::get_copy_view"));
00616     return 0;
00617   }
00618 }
00619 
00620 //: Create a read/write view of a copy of this data.
00621 // \return 0 if unable to get view of correct size.
00622 vil3d_image_view_base_sptr vimt3d_vil3d_v3i_image::get_view(unsigned i0, unsigned ni,
00623                                                             unsigned j0, unsigned nj,
00624                                                             unsigned k0, unsigned nk) const
00625 {
00626   if (!im_)
00627     load_full_image();
00628   if (!im_) return 0; // If load full image failed then im_ will remain null
00629 
00630   const vil3d_image_view_base &view = im_->image_base();
00631 
00632   if (i0 + ni > view.ni() || j0 + nj > view.nj() ||
00633       k0 + nk > view.nk()) return 0;
00634 
00635   switch (view.pixel_format())
00636   {
00637 #define macro( F , T ) \
00638    case  F : { \
00639     const vil3d_image_view< T > &v = \
00640       static_cast<const vil3d_image_view< T > &>(view); \
00641     return new vil3d_image_view< T >(v.memory_chunk(), &v(i0,j0,k0), \
00642                                      ni, nj, nk, v.nplanes(), \
00643                                      v.istep(), v.jstep(), v.kstep(), \
00644                                      v.planestep()); }
00645 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00646 //macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00647 //macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00648 //macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00649 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00650 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00651 //macro(VIL_PIXEL_FORMAT_BOOL , bool )
00652 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00653 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00654 #undef macro
00655    default:
00656      vil_exception_warning(vil_exception_unsupported_pixel_format(
00657        view.pixel_format(), "vimt3d_vil3d_v3i_image::get_view"));
00658     return 0;
00659   }
00660 }
00661 
00662 
00663 //: Set the contents of the volume.
00664 bool vimt3d_vil3d_v3i_image::put_view(const vil3d_image_view_base& vv,
00665                                       unsigned i0, unsigned j0, unsigned k0)
00666 {
00667   if (!im_)
00668     load_full_image();
00669   if (!im_) return false; // If load full image failed then im_ will remain null
00670 
00671 
00672   if (!view_fits(vv, i0, j0, k0))
00673   {
00674     vil_exception_warning(vil_exception_out_of_bounds("vimt3d_vil3d_v3i_image::put_view"));
00675     return false;
00676   }
00677 
00678   if (vv.pixel_format() != im_->image_base().pixel_format())
00679   {
00680     vil_exception_warning(vil_exception_pixel_formats_incompatible(
00681       vv.pixel_format(), im_->image_base().pixel_format(), "vimt3d_vil3d_v3i_image::put_view"));
00682     return false;
00683   }
00684 
00685 
00686   dirty_ = true;
00687 
00688   switch (vv.pixel_format())
00689   {
00690 #define macro( F , T ) \
00691    case  F : \
00692     vil3d_copy_to_window(static_cast<vil3d_image_view<T >const&>(vv), \
00693                          static_cast<vimt3d_image_3d_of<T >&>(*im_).image(), \
00694                          i0, j0, k0); \
00695     return true;
00696 
00697     macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00698 //  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00699 //  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00700 //  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00701     macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00702     macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00703 //  macro(VIL_PIXEL_FORMAT_BOOL , bool )
00704     macro(VIL_PIXEL_FORMAT_FLOAT , float )
00705     macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00706 #undef macro
00707    default:
00708      vil_exception_warning(vil_exception_unsupported_pixel_format(
00709        vv.pixel_format(), "vimt3d_vil3d_v3i_image::put_view"));
00710     return false;
00711   }
00712 }