[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/multi_impex.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 2003 by Gunnar Kedenburg                     */
00004 /*                                                                      */
00005 /*    This file is part of the VIGRA computer vision library.           */
00006 /*    The VIGRA Website is                                              */
00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
00008 /*    Please direct questions, bug reports, and contributions to        */
00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00010 /*        vigra@informatik.uni-hamburg.de                               */
00011 /*                                                                      */
00012 /*    Permission is hereby granted, free of charge, to any person       */
00013 /*    obtaining a copy of this software and associated documentation    */
00014 /*    files (the "Software"), to deal in the Software without           */
00015 /*    restriction, including without limitation the rights to use,      */
00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00017 /*    sell copies of the Software, and to permit persons to whom the    */
00018 /*    Software is furnished to do so, subject to the following          */
00019 /*    conditions:                                                       */
00020 /*                                                                      */
00021 /*    The above copyright notice and this permission notice shall be    */
00022 /*    included in all copies or substantial portions of the             */
00023 /*    Software.                                                         */
00024 /*                                                                      */
00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
00033 /*                                                                      */
00034 /************************************************************************/
00035 
00036 
00037 #ifndef VIGRA_MULTI_IMPEX_HXX
00038 #define VIGRA_MULTI_IMPEX_HXX
00039 
00040 #include <memory>
00041 #include <iomanip>
00042 #include <sstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <fstream>
00046 
00047 #include "config.hxx"
00048 #include "basicimageview.hxx"
00049 #include "impex.hxx"
00050 #include "multi_array.hxx"
00051 #include "multi_pointoperators.hxx"
00052 
00053 #ifdef _MSC_VER
00054 # include <direct.h>
00055 #else
00056 # include <unistd.h>
00057 #endif
00058 
00059 namespace vigra {
00060 
00061 /** \addtogroup VolumeImpex Import/export of volume data.
00062 */
00063 
00064 //@{
00065 
00066 /** \brief Argument object for the function importVolume().
00067 
00068     See \ref importVolume() for usage example. This object can be used
00069     to define the properties of a volume data set to be read from disk.
00070     Sorry, no \ref detailedDocumentation() available yet.
00071 
00072     <b>\#include</b> <vigra/multi_impex.hxx><br>
00073     Namespace: vigra
00074 **/
00075 class VolumeImportInfo
00076 {
00077   public:
00078     typedef ImageImportInfo::PixelType PixelType;
00079 
00080         /// type of volume size returned by shape()
00081     typedef MultiArrayShape<3>::type   ShapeType;
00082 
00083         /// provided for backwards-compatibility (deprecated)
00084     typedef ShapeType                  size_type;
00085 
00086         /// 3D resolution type returned by resolution()
00087     typedef TinyVector<float, 3>       Resolution;
00088 
00089     VIGRA_EXPORT VolumeImportInfo(const std::string &filename);
00090     VIGRA_EXPORT VolumeImportInfo(const std::string &baseName, const std::string &extension);
00091 
00092     VIGRA_EXPORT ShapeType shape() const;
00093 
00094         /** Get width of the volume.
00095          **/
00096     VIGRA_EXPORT MultiArrayIndex width() const;
00097 
00098         /** Get height of the volume.
00099          **/
00100     VIGRA_EXPORT MultiArrayIndex height() const;
00101 
00102         /** Get depth of the volume.
00103          **/
00104     VIGRA_EXPORT MultiArrayIndex depth() const;
00105 
00106         /**
00107          * resolution() contains the alignment and resolution of the
00108          * volume.  resolution()[0] is the x increment in a left-handed
00109          * world coordinate system of one unstrided step in the volume
00110          * memory.  The [1] and [2] elements contain the y resp. z
00111          * increments of the strided row resp. slice steps in the
00112          * volume.
00113          *
00114          * EXAMPLES: (1.f, 1.f, 4.f) means that the slices are four
00115          * times thicker than the x/y resolution.
00116          * (1.f, -1.f, 1.f) means that the volume coordinate system is
00117          * right-handed.
00118          */
00119     VIGRA_EXPORT Resolution resolution() const;
00120 
00121         /** Query the pixel type of the image.
00122 
00123             Possible values are:
00124             <DL>
00125             <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
00126             <DT>"INT16"<DD> 16-bit signed integer (short)
00127             <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
00128             <DT>"INT32"<DD> 32-bit signed integer (long)
00129             <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
00130             <DT>"FLOAT"<DD> 32-bit floating point (float)
00131             <DT>"DOUBLE"<DD> 64-bit floating point (double)
00132             </DL>
00133          **/
00134     VIGRA_EXPORT const char * getPixelType() const;
00135 
00136         /** Query the pixel type of the image.
00137 
00138             Same as getPixelType(), but the result is returned as a 
00139             ImageImportInfo::PixelType enum. This is useful to implement
00140             a switch() on the pixel type.
00141 
00142             Possible values are:
00143             <DL>
00144             <DT>UINT8<DD> 8-bit unsigned integer (unsigned char)
00145             <DT>INT16<DD> 16-bit signed integer (short)
00146             <DT>UINT16<DD> 16-bit unsigned integer (unsigned short)
00147             <DT>INT32<DD> 32-bit signed integer (long)
00148             <DT>UINT32<DD> 32-bit unsigned integer (unsigned long)
00149             <DT>FLOAT<DD> 32-bit floating point (float)
00150             <DT>DOUBLE<DD> 64-bit floating point (double)
00151             </DL>
00152          **/
00153     VIGRA_EXPORT PixelType pixelType() const;
00154 
00155     VIGRA_EXPORT MultiArrayIndex numBands() const;
00156     VIGRA_EXPORT bool isGrayscale() const;
00157     VIGRA_EXPORT bool isColor() const;
00158 
00159     // get base file name without path, image index, and extension
00160     VIGRA_EXPORT const std::string &name() const;
00161 
00162     VIGRA_EXPORT const std::string &description() const;
00163 
00164     template <class T, class Stride>
00165     void importImpl(MultiArrayView <3, T, Stride> &volume) const;
00166 
00167   protected:
00168     void getVolumeInfoFromFirstSlice(const std::string &filename);
00169 
00170     size_type shape_;
00171     Resolution resolution_;
00172     //PixelType pixelType_;
00173     int numBands_;
00174 
00175     std::string path_, name_, description_, pixelType_;
00176 
00177     std::string rawFilename_;
00178     std::string baseName_, extension_;
00179     std::vector<std::string> numbers_;
00180 };
00181 
00182 /********************************************************/
00183 /*                                                      */
00184 /*                   VolumeExportInfo                    */
00185 /*                                                      */
00186 /********************************************************/
00187 
00188 /** \brief Argument object for the function exportVolume().
00189 
00190     See \ref exportVolume() for usage example. This object must be used
00191     to define the properties of a volume to be written to disk.
00192 
00193     <b>\#include</b> <vigra/imageinfo.hxx><br>
00194     Namespace: vigra
00195 **/
00196 class VolumeExportInfo
00197 {
00198   public:
00199         /** Construct VolumeExportInfo object.
00200 
00201             The volume will be stored in a by-slice manner, where the number of slices 
00202             equals the depth of the volume. The file names will be enumerated like
00203             <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.
00204             (the actual number of zeros depends on the depth). If the target image type
00205             does not support the source voxel type, all slices will be mapped 
00206             simultaneously to the appropriate target range.
00207             The file type will be guessed from the extension unless overridden
00208             by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
00209             '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
00210             '.tif', '.tiff', '.xv', '.hdr'.
00211             JPEG support requires libjpeg, PNG support requires libpng, and
00212             TIFF support requires libtiff.
00213          **/
00214     VIGRA_EXPORT VolumeExportInfo( const char * name_base, const char * name_ext );
00215     VIGRA_EXPORT ~VolumeExportInfo();
00216 
00217         /** Set volume file name base.
00218 
00219         **/
00220     VIGRA_EXPORT VolumeExportInfo & setFileNameBase(const char * name_base);
00221         /** Set volume file name extension.
00222 
00223             The file type will be guessed from the extension unless overridden
00224             by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
00225             '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
00226             '.tif', '.tiff', '.xv', '.hdr'.
00227             JPEG support requires libjpeg, PNG support requires libpng, and
00228             TIFF support requires libtiff.
00229         **/
00230     VIGRA_EXPORT VolumeExportInfo & setFileNameExt(const char * name_ext);
00231     VIGRA_EXPORT const char * getFileNameBase() const;
00232     VIGRA_EXPORT const char * getFileNameExt() const;
00233 
00234         /** Store volume as given file type.
00235 
00236             This will override any type guessed
00237             from the file name's extension. Recognized file types:
00238 
00239             <DL>
00240             <DT>"BMP"<DD> Microsoft Windows bitmap image file.
00241             <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color.
00242             <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format;
00243             compressed 24-bit color (only available if libjpeg is installed).
00244             <DT>"PNG"<DD> Portable Network Graphic
00245             (only available if libpng is installed).
00246             <DT>"PBM"<DD> Portable bitmap format (black and white).
00247             <DT>"PGM"<DD> Portable graymap format (gray scale).
00248             <DT>"PNM"<DD> Portable anymap.
00249             <DT>"PPM"<DD> Portable pixmap format (color).
00250             <DT>"SUN"<DD> SUN Rasterfile.
00251             <DT>"TIFF"<DD> Tagged Image File Format.
00252             (only available if libtiff is installed.)
00253             <DT>"VIFF"<DD> Khoros Visualization image file.
00254             </DL>
00255 
00256             With the exception of TIFF, VIFF, PNG, and PNM all file types store
00257             1 byte (gray scale and mapped RGB) or 3 bytes (RGB) per
00258             pixel.
00259 
00260             PNG can store UInt8 and UInt16 values, and supports 1 and 3 channel
00261             images. One additional alpha channel is also supported.
00262 
00263             PNM can store 1 and 3 channel images with UInt8, UInt16 and UInt32
00264             values in each channel.
00265 
00266             TIFF and VIFF are additionally able to store short and long
00267             integers (2 or 4 bytes) and real values (32 bit float and
00268             64 bit double) without conversion. So you will need to use
00269             TIFF or VIFF if you need to store images with high
00270             accuracy (the appropriate type to write is automatically
00271             derived from the image type to be exported). However, many
00272             other programs using TIFF (e.g. ImageMagick) have not
00273             implemented support for those pixel types.  So don't be
00274             surprised if the generated TIFF is not readable in some
00275             cases.  If this happens, export the image as 'unsigned
00276             char' or 'RGBValue<unsigned char>' by calling
00277             \ref ImageExportInfo::setPixelType().
00278 
00279             Support to reading and writing ICC color profiles is
00280             provided for TIFF, JPEG, and PNG images.
00281          **/
00282     VIGRA_EXPORT VolumeExportInfo & setFileType( const char * );
00283     VIGRA_EXPORT const char * getFileType() const;
00284 
00285         /** Set compression type and quality.
00286 
00287             See \ref ImageExportInfo::setCompression() for details.
00288          **/
00289     VIGRA_EXPORT VolumeExportInfo & setCompression( const char * type);
00290     VIGRA_EXPORT const char * getCompression() const;
00291 
00292         /** Set the pixel type of the volume file(s). Possible values are:
00293             <DL>
00294             <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
00295             <DT>"INT16"<DD> 16-bit signed integer (short)
00296             <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
00297             <DT>"INT32"<DD> 32-bit signed integer (long)
00298             <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
00299             <DT>"FLOAT"<DD> 32-bit floating point (float)
00300             <DT>"DOUBLE"<DD> 64-bit floating point (double)
00301             </DL>
00302          **/
00303     VIGRA_EXPORT VolumeExportInfo & setPixelType( const char * );
00304 
00305         /** Get the pixel type of the images in the volume. Possible values are:
00306             <DL>
00307             <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
00308             <DT>"INT16"<DD> 16-bit signed integer (short)
00309             <DT>"INT32"<DD> 32-bit signed integer (long)
00310             <DT>"FLOAT"<DD> 32-bit floating point (float)
00311             <DT>"DOUBLE"<DD> 64-bit floating point (double)
00312             </DL>
00313          **/
00314     VIGRA_EXPORT const char * getPixelType() const;
00315     
00316     VIGRA_EXPORT VolumeExportInfo & setForcedRangeMapping(double fromMin, double fromMax,
00317                                                      double toMin, double toMax);    
00318     VIGRA_EXPORT bool hasForcedRangeMapping() const;
00319     VIGRA_EXPORT double getFromMin() const;
00320     VIGRA_EXPORT double getFromMax() const;
00321     VIGRA_EXPORT double getToMin() const;
00322     VIGRA_EXPORT double getToMax() const;
00323     
00324         /** Set the volume resolution in horizontal direction
00325          **/
00326     VIGRA_EXPORT VolumeExportInfo & setXResolution( float );
00327     VIGRA_EXPORT float getXResolution() const;
00328 
00329         /** Set the image resolution in vertical direction
00330          **/
00331     VIGRA_EXPORT VolumeExportInfo & setYResolution( float );
00332     VIGRA_EXPORT float getYResolution() const;
00333 
00334         /** Set the image resolution in depth direction
00335          **/
00336     VIGRA_EXPORT VolumeExportInfo & setZResolution( float );
00337     VIGRA_EXPORT float getZResolution() const;
00338 
00339         /** Set the position of the upper Left corner on a global
00340             canvas.
00341 
00342             Currently only supported by TIFF and PNG files.
00343 
00344             The offset is encoded in the XPosition and YPosition TIFF tags.
00345 
00346             @param pos     position of the upper left corner in pixels
00347                            (must be >= 0)
00348          **/
00349     // FIXME: mhanselm: we might want to support 3D positions
00350     VIGRA_EXPORT VolumeExportInfo & setPosition(const Diff2D & pos);
00351 
00352         /** Get the position of the upper left corner on
00353             a global canvas.
00354          **/
00355     // FIXME: mhanselm: we might want to support 3D positions
00356     VIGRA_EXPORT Diff2D getPosition() const;
00357 
00358         /**
00359           ICC profiles (handled as raw data so far).
00360           see getICCProfile()/setICCProfile()
00361          **/
00362     typedef ArrayVector<unsigned char> ICCProfile;
00363 
00364         /** Returns a reference to the ICC profile.
00365          */
00366     VIGRA_EXPORT const ICCProfile & getICCProfile() const;
00367 
00368         /** Sets the ICC profile.
00369             ICC profiles are currently supported by TIFF, PNG and JPEG images.
00370             (Otherwise, the profile data is silently ignored.)
00371          **/
00372     VIGRA_EXPORT VolumeExportInfo & setICCProfile(const ICCProfile & profile);
00373 
00374   private:
00375     float m_x_res, m_y_res, m_z_res;
00376 
00377     std::string m_filetype, m_filename_base, m_filename_ext, m_pixeltype, m_comp;
00378     Diff2D m_pos;
00379     ICCProfile m_icc_profile;
00380     double fromMin_, fromMax_, toMin_, toMax_;
00381 };
00382 
00383 namespace detail {
00384 
00385 template <class DestIterator, class Shape, class T>
00386 inline void
00387 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<0>)
00388 {
00389     s.read((char*)buffer.begin(), shape[0]*sizeof(T));
00390 
00391     DestIterator dend = d + shape[0];
00392     int k = 0;
00393     for(; d < dend; ++d, k++)
00394     {
00395         *d = buffer[k];
00396     }
00397 }
00398 
00399 template <class DestIterator, class Shape, class T, int N>
00400 void
00401 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<N>)
00402 {
00403     DestIterator dend = d + shape[N];
00404     for(; d < dend; ++d)
00405     {
00406         readVolumeImpl(d.begin(), shape, s, buffer, MetaInt<N-1>());
00407     }
00408 }
00409 
00410 } // namespace detail
00411 
00412 template <class T, class Stride>
00413 void VolumeImportInfo::importImpl(MultiArrayView <3, T, Stride> &volume) const
00414 {
00415     vigra_precondition(this->shape() == volume.shape(), "importVolume(): Volume must be shaped according to VolumeImportInfo.");
00416 
00417     if(rawFilename_.size())
00418     {
00419         std::string dirName, baseName;
00420         char oldCWD[2048];
00421 
00422 #ifdef _MSC_VER
00423         if(_getcwd(oldCWD, 2048) == 0)
00424         {
00425             perror("getcwd");
00426             vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
00427         }
00428         if(_chdir(path_.c_str()))
00429         {
00430             perror("chdir");
00431             vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
00432         }
00433 #else
00434         if(getcwd(oldCWD, 2048) == 0)
00435         {
00436             perror("getcwd");
00437             vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
00438         }
00439         if(chdir(path_.c_str()))
00440         {
00441             perror("chdir");
00442             vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
00443         }
00444 #endif
00445 
00446         std::ifstream s(rawFilename_.c_str(), std::ios::binary);
00447         vigra_precondition(s.good(), "RAW file could not be opened");
00448 
00449         ArrayVector<T> buffer(shape_[0]);
00450         detail::readVolumeImpl(volume.traverser_begin(), shape_, s, buffer, vigra::MetaInt<2>());
00451 
00452         //vigra_precondition(s.good(), "RAW file could not be opened");
00453         //s.read((char*)volume.data(), shape_[0]*shape_[1]*shape_[2]*sizeof(T));
00454 
00455 #ifdef _MSC_VER
00456         if(_chdir(oldCWD))
00457             perror("chdir");
00458 #else
00459         if(chdir(oldCWD))
00460             perror("chdir");
00461 #endif
00462 
00463         vigra_postcondition(
00464             volume.shape() == shape(), "imported volume has wrong size");
00465     }
00466     else
00467     {
00468         for (unsigned int i = 0; i < numbers_.size(); ++i)
00469         {
00470             // build the filename
00471             std::string name = baseName_ + numbers_[i] + extension_;
00472 
00473             // import the image
00474             ImageImportInfo info (name.c_str ());
00475 
00476             // generate a basic image view to the current layer
00477             MultiArrayView <2, T, Stride> view (volume.bindOuter (i));
00478             vigra_precondition(view.shape() == info.shape(),
00479                 "importVolume(): the images have inconsistent sizes.");
00480 
00481             importImage (info, destImage(view));
00482         }
00483     }
00484 }
00485 
00486 
00487 VIGRA_EXPORT void findImageSequence(const std::string &name_base,
00488                        const std::string &name_ext,
00489                        std::vector<std::string> & numbers);
00490 
00491 /********************************************************/
00492 /*                                                      */
00493 /*                    importVolume                      */
00494 /*                                                      */
00495 /********************************************************/
00496 
00497 /** \brief Function for importing a 3D volume.
00498 
00499     The data are expected to be stored in a by-slice manner,
00500     where the slices are enumerated from <tt>name_base+"[0-9]+"+name_ext</tt>.
00501     <tt>name_base</tt> may contain a path. All slice files with the same name base and
00502     extension are considered part of the same volume. Slice numbers must be non-negative,
00503     but can otherwise start anywhere and need not be successive. Slices will be read
00504     in ascending numerical (not lexicographic) order. All slices must have the
00505     same size. The <tt>volume</tt> will be reshaped to match the count and
00506     size of the slices found.
00507 
00508     <b>\#include</b>
00509     <vigra/multi_impex.hxx>
00510 
00511     Namespace: vigra
00512 */
00513 template <class T, class Allocator>
00514 void importVolume (MultiArray <3, T, Allocator> & volume,
00515                    const std::string &name_base,
00516                    const std::string &name_ext)
00517 {
00518     VolumeImportInfo info(name_base, name_ext);
00519     volume.reshape(info.shape());
00520 
00521     info.importImpl(volume);
00522 }
00523 
00524 
00525 /** \brief Function for importing a 3D volume.
00526 
00527     The data can be given in two ways:
00528 
00529     <UL>
00530     <LI> If the volume is stored in a by-slice manner (e.g. one image per slice),
00531          the <tt>filename</tt> can refer to an arbitrary image from the set. <tt>importVolume()</tt>
00532          then assumes that the slices are enumerated like <tt>name_base+"[0-9]+"+name_ext</tt>,
00533          where <tt>name_base</tt>, the index, and <tt>name_ext</tt> are determined automatically.
00534          All slice files with the same name base and extension are considered part of the same
00535          volume. Slice numbers must be non-negative, but can otherwise start anywhere and need
00536          not be successive. Slices will be read in ascending numerical (not lexicographic) order.
00537          All slices must have the same size.
00538     <li> Otherwise, <tt>importVolume()</tt> will try to read <tt>filename</tt> as an
00539          info text file with the following key-value pairs:
00540          <UL>
00541          <LI> name = [short descriptive name of the volume] (optional)
00542          <LI> filename = [absolute or relative path to raw voxel data file] (required)
00543          <li> gradfile =  [absolute or relative path to gradient data file] (currently ignored)
00544          <li> description =  [arbitrary description of the data set] (optional)
00545          <li> width = [positive integer] (required)
00546          <li> height = [positive integer] (required)
00547          <li> depth = [positive integer] (required)
00548          <li> datatype = [UNSIGNED_CHAR | UNSIGNED_BYTE] (default: UNSIGNED_CHAR)
00549          </UL>
00550          The voxel type is currently assumed to be binary compatible to the <tt>value_type T</TT>
00551          of the <tt>MuliArray</tt>. Lines starting with "#" are ignored.
00552     </UL>
00553 
00554     In either case, the <tt>volume</tt> will be reshaped to match the count and
00555     size of the slices found.
00556 
00557     <b>\#include</b>
00558     <vigra/multi_impex.hxx>
00559 
00560     Namespace: vigra
00561 */
00562 template <class T, class Allocator>
00563 void importVolume(MultiArray <3, T, Allocator> &volume,
00564                   const std::string &filename)
00565 {
00566     VolumeImportInfo info(filename);
00567     volume.reshape(info.shape());
00568 
00569     info.importImpl(volume);
00570 }
00571 
00572 /** \brief Function for importing a 3D volume.
00573 
00574     Read the volume data set <tt>info</tt> refers to. Explicit construction
00575     of the info object allows to allocate a <tt>volume</tt> object type whose
00576     <tt>value_type</tt> matches the voxel type of the stored data.
00577     The <tt>volume</tt> will be reshaped to match the count and
00578     size of the slices found.
00579 
00580     <b>\#include</b>
00581     <vigra/multi_impex.hxx>
00582 
00583     Namespace: vigra
00584 */
00585 template <class T, class Stride>
00586 void importVolume(VolumeImportInfo const & info, MultiArrayView <3, T, Stride> &volume)
00587 {
00588     info.importImpl(volume);
00589 }
00590 
00591 namespace detail {
00592 
00593 template <class T>
00594 void setRangeMapping(std::string const & pixeltype,
00595                      FindMinMax<T> const & minmax, ImageExportInfo & info)
00596 {
00597     if(pixeltype == "UINT8")
00598         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00599                                    (double)NumericTraits<UInt8>::min(),
00600                                    (double)NumericTraits<UInt8>::max());
00601     else if(pixeltype == "INT16")
00602         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00603                                    (double)NumericTraits<Int16>::min(),
00604                                    (double)NumericTraits<Int16>::max());
00605     else if(pixeltype == "UINT16")
00606         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00607                                    (double)NumericTraits<UInt16>::min(),
00608                                    (double)NumericTraits<UInt16>::max());
00609     else if(pixeltype == "INT32")
00610         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00611                                    (double)NumericTraits<Int32>::min(),
00612                                    (double)NumericTraits<Int32>::max());
00613     else if(pixeltype == "UINT32")
00614         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00615                                    (double)NumericTraits<UInt32>::min(),
00616                                    (double)NumericTraits<UInt32>::max());
00617     else if(pixeltype == "FLOAT")
00618         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
00619     else if(pixeltype == "DOUBLE")
00620         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
00621 }
00622 
00623 template <class T, class Tag>
00624 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
00625                      ImageExportInfo & info, VigraTrueType /* isScalar */)
00626 {
00627     std::string pixeltype = info.getPixelType();
00628     bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
00629                                        TypeAsString<T>::result(), pixeltype);
00630 
00631     if(downcast)
00632     {
00633         FindMinMax<T> minmax;
00634         inspectMultiArray(srcMultiArrayRange(volume), minmax);
00635         setRangeMapping(pixeltype, minmax, info);
00636     }
00637 }
00638 
00639 template <class T, class Tag>
00640 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
00641                      ImageExportInfo & info, VigraFalseType /* isScalar */)
00642 {
00643     typedef typename T::value_type SrcComponent;
00644     std::string pixeltype = info.getPixelType();
00645     bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
00646                                        TypeAsString<SrcComponent>::result(), pixeltype);
00647 
00648     if(downcast)
00649     {
00650         unsigned int bands = volume(0,0,0).size();
00651         FindMinMax<SrcComponent> minmax;
00652         for(unsigned int i=0; i<bands; ++i)
00653         {
00654             VectorComponentValueAccessor<T> band(i);
00655             inspectMultiArray(srcMultiArrayRange(volume, band), minmax );
00656         }
00657         setRangeMapping(pixeltype, minmax, info);
00658     }
00659 }
00660 
00661 } // namespace detail
00662 
00663 /********************************************************/
00664 /*                                                      */
00665 /*                    exportVolume                      */
00666 /*                                                      */
00667 /********************************************************/
00668 
00669 /** \brief Function for exporting a 3D volume.
00670 
00671     The volume is exported in a by-slice manner, where the number of slices equals
00672     the depth of the volume. The file names will be enumerated like
00673     <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.
00674     (the actual number of zeros depends on the depth). If the target image type
00675     does not support the source voxel type, all slices will be mapped simultaneously
00676     to the appropriate target range.
00677 
00678     <b>\#include</b>
00679     <vigra/multi_impex.hxx>
00680 
00681     Namespace: vigra
00682 */
00683 template <class T, class Tag>
00684 void exportVolume (MultiArrayView <3, T, Tag> const & volume,
00685                    const VolumeExportInfo & volinfo)
00686 {
00687     std::string name = std::string(volinfo.getFileNameBase()) + std::string(volinfo.getFileNameExt());
00688     ImageExportInfo info(name.c_str());
00689     info.setCompression(volinfo.getCompression());
00690     info.setPixelType(volinfo.getPixelType());
00691     detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScalar());
00692 
00693     const unsigned int depth = volume.shape (2);
00694     int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth)));
00695     for (unsigned int i = 0; i < depth; ++i)
00696     {
00697 
00698         // build the filename
00699         std::stringstream stream;
00700         stream << std::setfill ('0') << std::setw (numlen) << i;
00701         std::string name_num;
00702         stream >> name_num;
00703         std::string name = std::string(volinfo.getFileNameBase()) + name_num + std::string(volinfo.getFileNameExt());
00704 
00705         MultiArrayView <2, T, Tag> view (volume.bindOuter (i));
00706 
00707         // export the image
00708         info.setFileName(name.c_str ());
00709         exportImage(srcImageRange(view), info); 
00710     }
00711 }
00712 
00713 // for backward compatibility
00714 template <class T, class Tag>
00715 inline 
00716 void exportVolume (MultiArrayView <3, T, Tag> const & volume,
00717                    const std::string &name_base,
00718                    const std::string &name_ext)
00719 {
00720     VolumeExportInfo volinfo(name_base.c_str(), name_ext.c_str());
00721     exportVolume(volume, volinfo);
00722 }
00723 
00724 //@}
00725 
00726 } // namespace vigra
00727 
00728 #endif // VIGRA_MULTI_IMPEX_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.8.0 (20 Sep 2011)