vigra - vigra/multi_impex.hxx Source File

[ 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> <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.9.0 (Tue Nov 6 2012)