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