[ 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.1 (3 Dec 2010)