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

multi_impex.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 2003 by Gunnar Kedenburg */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 
37 #ifndef VIGRA_MULTI_IMPEX_HXX
38 #define VIGRA_MULTI_IMPEX_HXX
39 
40 #include <memory>
41 #include <iomanip>
42 #include <sstream>
43 #include <iostream>
44 #include <string>
45 #include <fstream>
46 
47 #include "config.hxx"
48 #include "basicimageview.hxx"
49 #include "impex.hxx"
50 #include "multi_array.hxx"
51 #include "multi_pointoperators.hxx"
52 
53 #ifdef _MSC_VER
54 # include <direct.h>
55 #else
56 # include <unistd.h>
57 #endif
58 
59 namespace vigra {
60 
61 /** \addtogroup VolumeImpex Import/export of volume data.
62 */
63 
64 //@{
65 
66 /** \brief Argument object for the function importVolume().
67 
68  See \ref importVolume() for usage example. This object can be used
69  to define the properties of a volume data set to be read from disk.
70  Sorry, no \ref detailedDocumentation() available yet.
71 
72  <b>\#include</b> <<a href="imageinfo_8hxx-source.html">vigra/multi_impex.hxx</a>><br>
73  Namespace: vigra
74 **/
76 {
77  public:
78  typedef ImageImportInfo::PixelType PixelType;
79 
80  /// type of volume size returned by shape()
82 
83  /// provided for backwards-compatibility (deprecated)
85 
86  /// 3D resolution type returned by resolution()
88 
89  VIGRA_EXPORT VolumeImportInfo(const std::string &filename);
90  VIGRA_EXPORT VolumeImportInfo(const std::string &baseName, const std::string &extension);
91 
92  VIGRA_EXPORT ShapeType shape() const;
93 
94  /** Get width of the volume.
95  **/
96  VIGRA_EXPORT MultiArrayIndex width() const;
97 
98  /** Get height of the volume.
99  **/
100  VIGRA_EXPORT MultiArrayIndex height() const;
101 
102  /** Get depth of the volume.
103  **/
104  VIGRA_EXPORT MultiArrayIndex depth() const;
105 
106  /**
107  * resolution() contains the alignment and resolution of the
108  * volume. resolution()[0] is the x increment in a left-handed
109  * world coordinate system of one unstrided step in the volume
110  * memory. The [1] and [2] elements contain the y resp. z
111  * increments of the strided row resp. slice steps in the
112  * volume.
113  *
114  * EXAMPLES: (1.f, 1.f, 4.f) means that the slices are four
115  * times thicker than the x/y resolution.
116  * (1.f, -1.f, 1.f) means that the volume coordinate system is
117  * right-handed.
118  */
119  VIGRA_EXPORT Resolution resolution() const;
120 
121  /** Query the pixel type of the image.
122 
123  Possible values are:
124  <DL>
125  <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
126  <DT>"INT16"<DD> 16-bit signed integer (short)
127  <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
128  <DT>"INT32"<DD> 32-bit signed integer (long)
129  <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
130  <DT>"FLOAT"<DD> 32-bit floating point (float)
131  <DT>"DOUBLE"<DD> 64-bit floating point (double)
132  </DL>
133  **/
134  VIGRA_EXPORT const char * getPixelType() const;
135 
136  /** Query the pixel type of the image.
137 
138  Same as getPixelType(), but the result is returned as a
139  ImageImportInfo::PixelType enum. This is useful to implement
140  a switch() on the pixel type.
141 
142  Possible values are:
143  <DL>
144  <DT>UINT8<DD> 8-bit unsigned integer (unsigned char)
145  <DT>INT16<DD> 16-bit signed integer (short)
146  <DT>UINT16<DD> 16-bit unsigned integer (unsigned short)
147  <DT>INT32<DD> 32-bit signed integer (long)
148  <DT>UINT32<DD> 32-bit unsigned integer (unsigned long)
149  <DT>FLOAT<DD> 32-bit floating point (float)
150  <DT>DOUBLE<DD> 64-bit floating point (double)
151  </DL>
152  **/
153  VIGRA_EXPORT PixelType pixelType() const;
154 
155  VIGRA_EXPORT MultiArrayIndex numBands() const;
156  VIGRA_EXPORT bool isGrayscale() const;
157  VIGRA_EXPORT bool isColor() const;
158 
159  // get base file name without path, image index, and extension
160  VIGRA_EXPORT const std::string &name() const;
161 
162  VIGRA_EXPORT const std::string &description() const;
163 
164  template <class T, class Stride>
165  void importImpl(MultiArrayView <3, T, Stride> &volume) const;
166 
167  protected:
168  void getVolumeInfoFromFirstSlice(const std::string &filename);
169 
170  size_type shape_;
171  Resolution resolution_;
172  //PixelType pixelType_;
173  int numBands_;
174 
175  std::string path_, name_, description_, pixelType_;
176 
177  std::string rawFilename_;
178  std::string baseName_, extension_;
179  std::vector<std::string> numbers_;
180 };
181 
182 /********************************************************/
183 /* */
184 /* VolumeExportInfo */
185 /* */
186 /********************************************************/
187 
188 /** \brief Argument object for the function exportVolume().
189 
190  See \ref exportVolume() for usage example. This object must be used
191  to define the properties of a volume to be written to disk.
192 
193  <b>\#include</b> <<a href="imageinfo_8hxx-source.html">vigra/imageinfo.hxx</a>><br>
194  Namespace: vigra
195 **/
197 {
198  public:
199  /** Construct VolumeExportInfo object.
200 
201  The volume will be stored in a by-slice manner, where the number of slices
202  equals the depth of the volume. The file names will be enumerated like
203  <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.
204  (the actual number of zeros depends on the depth). If the target image type
205  does not support the source voxel type, all slices will be mapped
206  simultaneously to the appropriate target range.
207  The file type will be guessed from the extension unless overridden
208  by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
209  '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
210  '.tif', '.tiff', '.xv', '.hdr'.
211  JPEG support requires libjpeg, PNG support requires libpng, and
212  TIFF support requires libtiff.
213  **/
214  VIGRA_EXPORT VolumeExportInfo( const char * name_base, const char * name_ext );
215  VIGRA_EXPORT ~VolumeExportInfo();
216 
217  /** Set volume file name base.
218 
219  **/
220  VIGRA_EXPORT VolumeExportInfo & setFileNameBase(const char * name_base);
221  /** Set volume file name extension.
222 
223  The file type will be guessed from the extension unless overridden
224  by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
225  '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
226  '.tif', '.tiff', '.xv', '.hdr'.
227  JPEG support requires libjpeg, PNG support requires libpng, and
228  TIFF support requires libtiff.
229  **/
230  VIGRA_EXPORT VolumeExportInfo & setFileNameExt(const char * name_ext);
231  VIGRA_EXPORT const char * getFileNameBase() const;
232  VIGRA_EXPORT const char * getFileNameExt() const;
233 
234  /** Store volume as given file type.
235 
236  This will override any type guessed
237  from the file name's extension. Recognized file types:
238 
239  <DL>
240  <DT>"BMP"<DD> Microsoft Windows bitmap image file.
241  <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color.
242  <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format;
243  compressed 24-bit color (only available if libjpeg is installed).
244  <DT>"PNG"<DD> Portable Network Graphic
245  (only available if libpng is installed).
246  <DT>"PBM"<DD> Portable bitmap format (black and white).
247  <DT>"PGM"<DD> Portable graymap format (gray scale).
248  <DT>"PNM"<DD> Portable anymap.
249  <DT>"PPM"<DD> Portable pixmap format (color).
250  <DT>"SUN"<DD> SUN Rasterfile.
251  <DT>"TIFF"<DD> Tagged Image File Format.
252  (only available if libtiff is installed.)
253  <DT>"VIFF"<DD> Khoros Visualization image file.
254  </DL>
255 
256  With the exception of TIFF, VIFF, PNG, and PNM all file types store
257  1 byte (gray scale and mapped RGB) or 3 bytes (RGB) per
258  pixel.
259 
260  PNG can store UInt8 and UInt16 values, and supports 1 and 3 channel
261  images. One additional alpha channel is also supported.
262 
263  PNM can store 1 and 3 channel images with UInt8, UInt16 and UInt32
264  values in each channel.
265 
266  TIFF and VIFF are aditionally able to store short and long
267  integers (2 or 4 bytes) and real values (32 bit float and
268  64 bit double) without conversion. So you will need to use
269  TIFF or VIFF if you need to store images with high
270  accuracy (the appropriate type to write is automatically
271  derived from the image type to be exported). However, many
272  other programs using TIFF (e.g. ImageMagick) have not
273  implemented support for those pixel types. So don't be
274  surprised if the generated TIFF is not readable in some
275  cases. If this happens, export the image as 'unsigned
276  char' or 'RGBValue<unsigned char>' by calling
277  \ref ImageExportInfo::setPixelType().
278 
279  Support to reading and writing ICC color profiles is
280  provided for TIFF, JPEG, and PNG images.
281  **/
282  VIGRA_EXPORT VolumeExportInfo & setFileType( const char * );
283  VIGRA_EXPORT const char * getFileType() const;
284 
285  /** Set compression type.
286 
287  Recognized strings: "" (no compression), "LZW",
288  "RunLength", "1" ... "100". A number is interpreted as the
289  compression quality for JPEG compression. JPEG compression is
290  supported by the JPEG and TIFF formats. "LZW" is only available
291  if libtiff was installed with LZW enabled. By default, libtiff came
292  with LZW disabled due to Unisys patent enforcement. In this case,
293  VIGRA stores the image uncompressed.
294 
295  Valid Compression for TIFF files:
296  JPEG jpeg compression, call setQuality as well!
297  RLE runlength compression
298  LZW lzw compression
299  DEFLATE deflate compression
300  **/
301  VIGRA_EXPORT VolumeExportInfo & setCompression( const char * );
302  VIGRA_EXPORT const char * getCompression() const;
303 
304  /** Set the pixel type of the volume file(s). Possible values are:
305  <DL>
306  <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
307  <DT>"INT16"<DD> 16-bit signed integer (short)
308  <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
309  <DT>"INT32"<DD> 32-bit signed integer (long)
310  <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
311  <DT>"FLOAT"<DD> 32-bit floating point (float)
312  <DT>"DOUBLE"<DD> 64-bit floating point (double)
313  </DL>
314  **/
315  VIGRA_EXPORT VolumeExportInfo & setPixelType( const char * );
316 
317  /** Get the pixel type of the images in the volume. Possible values are:
318  <DL>
319  <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
320  <DT>"INT16"<DD> 16-bit signed integer (short)
321  <DT>"INT32"<DD> 32-bit signed integer (long)
322  <DT>"FLOAT"<DD> 32-bit floating point (float)
323  <DT>"DOUBLE"<DD> 64-bit floating point (double)
324  </DL>
325  **/
326  VIGRA_EXPORT const char * getPixelType() const;
327 
328  VIGRA_EXPORT VolumeExportInfo & setForcedRangeMapping(double fromMin, double fromMax,
329  double toMin, double toMax);
330  VIGRA_EXPORT bool hasForcedRangeMapping() const;
331  VIGRA_EXPORT double getFromMin() const;
332  VIGRA_EXPORT double getFromMax() const;
333  VIGRA_EXPORT double getToMin() const;
334  VIGRA_EXPORT double getToMax() const;
335 
336  /** Set the volume resolution in horizontal direction
337  **/
338  VIGRA_EXPORT VolumeExportInfo & setXResolution( float );
339  VIGRA_EXPORT float getXResolution() const;
340 
341  /** Set the image resolution in vertical direction
342  **/
343  VIGRA_EXPORT VolumeExportInfo & setYResolution( float );
344  VIGRA_EXPORT float getYResolution() const;
345 
346  /** Set the image resolution in depth direction
347  **/
348  VIGRA_EXPORT VolumeExportInfo & setZResolution( float );
349  VIGRA_EXPORT float getZResolution() const;
350 
351  /** Set the position of the upper Left corner on a global
352  canvas.
353 
354  Currently only supported by TIFF and PNG files.
355 
356  The offset is encoded in the XPosition and YPosition TIFF tags.
357 
358  @param pos position of the upper left corner in pixels
359  (must be >= 0)
360  **/
361  // FIXME: mhanselm: we might want to support 3D positions
362  VIGRA_EXPORT VolumeExportInfo & setPosition(const Diff2D & pos);
363 
364  /** Get the position of the upper left corner on
365  a global canvas.
366  **/
367  // FIXME: mhanselm: we might want to support 3D positions
368  VIGRA_EXPORT Diff2D getPosition() const;
369 
370  /**
371  ICC profiles (handled as raw data so far).
372  see getICCProfile()/setICCProfile()
373  **/
375 
376  /** Returns a reference to the ICC profile.
377  */
378  VIGRA_EXPORT const ICCProfile & getICCProfile() const;
379 
380  /** Sets the ICC profile.
381  ICC profiles are currently supported by TIFF, PNG and JPEG images.
382  (Otherwise, the profile data is silently ignored.)
383  **/
384  VIGRA_EXPORT VolumeExportInfo & setICCProfile(const ICCProfile & profile);
385 
386  private:
387  float m_x_res, m_y_res, m_z_res;
388 
389  std::string m_filetype, m_filename_base, m_filename_ext, m_pixeltype, m_comp;
390  Diff2D m_pos;
391  ICCProfile m_icc_profile;
392  double fromMin_, fromMax_, toMin_, toMax_;
393 };
394 
395 namespace detail {
396 
397 template <class DestIterator, class Shape, class T>
398 inline void
399 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<0>)
400 {
401  s.read((char*)buffer.begin(), shape[0]*sizeof(T));
402 
403  DestIterator dend = d + shape[0];
404  int k = 0;
405  for(; d < dend; ++d, k++)
406  {
407  *d = buffer[k];
408  }
409 }
410 
411 template <class DestIterator, class Shape, class T, int N>
412 void
413 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<N>)
414 {
415  DestIterator dend = d + shape[N];
416  for(; d < dend; ++d)
417  {
418  readVolumeImpl(d.begin(), shape, s, buffer, MetaInt<N-1>());
419  }
420 }
421 
422 } // namespace detail
423 
424 template <class T, class Stride>
425 void VolumeImportInfo::importImpl(MultiArrayView <3, T, Stride> &volume) const
426 {
427  vigra_precondition(this->shape() == volume.shape(), "importVolume(): Volume must be shaped according to VolumeImportInfo.");
428 
429  if(rawFilename_.size())
430  {
431  std::string dirName, baseName;
432  char oldCWD[2048];
433 
434 #ifdef _MSC_VER
435  if(_getcwd(oldCWD, 2048) == 0)
436  {
437  perror("getcwd");
438  vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
439  }
440  if(_chdir(path_.c_str()))
441  {
442  perror("chdir");
443  vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
444  }
445 #else
446  if(getcwd(oldCWD, 2048) == 0)
447  {
448  perror("getcwd");
449  vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
450  }
451  if(chdir(path_.c_str()))
452  {
453  perror("chdir");
454  vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
455  }
456 #endif
457 
458  std::ifstream s(rawFilename_.c_str(), std::ios::binary);
459  vigra_precondition(s.good(), "RAW file could not be opened");
460 
461  ArrayVector<T> buffer(shape_[0]);
462  detail::readVolumeImpl(volume.traverser_begin(), shape_, s, buffer, vigra::MetaInt<2>());
463 
464  //vigra_precondition(s.good(), "RAW file could not be opened");
465  //s.read((char*)volume.data(), shape_[0]*shape_[1]*shape_[2]*sizeof(T));
466 
467 #ifdef _MSC_VER
468  if(_chdir(oldCWD))
469  perror("chdir");
470 #else
471  if(chdir(oldCWD))
472  perror("chdir");
473 #endif
474 
475  vigra_postcondition(
476  volume.shape() == shape(), "imported volume has wrong size");
477  }
478  else
479  {
480  for (unsigned int i = 0; i < numbers_.size(); ++i)
481  {
482  // build the filename
483  std::string name = baseName_ + numbers_[i] + extension_;
484 
485  // import the image
486  ImageImportInfo info (name.c_str ());
487 
488  // generate a basic image view to the current layer
489  MultiArrayView <2, T, Stride> view (volume.bindOuter (i));
490  vigra_precondition(view.shape() == info.shape(),
491  "importVolume(): the images have inconsistent sizes.");
492 
493  importImage (info, destImage(view));
494  }
495  }
496 }
497 
498 
499 VIGRA_EXPORT void findImageSequence(const std::string &name_base,
500  const std::string &name_ext,
501  std::vector<std::string> & numbers);
502 
503 /********************************************************/
504 /* */
505 /* importVolume */
506 /* */
507 /********************************************************/
508 
509 /** \brief Function for importing a 3D volume.
510 
511  The data are expected to be stored in a by-slice manner,
512  where the slices are enumerated from <tt>name_base+"[0-9]+"+name_ext</tt>.
513  <tt>name_base</tt> may contain a path. All slice files with the same name base and
514  extension are considered part of the same volume. Slice numbers must be non-negative,
515  but can otherwise start anywhere and need not be successive. Slices will be read
516  in ascending numerical (not lexicographic) order. All slices must have the
517  same size. The <tt>volume</tt> will be reshaped to match the count and
518  size of the slices found.
519 
520  <b>\#include</b>
521  <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
522 
523  Namespace: vigra
524 */
525 template <class T, class Allocator>
527  const std::string &name_base,
528  const std::string &name_ext)
529 {
530  VolumeImportInfo info(name_base, name_ext);
531  volume.reshape(info.shape());
532 
533  info.importImpl(volume);
534 }
535 
536 
537 /** \brief Function for importing a 3D volume.
538 
539  The data can be given in two ways:
540 
541  <UL>
542  <LI> If the volume is stored in a by-slice manner (e.g. one image per slice),
543  the <tt>filename</tt> can refer to an arbitrary image from the set. <tt>importVolume()</tt>
544  then assumes that the slices are enumerated like <tt>name_base+"[0-9]+"+name_ext</tt>,
545  where <tt>name_base</tt>, the index, and <tt>name_ext</tt> are determined automatically.
546  All slice files with the same name base and extension are considered part of the same
547  volume. Slice numbers must be non-negative, but can otherwise start anywhere and need
548  not be successive. Slices will be read in ascending numerical (not lexicographic) order.
549  All slices must have the same size.
550  <li> Otherwise, <tt>importVolume()</tt> will try to read <tt>filename</tt> as an
551  info text file with the following key-value pairs:
552  <UL>
553  <LI> name = [short descriptive name of the volume] (optional)
554  <LI> filename = [absolute or relative path to raw voxel data file] (required)
555  <li> gradfile = [absolute or relative path to gradient data file] (currently ignored)
556  <li> description = [arbitrary description of the data set] (optional)
557  <li> width = [positive integer] (required)
558  <li> height = [positive integer] (required)
559  <li> depth = [positive integer] (required)
560  <li> datatype = [UNSIGNED_CHAR | UNSIGNED_BYTE] (default: UNSIGNED_CHAR)
561  </UL>
562  The voxel type is currently assumed to be binary compatible to the <tt>value_type T</TT>
563  of the <tt>MuliArray</tt>. Lines starting with "#" are ignored.
564  </UL>
565 
566  In either case, the <tt>volume</tt> will be reshaped to match the count and
567  size of the slices found.
568 
569  <b>\#include</b>
570  <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
571 
572  Namespace: vigra
573 */
574 template <class T, class Allocator>
576  const std::string &filename)
577 {
578  VolumeImportInfo info(filename);
579  volume.reshape(info.shape());
580 
581  info.importImpl(volume);
582 }
583 
584 /** \brief Function for importing a 3D volume.
585 
586  Read the volume data set <tt>info</tt> refers to. Explicit construction
587  of the info object allows to allocate a <tt>volume</tt> object type whose
588  <tt>value_type</tt> matches the voxel type of the stored data.
589  The <tt>volume</tt> will be reshaped to match the count and
590  size of the slices found.
591 
592  <b>\#include</b>
593  <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
594 
595  Namespace: vigra
596 */
597 template <class T, class Stride>
599 {
600  info.importImpl(volume);
601 }
602 
603 namespace detail {
604 
605 template <class T>
606 void setRangeMapping(std::string const & pixeltype,
607  FindMinMax<T> const & minmax, ImageExportInfo & info)
608 {
609  if(pixeltype == "UINT8")
610  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
611  (double)NumericTraits<UInt8>::min(),
612  (double)NumericTraits<UInt8>::max());
613  else if(pixeltype == "INT16")
614  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
615  (double)NumericTraits<Int16>::min(),
616  (double)NumericTraits<Int16>::max());
617  else if(pixeltype == "UINT16")
618  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
619  (double)NumericTraits<UInt16>::min(),
620  (double)NumericTraits<UInt16>::max());
621  else if(pixeltype == "INT32")
622  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
623  (double)NumericTraits<Int32>::min(),
624  (double)NumericTraits<Int32>::max());
625  else if(pixeltype == "UINT32")
626  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
627  (double)NumericTraits<UInt32>::min(),
628  (double)NumericTraits<UInt32>::max());
629  else if(pixeltype == "FLOAT")
630  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
631  else if(pixeltype == "DOUBLE")
632  info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
633 }
634 
635 template <class T, class Tag>
636 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
637  ImageExportInfo & info, VigraTrueType /* isScalar */)
638 {
639  std::string pixeltype = info.getPixelType();
640  bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
641  TypeAsString<T>::result(), pixeltype);
642 
643  if(downcast)
644  {
645  FindMinMax<T> minmax;
646  inspectMultiArray(srcMultiArrayRange(volume), minmax);
647  setRangeMapping(pixeltype, minmax, info);
648  }
649 }
650 
651 template <class T, class Tag>
652 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
653  ImageExportInfo & info, VigraFalseType /* isScalar */)
654 {
655  typedef typename T::value_type SrcComponent;
656  std::string pixeltype = info.getPixelType();
657  bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
658  TypeAsString<SrcComponent>::result(), pixeltype);
659 
660  if(downcast)
661  {
662  unsigned int bands = volume(0,0,0).size();
663  FindMinMax<SrcComponent> minmax;
664  for(unsigned int i=0; i<bands; ++i)
665  {
666  VectorComponentValueAccessor<T> band(i);
667  inspectMultiArray(srcMultiArrayRange(volume, band), minmax );
668  }
669  setRangeMapping(pixeltype, minmax, info);
670  }
671 }
672 
673 } // namespace detail
674 
675 /********************************************************/
676 /* */
677 /* exportVolume */
678 /* */
679 /********************************************************/
680 
681 /** \brief Function for exporting a 3D volume.
682 
683  The volume is exported in a by-slice manner, where the number of slices equals
684  the depth of the volume. The file names will be enumerated like
685  <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.
686  (the actual number of zeros depends on the depth). If the target image type
687  does not support the source voxel type, all slices will be mapped simultaneously
688  to the appropriate target range.
689 
690  <b>\#include</b>
691  <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>>
692 
693  Namespace: vigra
694 */
695 template <class T, class Tag>
697  const VolumeExportInfo & volinfo)
698 {
699  std::string name = std::string(volinfo.getFileNameBase()) + std::string(volinfo.getFileNameExt());
700  ImageExportInfo info(name.c_str());
701  info.setCompression(volinfo.getCompression());
702  info.setPixelType(volinfo.getPixelType());
703  detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScalar());
704 
705  const unsigned int depth = volume.shape (2);
706  int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth)));
707  for (unsigned int i = 0; i < depth; ++i)
708  {
709 
710  // build the filename
711  std::stringstream stream;
712  stream << std::setfill ('0') << std::setw (numlen) << i;
713  std::string name_num;
714  stream >> name_num;
715  std::string name = std::string(volinfo.getFileNameBase()) + name_num + std::string(volinfo.getFileNameExt());
716 
717  MultiArrayView <2, T, Tag> view (volume.bindOuter (i));
718 
719  // export the image
720  info.setFileName(name.c_str ());
721  exportImage(srcImageRange(view), info);
722  }
723 }
724 
725 // for backward compatibility
726 template <class T, class Tag>
727 inline
728 void exportVolume (MultiArrayView <3, T, Tag> const & volume,
729  const std::string &name_base,
730  const std::string &name_ext)
731 {
732  VolumeExportInfo volinfo(name_base.c_str(), name_ext.c_str());
733  exportVolume(volume, volinfo);
734 }
735 
736 //@}
737 
738 } // namespace vigra
739 
740 #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 (Thu Jun 14 2012)