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

vigra/multi_impex.hxx
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> <<a href="imageinfo_8hxx-source.html">vigra/multi_impex.hxx</a>><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> <<a href="imageinfo_8hxx-source.html">vigra/imageinfo.hxx</a>><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 aditionally 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.
00286 
00287             Recognized strings: "" (no compression), "LZW",
00288             "RunLength", "1" ... "100". A number is interpreted as the
00289             compression quality for JPEG compression. JPEG compression is
00290             supported by the JPEG and TIFF formats. "LZW" is only available
00291             if libtiff was installed with LZW enabled. By default, libtiff came
00292             with LZW disabled due to Unisys patent enforcement. In this case,
00293             VIGRA stores the image uncompressed.
00294 
00295                 Valid Compression for TIFF files:
00296                   JPEG    jpeg compression, call setQuality as well!
00297                   RLE     runlength compression
00298                   LZW     lzw compression
00299                   DEFLATE deflate compression
00300          **/
00301     VIGRA_EXPORT VolumeExportInfo & setCompression( const char * );
00302     VIGRA_EXPORT const char * getCompression() const;
00303 
00304         /** Set the pixel type of the volume file(s). Possible values are:
00305             <DL>
00306             <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
00307             <DT>"INT16"<DD> 16-bit signed integer (short)
00308             <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
00309             <DT>"INT32"<DD> 32-bit signed integer (long)
00310             <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
00311             <DT>"FLOAT"<DD> 32-bit floating point (float)
00312             <DT>"DOUBLE"<DD> 64-bit floating point (double)
00313             </DL>
00314          **/
00315     VIGRA_EXPORT VolumeExportInfo & setPixelType( const char * );
00316 
00317         /** Get the pixel type of the images in the volume. Possible values are:
00318             <DL>
00319             <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
00320             <DT>"INT16"<DD> 16-bit signed integer (short)
00321             <DT>"INT32"<DD> 32-bit signed integer (long)
00322             <DT>"FLOAT"<DD> 32-bit floating point (float)
00323             <DT>"DOUBLE"<DD> 64-bit floating point (double)
00324             </DL>
00325          **/
00326     VIGRA_EXPORT const char * getPixelType() const;
00327     
00328     VIGRA_EXPORT VolumeExportInfo & setForcedRangeMapping(double fromMin, double fromMax,
00329                                                      double toMin, double toMax);    
00330     VIGRA_EXPORT bool hasForcedRangeMapping() const;
00331     VIGRA_EXPORT double getFromMin() const;
00332     VIGRA_EXPORT double getFromMax() const;
00333     VIGRA_EXPORT double getToMin() const;
00334     VIGRA_EXPORT double getToMax() const;
00335     
00336         /** Set the volume resolution in horizontal direction
00337          **/
00338     VIGRA_EXPORT VolumeExportInfo & setXResolution( float );
00339     VIGRA_EXPORT float getXResolution() const;
00340 
00341         /** Set the image resolution in vertical direction
00342          **/
00343     VIGRA_EXPORT VolumeExportInfo & setYResolution( float );
00344     VIGRA_EXPORT float getYResolution() const;
00345 
00346         /** Set the image resolution in depth direction
00347          **/
00348     VIGRA_EXPORT VolumeExportInfo & setZResolution( float );
00349     VIGRA_EXPORT float getZResolution() const;
00350 
00351         /** Set the position of the upper Left corner on a global
00352             canvas.
00353 
00354             Currently only supported by TIFF and PNG files.
00355 
00356             The offset is encoded in the XPosition and YPosition TIFF tags.
00357 
00358             @param pos     position of the upper left corner in pixels
00359                            (must be >= 0)
00360          **/
00361     // FIXME: mhanselm: we might want to support 3D positions
00362     VIGRA_EXPORT VolumeExportInfo & setPosition(const Diff2D & pos);
00363 
00364         /** Get the position of the upper left corner on
00365             a global canvas.
00366          **/
00367     // FIXME: mhanselm: we might want to support 3D positions
00368     VIGRA_EXPORT Diff2D getPosition() const;
00369 
00370         /**
00371           ICC profiles (handled as raw data so far).
00372           see getICCProfile()/setICCProfile()
00373          **/
00374     typedef ArrayVector<unsigned char> ICCProfile;
00375 
00376         /** Returns a reference to the ICC profile.
00377          */
00378     VIGRA_EXPORT const ICCProfile & getICCProfile() const;
00379 
00380         /** Sets the ICC profile.
00381             ICC profiles are currently supported by TIFF, PNG and JPEG images.
00382             (Otherwise, the profile data is silently ignored.)
00383          **/
00384     VIGRA_EXPORT VolumeExportInfo & setICCProfile(const ICCProfile & profile);
00385 
00386   private:
00387     float m_x_res, m_y_res, m_z_res;
00388 
00389     std::string m_filetype, m_filename_base, m_filename_ext, m_pixeltype, m_comp;
00390     Diff2D m_pos;
00391     ICCProfile m_icc_profile;
00392     double fromMin_, fromMax_, toMin_, toMax_;
00393 };
00394 
00395 namespace detail {
00396 
00397 template <class DestIterator, class Shape, class T>
00398 inline void
00399 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<0>)
00400 {
00401     s.read((char*)buffer.begin(), shape[0]*sizeof(T));
00402 
00403     DestIterator dend = d + shape[0];
00404     int k = 0;
00405     for(; d < dend; ++d, k++)
00406     {
00407         *d = buffer[k];
00408     }
00409 }
00410 
00411 template <class DestIterator, class Shape, class T, int N>
00412 void
00413 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<N>)
00414 {
00415     DestIterator dend = d + shape[N];
00416     for(; d < dend; ++d)
00417     {
00418         readVolumeImpl(d.begin(), shape, s, buffer, MetaInt<N-1>());
00419     }
00420 }
00421 
00422 } // namespace detail
00423 
00424 template <class T, class Stride>
00425 void VolumeImportInfo::importImpl(MultiArrayView <3, T, Stride> &volume) const
00426 {
00427     vigra_precondition(this->shape() == volume.shape(), "importVolume(): Volume must be shaped according to VolumeImportInfo.");
00428 
00429     if(rawFilename_.size())
00430     {
00431         std::string dirName, baseName;
00432         char oldCWD[2048];
00433 
00434 #ifdef _MSC_VER
00435         if(_getcwd(oldCWD, 2048) == 0)
00436         {
00437             perror("getcwd");
00438             vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
00439         }
00440         if(_chdir(path_.c_str()))
00441         {
00442             perror("chdir");
00443             vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
00444         }
00445 #else
00446         if(getcwd(oldCWD, 2048) == 0)
00447         {
00448             perror("getcwd");
00449             vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
00450         }
00451         if(chdir(path_.c_str()))
00452         {
00453             perror("chdir");
00454             vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
00455         }
00456 #endif
00457 
00458         std::ifstream s(rawFilename_.c_str(), std::ios::binary);
00459         vigra_precondition(s.good(), "RAW file could not be opened");
00460 
00461         ArrayVector<T> buffer(shape_[0]);
00462         detail::readVolumeImpl(volume.traverser_begin(), shape_, s, buffer, vigra::MetaInt<2>());
00463 
00464         //vigra_precondition(s.good(), "RAW file could not be opened");
00465         //s.read((char*)volume.data(), shape_[0]*shape_[1]*shape_[2]*sizeof(T));
00466 
00467 #ifdef _MSC_VER
00468         if(_chdir(oldCWD))
00469             perror("chdir");
00470 #else
00471         if(chdir(oldCWD))
00472             perror("chdir");
00473 #endif
00474 
00475         vigra_postcondition(
00476             volume.shape() == shape(), "imported volume has wrong size");
00477     }
00478     else
00479     {
00480         for (unsigned int i = 0; i < numbers_.size(); ++i)
00481         {
00482             // build the filename
00483             std::string name = baseName_ + numbers_[i] + extension_;
00484 
00485             // import the image
00486             ImageImportInfo info (name.c_str ());
00487 
00488             // generate a basic image view to the current layer
00489             MultiArrayView <2, T, Stride> view (volume.bindOuter (i));
00490             vigra_precondition(view.shape() == info.shape(),
00491                 "importVolume(): the images have inconsistent sizes.");
00492 
00493             importImage (info, destImage(view));
00494         }
00495     }
00496 }
00497 
00498 
00499 VIGRA_EXPORT void findImageSequence(const std::string &name_base,
00500                        const std::string &name_ext,
00501                        std::vector<std::string> & numbers);
00502 
00503 /********************************************************/
00504 /*                                                      */
00505 /*                    importVolume                      */
00506 /*                                                      */
00507 /********************************************************/
00508 
00509 /** \brief Function for importing a 3D volume.
00510 
00511     The data are expected to be stored in a by-slice manner,
00512     where the slices are enumerated from <tt>name_base+"[0-9]+"+name_ext</tt>.
00513     <tt>name_base</tt> may contain a path. All slice files with the same name base and
00514     extension are considered part of the same volume. Slice numbers must be non-negative,
00515     but can otherwise start anywhere and need not be successive. Slices will be read
00516     in ascending numerical (not lexicographic) order. All slices must have the
00517     same size. The <tt>volume</tt> will be reshaped to match the count and
00518     size of the slices found.
00519 
00520     <b>\#include</b>
00521     <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
00522 
00523     Namespace: vigra
00524 */
00525 template <class T, class Allocator>
00526 void importVolume (MultiArray <3, T, Allocator> & volume,
00527                    const std::string &name_base,
00528                    const std::string &name_ext)
00529 {
00530     VolumeImportInfo info(name_base, name_ext);
00531     volume.reshape(info.shape());
00532 
00533     info.importImpl(volume);
00534 }
00535 
00536 
00537 /** \brief Function for importing a 3D volume.
00538 
00539     The data can be given in two ways:
00540 
00541     <UL>
00542     <LI> If the volume is stored in a by-slice manner (e.g. one image per slice),
00543          the <tt>filename</tt> can refer to an arbitrary image from the set. <tt>importVolume()</tt>
00544          then assumes that the slices are enumerated like <tt>name_base+"[0-9]+"+name_ext</tt>,
00545          where <tt>name_base</tt>, the index, and <tt>name_ext</tt> are determined automatically.
00546          All slice files with the same name base and extension are considered part of the same
00547          volume. Slice numbers must be non-negative, but can otherwise start anywhere and need
00548          not be successive. Slices will be read in ascending numerical (not lexicographic) order.
00549          All slices must have the same size.
00550     <li> Otherwise, <tt>importVolume()</tt> will try to read <tt>filename</tt> as an
00551          info text file with the following key-value pairs:
00552          <UL>
00553          <LI> name = [short descriptive name of the volume] (optional)
00554          <LI> filename = [absolute or relative path to raw voxel data file] (required)
00555          <li> gradfile =  [absolute or relative path to gradient data file] (currently ignored)
00556          <li> description =  [arbitrary description of the data set] (optional)
00557          <li> width = [positive integer] (required)
00558          <li> height = [positive integer] (required)
00559          <li> depth = [positive integer] (required)
00560          <li> datatype = [UNSIGNED_CHAR | UNSIGNED_BYTE] (default: UNSIGNED_CHAR)
00561          </UL>
00562          The voxel type is currently assumed to be binary compatible to the <tt>value_type T</TT>
00563          of the <tt>MuliArray</tt>. Lines starting with "#" are ignored.
00564     </UL>
00565 
00566     In either case, the <tt>volume</tt> will be reshaped to match the count and
00567     size of the slices found.
00568 
00569     <b>\#include</b>
00570     <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
00571 
00572     Namespace: vigra
00573 */
00574 template <class T, class Allocator>
00575 void importVolume(MultiArray <3, T, Allocator> &volume,
00576                   const std::string &filename)
00577 {
00578     VolumeImportInfo info(filename);
00579     volume.reshape(info.shape());
00580 
00581     info.importImpl(volume);
00582 }
00583 
00584 /** \brief Function for importing a 3D volume.
00585 
00586     Read the volume data set <tt>info</tt> refers to. Explicit construction
00587     of the info object allows to allocate a <tt>volume</tt> object type whose
00588     <tt>value_type</tt> matches the voxel type of the stored data.
00589     The <tt>volume</tt> will be reshaped to match the count and
00590     size of the slices found.
00591 
00592     <b>\#include</b>
00593     <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
00594 
00595     Namespace: vigra
00596 */
00597 template <class T, class Stride>
00598 void importVolume(VolumeImportInfo const & info, MultiArrayView <3, T, Stride> &volume)
00599 {
00600     info.importImpl(volume);
00601 }
00602 
00603 namespace detail {
00604 
00605 template <class T>
00606 void setRangeMapping(std::string const & pixeltype,
00607                      FindMinMax<T> const & minmax, ImageExportInfo & info)
00608 {
00609     if(pixeltype == "UINT8")
00610         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00611                                    (double)NumericTraits<UInt8>::min(),
00612                                    (double)NumericTraits<UInt8>::max());
00613     else if(pixeltype == "INT16")
00614         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00615                                    (double)NumericTraits<Int16>::min(),
00616                                    (double)NumericTraits<Int16>::max());
00617     else if(pixeltype == "UINT16")
00618         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00619                                    (double)NumericTraits<UInt16>::min(),
00620                                    (double)NumericTraits<UInt16>::max());
00621     else if(pixeltype == "INT32")
00622         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00623                                    (double)NumericTraits<Int32>::min(),
00624                                    (double)NumericTraits<Int32>::max());
00625     else if(pixeltype == "UINT32")
00626         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
00627                                    (double)NumericTraits<UInt32>::min(),
00628                                    (double)NumericTraits<UInt32>::max());
00629     else if(pixeltype == "FLOAT")
00630         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
00631     else if(pixeltype == "DOUBLE")
00632         info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
00633 }
00634 
00635 template <class T, class Tag>
00636 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
00637                      ImageExportInfo & info, VigraTrueType /* isScalar */)
00638 {
00639     std::string pixeltype = info.getPixelType();
00640     bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
00641                                        TypeAsString<T>::result(), pixeltype);
00642 
00643     if(downcast)
00644     {
00645         FindMinMax<T> minmax;
00646         inspectMultiArray(srcMultiArrayRange(volume), minmax);
00647         setRangeMapping(pixeltype, minmax, info);
00648     }
00649 }
00650 
00651 template <class T, class Tag>
00652 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
00653                      ImageExportInfo & info, VigraFalseType /* isScalar */)
00654 {
00655     typedef typename T::value_type SrcComponent;
00656     std::string pixeltype = info.getPixelType();
00657     bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
00658                                        TypeAsString<SrcComponent>::result(), pixeltype);
00659 
00660     if(downcast)
00661     {
00662         unsigned int bands = volume(0,0,0).size();
00663         FindMinMax<SrcComponent> minmax;
00664         for(unsigned int i=0; i<bands; ++i)
00665         {
00666             VectorComponentValueAccessor<T> band(i);
00667             inspectMultiArray(srcMultiArrayRange(volume, band), minmax );
00668         }
00669         setRangeMapping(pixeltype, minmax, info);
00670     }
00671 }
00672 
00673 } // namespace detail
00674 
00675 /********************************************************/
00676 /*                                                      */
00677 /*                    exportVolume                      */
00678 /*                                                      */
00679 /********************************************************/
00680 
00681 /** \brief Function for exporting a 3D volume.
00682 
00683     The volume is exported in a by-slice manner, where the number of slices equals
00684     the depth of the volume. The file names will be enumerated like
00685     <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.
00686     (the actual number of zeros depends on the depth). If the target image type
00687     does not support the source voxel type, all slices will be mapped simultaneously
00688     to the appropriate target range.
00689 
00690     <b>\#include</b>
00691     <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
00692 
00693     Namespace: vigra
00694 */
00695 template <class T, class Tag>
00696 void exportVolume (MultiArrayView <3, T, Tag> const & volume,
00697                    const VolumeExportInfo & volinfo)
00698 {
00699     std::string name = std::string(volinfo.getFileNameBase()) + std::string(volinfo.getFileNameExt());
00700     ImageExportInfo info(name.c_str());
00701     info.setCompression(volinfo.getCompression());
00702     info.setPixelType(volinfo.getPixelType());
00703     detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScalar());
00704 
00705     const unsigned int depth = volume.shape (2);
00706     int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth)));
00707     for (unsigned int i = 0; i < depth; ++i)
00708     {
00709 
00710         // build the filename
00711         std::stringstream stream;
00712         stream << std::setfill ('0') << std::setw (numlen) << i;
00713         std::string name_num;
00714         stream >> name_num;
00715         std::string name = std::string(volinfo.getFileNameBase()) + name_num + std::string(volinfo.getFileNameExt());
00716 
00717         MultiArrayView <2, T, Tag> view (volume.bindOuter (i));
00718 
00719         // export the image
00720         info.setFileName(name.c_str ());
00721         exportImage(srcImageRange(view), info); 
00722     }
00723 }
00724 
00725 // for backward compatibility
00726 template <class T, class Tag>
00727 inline 
00728 void exportVolume (MultiArrayView <3, T, Tag> const & volume,
00729                    const std::string &name_base,
00730                    const std::string &name_ext)
00731 {
00732     VolumeExportInfo volinfo(name_base.c_str(), name_ext.c_str());
00733     exportVolume(volume, volinfo);
00734 }
00735 
00736 //@}
00737 
00738 } // namespace vigra
00739 
00740 #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.7.0 (Thu Aug 25 2011)