[ 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) |
html generated using doxygen and Python
|