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

vigra/impex.hxx VIGRA

Go to the documentation of this file.

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 2001-2002 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 /* Modifications by Pablo d'Angelo
00036  * updated to vigra 1.4 by Douglas Wilkins
00037  * as of 18 February 2006:
00038  *  - Added import/export of UINT16 and UINT32 image types.
00039  * Modifications by Andrew Mihal
00040  * updated to vigra 1.4 by Douglas Wilkins
00041  * as of 18 February 2006:
00042  *  - Moved some RowIterator declarations around to avoid using default ctors
00043  *    (cachedfileimages do not have default ctors for row iterators).
00044  *  - Added some case-specific optimizations
00045  */
00046 
00047 /*!
00048   \file  impex.hxx
00049   \brief image import and export functions
00050 
00051   this file provides the declarations and implementations of importImage()
00052   and exportImage(). the matching implementation for the given datatype is
00053   selected by template metacode.
00054 */
00055 
00056 #ifndef VIGRA_IMPEX_HXX
00057 #define VIGRA_IMPEX_HXX
00058 
00059 #include "sized_int.hxx"
00060 #include "stdimage.hxx"
00061 #include "tinyvector.hxx"
00062 #include "imageinfo.hxx"
00063 #include "numerictraits.hxx"
00064 #include "codec.hxx"
00065 #include "accessor.hxx"
00066 #include "inspectimage.hxx"
00067 #include "transformimage.hxx"
00068 #include "copyimage.hxx"
00069 #include "multi_array.hxx"
00070 #include <typeinfo>
00071 #include <iostream>
00072 
00073 // TODO
00074 // next refactoring: pluggable conversion algorithms
00075 
00076 namespace vigra
00077 {
00078 /** \addtogroup VigraImpex
00079 **/
00080 //@{
00081 
00082     /*!
00083       \brief used for reading bands after the source data type has been figured out.
00084 
00085         <b>\#include</b> <vigra/impex.hxx><br>
00086         Namespace: vigra
00087 
00088         <b> Declaration:</b>
00089 
00090         \code
00091         namespace vigra {
00092             template< class ImageIterator, class Accessor, class SrcValueType >
00093             void read_bands( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
00094         }
00095         \endcode
00096 
00097       \param dec decoder object through which the source data will be accessed
00098       \param ys  image iterator referencing the upper left pixel of the destination image
00099       \param a   image accessor for the destination image
00100     */
00101     template< class ImageIterator, class Accessor, class SrcValueType >
00102     void read_bands( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
00103     {
00104         
00105         typedef unsigned int size_type;
00106         typedef typename ImageIterator::row_iterator DstRowIterator;
00107         typedef typename Accessor::value_type  AccessorValueType;
00108         typedef typename AccessorValueType::value_type DstValueType;
00109 
00110         const size_type width = dec->getWidth();
00111         const size_type height = dec->getHeight();
00112         const size_type num_bands = dec->getNumBands();
00113 
00114         vigra_precondition(num_bands == (size_type)a.size(ys),
00115             "importImage(): number of bands (color channels) in file and destination image differ.");
00116 
00117         SrcValueType const * scanline;
00118         // MIHAL no default constructor available for cachedfileimages.
00119         DstRowIterator xs = ys.rowIterator();
00120 
00121         // iterate
00122         if (num_bands == 4) 
00123         {
00124             // Speedup for this particular case
00125             unsigned int offset = dec->getOffset();
00126             SrcValueType const * scanline0;
00127             SrcValueType const * scanline1;
00128             SrcValueType const * scanline2;
00129             SrcValueType const * scanline3;
00130             for( size_type y = 0; y < height; ++y, ++ys.y ) 
00131             {
00132                 dec->nextScanline();
00133                 xs = ys.rowIterator();
00134                 scanline0 = static_cast< SrcValueType const * >
00135                     (dec->currentScanlineOfBand(0));
00136                 scanline1 = static_cast< SrcValueType const * >
00137                     (dec->currentScanlineOfBand(1));
00138                 scanline2 = static_cast< SrcValueType const * >
00139                     (dec->currentScanlineOfBand(2));
00140                 scanline3 = static_cast< SrcValueType const * >
00141                     (dec->currentScanlineOfBand(3));
00142                 for( size_type x = 0; x < width; ++x, ++xs ) 
00143                 {
00144                     a.setComponent( *scanline0, xs, 0);
00145                     a.setComponent( *scanline1, xs, 1);
00146                     a.setComponent( *scanline2, xs, 2);
00147                     a.setComponent( *scanline3, xs, 3);
00148                     scanline0 += offset;
00149                     scanline1 += offset;
00150                     scanline2 += offset;
00151                     scanline3 += offset;
00152                 }
00153             }
00154         }
00155         else 
00156         {
00157             // General case
00158             for( size_type y = 0; y < height; ++y, ++ys.y ) 
00159             {
00160                 dec->nextScanline();
00161                 for( size_type b = 0; b < num_bands; ++b ) 
00162                 {
00163                     xs = ys.rowIterator();
00164                     scanline = static_cast< SrcValueType const * >
00165                         (dec->currentScanlineOfBand(b));
00166                     for( size_type x = 0; x < width; ++x, ++xs ) 
00167                     {
00168                         a.setComponent( *scanline, xs, b );
00169                         scanline += dec->getOffset();
00170                     }
00171                 }
00172             }
00173         }
00174     } // read_bands()
00175 
00176     
00177     // specialization for speed-up (the standard version would also work, 
00178     // but causes a stupid gcc waring)
00179     template< class ImageIterator, class RGBType, 
00180               class SrcValueType >
00181     void read_bands( Decoder * dec, ImageIterator ys, 
00182                      RGBAccessor<RGBType> a, SrcValueType )
00183     {
00184         typedef unsigned int size_type;
00185         typedef typename ImageIterator::row_iterator DstRowIterator;
00186         typedef RGBType  AccessorValueType;
00187         typedef typename AccessorValueType::value_type DstValueType;
00188 
00189         const size_type width = dec->getWidth();
00190         const size_type height = dec->getHeight();
00191         const size_type num_bands = dec->getNumBands();
00192 
00193         vigra_precondition(num_bands == (size_type)a.size(ys),
00194            "importImage(): number of bands (color channels) in file and destination image differ.");
00195 
00196         // MIHAL no default constructor available for cachedfileimages.
00197         DstRowIterator xs = ys.rowIterator();
00198 
00199         // Speedup for this particular case
00200         unsigned int offset = dec->getOffset();
00201         SrcValueType const * scanline0;
00202         SrcValueType const * scanline1;
00203         SrcValueType const * scanline2;
00204         for( size_type y = 0; y < height; ++y, ++ys.y ) 
00205         {
00206             dec->nextScanline();
00207             xs = ys.rowIterator();
00208             scanline0 = static_cast< SrcValueType const * >
00209                 (dec->currentScanlineOfBand(0));
00210             scanline1 = static_cast< SrcValueType const * >
00211                 (dec->currentScanlineOfBand(1));
00212             scanline2 = static_cast< SrcValueType const * >
00213                 (dec->currentScanlineOfBand(2));
00214             for( size_type x = 0; x < width; ++x, ++xs ) 
00215             {
00216                 a.setComponent( *scanline0, xs, 0);
00217                 a.setComponent( *scanline1, xs, 1);
00218                 a.setComponent( *scanline2, xs, 2);
00219                 scanline0 += offset;
00220                 scanline1 += offset;
00221                 scanline2 += offset;
00222             }
00223         }
00224     } // read_bands()
00225 
00226     // specialization for speed-up (the standard version would also work, 
00227     // but causes a stupid gcc waring)
00228     template< class ImageIterator, class ComponentType, class SrcValueType >
00229     void read_bands( Decoder * dec, ImageIterator ys, 
00230                      VectorAccessor<TinyVector<ComponentType, 3> > a, SrcValueType )
00231     {
00232         typedef unsigned int size_type;
00233         typedef typename ImageIterator::row_iterator DstRowIterator;
00234         typedef TinyVector<ComponentType, 3>  AccessorValueType;
00235         typedef typename AccessorValueType::value_type DstValueType;
00236 
00237         const size_type width = dec->getWidth();
00238         const size_type height = dec->getHeight();
00239         const size_type num_bands = dec->getNumBands();
00240 
00241         vigra_precondition(num_bands == (size_type)a.size(ys),
00242            "importImage(): number of bands (color channels) in file and destination image differ.");
00243 
00244         // MIHAL no default constructor available for cachedfileimages.
00245         DstRowIterator xs = ys.rowIterator();
00246 
00247         // Speedup for this particular case
00248         unsigned int offset = dec->getOffset();
00249         SrcValueType const * scanline0;
00250         SrcValueType const * scanline1;
00251         SrcValueType const * scanline2;
00252         for( size_type y = 0; y < height; ++y, ++ys.y ) 
00253         {
00254             dec->nextScanline();
00255             xs = ys.rowIterator();
00256             scanline0 = static_cast< SrcValueType const * >
00257                 (dec->currentScanlineOfBand(0));
00258             scanline1 = static_cast< SrcValueType const * >
00259                 (dec->currentScanlineOfBand(1));
00260             scanline2 = static_cast< SrcValueType const * >
00261                 (dec->currentScanlineOfBand(2));
00262             for( size_type x = 0; x < width; ++x, ++xs ) 
00263             {
00264                 a.setComponent( *scanline0, xs, 0);
00265                 a.setComponent( *scanline1, xs, 1);
00266                 a.setComponent( *scanline2, xs, 2);
00267                 scanline0 += offset;
00268                 scanline1 += offset;
00269                 scanline2 += offset;
00270             }
00271         }
00272     } // read_bands()
00273 
00274 
00275     // specialization for speed-up (the standard version would also work, 
00276     // but causes a stupid gcc waring)
00277     template< class ImageIterator, class ComponentType, class SrcValueType >
00278     void read_bands( Decoder * dec, ImageIterator ys, 
00279                      VectorAccessor<TinyVector<ComponentType, 4> > a, SrcValueType )
00280     {
00281         typedef unsigned int size_type;
00282         typedef typename ImageIterator::row_iterator DstRowIterator;
00283         typedef TinyVector<ComponentType, 4>  AccessorValueType;
00284         typedef typename AccessorValueType::value_type DstValueType;
00285 
00286         const size_type width = dec->getWidth();
00287         const size_type height = dec->getHeight();
00288         const size_type num_bands = dec->getNumBands();
00289 
00290         vigra_precondition(num_bands == (size_type)a.size(ys),
00291            "importImage(): number of bands (color channels) in file and destination image differ.");
00292 
00293         // MIHAL no default constructor available for cachedfileimages.
00294         DstRowIterator xs = ys.rowIterator();
00295 
00296         // Speedup for this particular case
00297         unsigned int offset = dec->getOffset();
00298         SrcValueType const * scanline0;
00299         SrcValueType const * scanline1;
00300         SrcValueType const * scanline2;
00301         SrcValueType const * scanline3;
00302         for( size_type y = 0; y < height; ++y, ++ys.y ) 
00303         {
00304             dec->nextScanline();
00305             xs = ys.rowIterator();
00306             scanline0 = static_cast< SrcValueType const * >
00307                 (dec->currentScanlineOfBand(0));
00308             scanline1 = static_cast< SrcValueType const * >
00309                 (dec->currentScanlineOfBand(1));
00310             scanline2 = static_cast< SrcValueType const * >
00311                 (dec->currentScanlineOfBand(2));
00312             scanline3 = static_cast< SrcValueType const * >
00313                 (dec->currentScanlineOfBand(3));
00314             for( size_type x = 0; x < width; ++x, ++xs ) 
00315             {
00316                 a.setComponent( *scanline0, xs, 0);
00317                 a.setComponent( *scanline1, xs, 1);
00318                 a.setComponent( *scanline2, xs, 2);
00319                 a.setComponent( *scanline3, xs, 3);
00320                 scanline0 += offset;
00321                 scanline1 += offset;
00322                 scanline2 += offset;
00323                 scanline3 += offset;
00324             }
00325         }
00326     } // read_bands()
00327 
00328     /*!
00329       \brief used for reading bands after the source data type has been figured out.
00330 
00331         <b>\#include</b> <vigra/impex.hxx><br>
00332         Namespace: vigra
00333 
00334         <b> Declaration:</b>
00335 
00336         \code
00337         namespace vigra {
00338             template< class ImageIterator, class Accessor, class SrcValueType >
00339             void read_band( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
00340         }
00341         \endcode
00342 
00343       \param dec decoder object through which the source data will be accessed
00344       \param ys  image iterator referencing the upper left pixel of the destination image
00345       \param a   image accessor for the destination image
00346     */
00347     template< class ImageIterator, class Accessor, class SrcValueType >
00348     void read_band( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
00349     {
00350         typedef unsigned int size_type;
00351         typedef typename ImageIterator::row_iterator DstRowIterator;
00352         typedef typename Accessor::value_type DstValueType;
00353         const size_type width = dec->getWidth();
00354         const size_type height = dec->getHeight();
00355 
00356         SrcValueType const * scanline;
00357         // MIHAL no default constructor available for cachedfileimages.
00358         DstRowIterator xs = ys.rowIterator();
00359 
00360         for( size_type y = 0; y < height; ++y, ++ys.y ) {
00361             dec->nextScanline();
00362             xs = ys.rowIterator();
00363             scanline = static_cast< SrcValueType const * >(dec->currentScanlineOfBand(0));
00364             for( size_type x = 0; x < width; ++x, ++xs )
00365                 a.set( scanline[x], xs );
00366         }
00367     } // read_band()
00368 
00369     /*!
00370       \brief used for reading images of vector type, such as integer of float rgb.
00371 
00372         <b>\#include</b> <vigra/impex.hxx><br>
00373         Namespace: vigra
00374 
00375         <b> Declaration:</b>
00376 
00377         \code
00378         namespace vigra {
00379             template< class ImageIterator, class Accessor >
00380             void importVectorImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
00381         }
00382         \endcode
00383 
00384         <b> Parameters:</b>
00385 
00386         <DL>
00387         <DT>ImageIterator<DD> the image iterator type for the destination image
00388         <DT>Accessor<DD> the image accessor type for the destination image
00389         <DT>info<DD> user supplied image import information
00390         <DT>iter<DD> image iterator referencing the upper left pixel of the destination image
00391         <DT>a<DD> image accessor for the destination image
00392         </DL>
00393     */
00394 doxygen_overloaded_function(template <...> void importVectorImage)
00395 
00396     template< class ImageIterator, class Accessor >
00397     void importVectorImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
00398     {
00399         std::auto_ptr<Decoder> dec = decoder(info);
00400         std::string pixeltype = dec->getPixelType();
00401 
00402         if ( pixeltype == "UINT8" )
00403             read_bands( dec.get(), iter, a, (UInt8)0 );
00404         else if ( pixeltype == "INT16" )
00405             read_bands( dec.get(), iter, a, Int16() );
00406         else if ( pixeltype == "UINT16" )
00407             read_bands( dec.get(), iter, a, (UInt16)0 );
00408         else if ( pixeltype == "INT32" )
00409             read_bands( dec.get(), iter, a, Int32() );
00410         else if ( pixeltype == "UINT32" )
00411             read_bands( dec.get(), iter, a, (UInt32)0 );
00412         else if ( pixeltype == "FLOAT" )
00413             read_bands( dec.get(), iter, a, float() );
00414         else if ( pixeltype == "DOUBLE" )
00415             read_bands( dec.get(), iter, a, double() );
00416         else
00417             vigra_precondition( false, "invalid pixeltype" );
00418 
00419         // close the decoder
00420         dec->close();
00421     }
00422 
00423     /*!
00424       \brief used for reading images of  scalar type, such as integer and float grayscale.
00425 
00426         <b>\#include</b> <vigra/impex.hxx><br>
00427         Namespace: vigra
00428 
00429         <b> Declaration:</b>
00430 
00431         \code
00432         namespace vigra {
00433             template < class ImageIterator, class Accessor >
00434             void importScalarImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
00435         }
00436         \endcode
00437 
00438         <b> Parameters:</b>
00439 
00440         <DL>
00441         <DT>ImageIterator<DD> the image iterator type for the destination image
00442         <DT>Accessor<DD> the image accessor type for the destination image
00443         <DT>info<DD> user supplied image import information
00444         <DT>iter<DD> image iterator referencing the upper left pixel of the destination image
00445         <DT>a<DD> image accessor for the destination image
00446         </DL>
00447     */
00448 doxygen_overloaded_function(template <...> void importScalarImage)
00449 
00450     template < class ImageIterator, class Accessor >
00451     void importScalarImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
00452     {
00453         std::auto_ptr<Decoder> dec = decoder(info);
00454         std::string pixeltype = dec->getPixelType();
00455 
00456         if ( pixeltype == "UINT8" )
00457             read_band( dec.get(), iter, a, (UInt8)0 );
00458         else if ( pixeltype == "INT16" )
00459             read_band( dec.get(), iter, a, Int16() );
00460         else if ( pixeltype == "UINT16" )
00461             read_band( dec.get(), iter, a, (UInt16)0 );
00462         else if ( pixeltype == "INT32" )
00463             read_band( dec.get(), iter, a, Int32() );
00464         else if ( pixeltype == "UINT32" )
00465             read_band( dec.get(), iter, a, (UInt32)0 );
00466         else if ( pixeltype == "FLOAT" )
00467             read_band( dec.get(), iter, a, float() );
00468         else if ( pixeltype == "DOUBLE" )
00469             read_band( dec.get(), iter, a, double() );
00470         else
00471             vigra_precondition( false, "invalid pixeltype" );
00472 
00473         // close the decoder
00474         dec->close();
00475     }
00476 
00477 /********************************************************/
00478 /*                                                      */
00479 /*                     importImage                      */
00480 /*                                                      */
00481 /********************************************************/
00482 
00483     /** \brief Read the image specified by the given \ref vigra::ImageImportInfo object.
00484 
00485         <b> Declarations:</b>
00486 
00487         pass arguments explicitly:
00488         \code
00489         namespace vigra {
00490             template <class ImageIterator, class Accessor>
00491             void
00492             importImage(ImageImportInfo const & image, ImageIterator iter, Accessor a)
00493         }
00494         \endcode
00495 
00496         use argument objects in conjunction with \ref ArgumentObjectFactories :
00497         \code
00498         namespace vigra {
00499             template <class ImageIterator, class Accessor>
00500             inline void
00501             importImage(ImageImportInfo const & image, pair<ImageIterator, Accessor> dest)
00502         }
00503         \endcode
00504 
00505         <b> Usage:</b>
00506 
00507         <b>\#include</b> <vigra/impex.hxx><br>
00508         Namespace: vigra
00509 
00510         \code
00511 
00512         vigra::ImageImportInfo info("myimage.gif");
00513 
00514         if(info.isGrayscale())
00515         {
00516             // create byte image of appropriate size
00517             vigra::BImage in(info.width(), info.height());
00518 
00519             vigra::importImage(info, destImage(in)); // read the image
00520             ...
00521         }
00522         else
00523         {
00524             // create byte RGB image of appropriate size
00525             vigra::BRGBImage in(info.width(), info.height());
00526 
00527             vigra::importImage(info, destImage(in)); // read the image
00528             ...
00529         }
00530 
00531         \endcode
00532 
00533         <b> Preconditions:</b>
00534 
00535         <UL>
00536 
00537         <LI> the image file must be readable
00538         <LI> the file type must be one of
00539 
00540             <DL>
00541             <DT>"BMP"<DD> Microsoft Windows bitmap image file.
00542             <DT>"EXR"<DD> OpenEXR high dynamic range image format. 
00543             (only available if libopenexr is installed)
00544             <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color.
00545             <DT>"HDR"<DD> Radiance RGBE high dynamic range image format.
00546             <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format;
00547             compressed 24-bit color (only available if libjpeg is installed).
00548             <DT>"PNG"<DD> Portable Network Graphic
00549             (only available if libpng is installed).
00550             <DT>"PBM"<DD> Portable bitmap format (black and white).
00551             <DT>"PGM"<DD> Portable graymap format (gray scale).
00552             <DT>"PNM"<DD> Portable anymap.
00553             <DT>"PPM"<DD> Portable pixmap format (color).
00554             <DT>"SUN"<DD> SUN Rasterfile.
00555             <DT>"TIFF"<DD> Tagged Image File Format.
00556             (only available if libtiff is installed.)
00557             <DT>"VIFF"<DD> Khoros Visualization image file.
00558             </DL>
00559         </UL>
00560     **/
00561 doxygen_overloaded_function(template <...> void importImage)
00562 
00563     template < class ImageIterator, class Accessor >
00564     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
00565     {
00566         typedef typename NumericTraits<typename Accessor::value_type>::isScalar is_scalar;
00567         importImage( info, iter, a, is_scalar() );
00568     }
00569 
00570     template < class ImageIterator, class Accessor >
00571     void importImage( const ImageImportInfo & info, pair< ImageIterator, Accessor > dest )
00572     {
00573         importImage( info, dest.first, dest.second );
00574     }
00575 
00576     template < class ImageIterator, class Accessor >
00577     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraFalseType )
00578     {
00579         importVectorImage( info, iter, a );
00580     }
00581 
00582     template < class ImageIterator, class Accessor >
00583     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraTrueType )
00584     {
00585         importScalarImage( info, iter, a );
00586     }
00587 
00588     /*!
00589       \brief used for writing bands after the source data type has been figured out.
00590 
00591         <b>\#include</b> <vigra/impex.hxx><br>
00592         Namespace: vigra
00593 
00594         <b> Declaration:</b>
00595 
00596         \code
00597         namespace vigra {
00598             template< class ImageIterator, class Accessor, class DstValueType >
00599             void write_bands( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
00600         }
00601         \endcode
00602 
00603       \param enc encoder object through which the destination data will be accessed
00604       \param ul  image iterator referencing the upper left pixel of the source image
00605       \param lr  image iterator referencing the lower right pixel of the source image
00606       \param a   image accessor for the source image
00607     */
00608     template< class ImageIterator, class Accessor, class DstValueType >
00609     void write_bands( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType)
00610     {
00611         typedef unsigned int size_type;
00612         typedef typename ImageIterator::row_iterator SrcRowIterator;
00613         typedef typename Accessor::value_type  AccessorValueType;
00614         typedef typename AccessorValueType::value_type SrcValueType;
00615 
00616         // complete decoder settings
00617         const size_type width = lr.x - ul.x;
00618         const size_type height = lr.y - ul.y;
00619         enc->setWidth(width);
00620         enc->setHeight(height);
00621         const size_type num_bands = a.size(ul);
00622         enc->setNumBands(num_bands);
00623         enc->finalizeSettings();
00624 
00625         DstValueType * scanline;
00626 
00627         // iterate
00628         ImageIterator ys(ul);
00629         // MIHAL no default constructor available for cachedfileimages
00630         SrcRowIterator xs = ys.rowIterator();
00631 
00632             // Speedup for the common cases
00633         switch (num_bands) 
00634         {
00635           case 2:
00636           {
00637             unsigned int offset = enc->getOffset();
00638             DstValueType * scanline0;
00639             DstValueType * scanline1;
00640             for( size_type y = 0; y < height; ++y, ++ys.y ) {
00641                 xs = ys.rowIterator();
00642                 scanline0 = static_cast< DstValueType * >
00643                         (enc->currentScanlineOfBand(0));
00644                 scanline1 = static_cast< DstValueType * >
00645                         (enc->currentScanlineOfBand(1));
00646                 for( size_type x = 0; x < width; ++x, ++xs) {
00647                     *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
00648                     *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
00649                     scanline0 += offset;
00650                     scanline1 += offset;
00651                 }
00652                 enc->nextScanline();
00653                 
00654             }
00655             break;
00656           }
00657           case 3:
00658           {
00659             unsigned int offset = enc->getOffset();
00660             DstValueType * scanline0;
00661             DstValueType * scanline1;
00662             DstValueType * scanline2;
00663             for( size_type y = 0; y < height; ++y, ++ys.y ) {
00664                 xs = ys.rowIterator();
00665                 scanline0 = static_cast< DstValueType * >
00666                         (enc->currentScanlineOfBand(0));
00667                 scanline1 = static_cast< DstValueType * >
00668                         (enc->currentScanlineOfBand(1));
00669                 scanline2 = static_cast< DstValueType * >
00670                         (enc->currentScanlineOfBand(2));
00671                 for( size_type x = 0; x < width; ++x, ++xs) {
00672                     *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
00673                     *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
00674                     *scanline2 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 2));
00675                     scanline0 += offset;
00676                     scanline1 += offset;
00677                     scanline2 += offset;
00678                 }
00679                 enc->nextScanline();
00680             }
00681             break;
00682           }
00683           case 4:
00684           {
00685             unsigned int offset = enc->getOffset();
00686             DstValueType * scanline0;
00687             DstValueType * scanline1;
00688             DstValueType * scanline2;
00689             DstValueType * scanline3;
00690             for( size_type y = 0; y < height; ++y, ++ys.y ) {
00691                 xs = ys.rowIterator();
00692                 scanline0 = static_cast< DstValueType * >
00693                         (enc->currentScanlineOfBand(0));
00694                 scanline1 = static_cast< DstValueType * >
00695                         (enc->currentScanlineOfBand(1));
00696                 scanline2 = static_cast< DstValueType * >
00697                         (enc->currentScanlineOfBand(2));
00698                 scanline3 = static_cast< DstValueType * >
00699                         (enc->currentScanlineOfBand(3));
00700                 for( size_type x = 0; x < width; ++x, ++xs) {
00701                     *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
00702                     *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
00703                     *scanline2 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 2));
00704                     *scanline3 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 3));
00705                     scanline0 += offset;
00706                     scanline1 += offset;
00707                     scanline2 += offset;
00708                     scanline3 += offset;
00709                 }
00710                 enc->nextScanline();
00711             }
00712             break;
00713           }
00714           default:
00715           {
00716             // General case
00717             for( size_type y = 0; y < height; ++y, ++ys.y ) {
00718                 for( size_type b = 0; b < num_bands; ++b ) {
00719                     xs = ys.rowIterator();
00720                     scanline = static_cast< DstValueType * >
00721                         (enc->currentScanlineOfBand(b));
00722                     for( size_type x = 0; x < width; ++x, ++xs ) {
00723                         *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, b ));
00724                         scanline += enc->getOffset();
00725                     }
00726                 }
00727                 enc->nextScanline();
00728             }
00729           }
00730         }
00731     } // write_bands()
00732 
00733     template< class MArray, class DstValueType >
00734     void write_bands( Encoder * enc, MArray const & array, DstValueType)
00735     {
00736         typedef unsigned int size_type;
00737 
00738         // complete decoder settings
00739         const size_type width = array.shape(0);
00740         const size_type height = array.shape(1);
00741         enc->setWidth(width);
00742         enc->setHeight(height);
00743         const size_type num_bands = array.shape(2);
00744         enc->setNumBands(num_bands);
00745         enc->finalizeSettings();
00746 
00747         DstValueType * scanline;
00748 
00749         // iterate
00750         for( size_type y = 0; y < height; ++y ) {
00751             for( size_type b = 0; b < num_bands; ++b ) {
00752                 scanline = static_cast< DstValueType * >
00753                     (enc->currentScanlineOfBand(b));
00754                 for( size_type x = 0; x < width; ++x) {
00755                     *scanline = array(x, y, b);
00756                     scanline += enc->getOffset();
00757                 }
00758             }
00759             enc->nextScanline();
00760         }
00761     } // write_bands()
00762 
00763     /*!
00764       \brief used for writing bands after the source data type has been figured out.
00765 
00766         <b>\#include</b> <vigra/impex.hxx><br>
00767         Namespace: vigra
00768 
00769         <b> Declaration:</b>
00770 
00771         \code
00772         namespace vigra {
00773             template< class ImageIterator, class Accessor, class DstValueType >
00774             void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
00775         }
00776         \endcode
00777 
00778       \param enc encoder object through which the destination data will be accessed
00779       \param ul  image iterator referencing the upper left pixel of the source image
00780       \param lr  image iterator referencing the lower right pixel of the source image
00781       \param a   image accessor for the source image
00782     */
00783     template< class ImageIterator, class Accessor, class DstValueType >
00784     void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType)
00785     {
00786         typedef unsigned int size_type;
00787         typedef typename ImageIterator::row_iterator SrcRowIterator;
00788         typedef typename Accessor::value_type SrcValueType;
00789 
00790         // complete decoder settings
00791         const size_type width = size_type(lr.x - ul.x);
00792         const size_type height = size_type(lr.y - ul.y);
00793         enc->setWidth(width);
00794         enc->setHeight(height);
00795         enc->setNumBands(1);
00796         enc->finalizeSettings();
00797 
00798         DstValueType * scanline;
00799 
00800         // iterate
00801         ImageIterator ys(ul);
00802         // MIHAL no default constructor available for cachedfileimages.
00803         SrcRowIterator xs = ys.rowIterator();
00804         size_type y;
00805         for(  y = 0; y < height; ++y, ++ys.y ) {
00806             xs = ys.rowIterator();
00807             scanline = static_cast< DstValueType * >(enc->currentScanlineOfBand(0));
00808             for( size_type x = 0; x < width; ++x, ++xs, ++scanline )
00809                 *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a(xs));
00810             enc->nextScanline();
00811         }
00812     } // write_band()
00813 
00814 namespace detail {
00815 
00816     // export scalar images without conversion
00817     template < class SrcIterator, class SrcAccessor, class T >
00818     void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00819                            Encoder * enc, T zero)
00820     {
00821         write_band( enc, sul, slr, sget, zero );
00822     }
00823 
00824     // export scalar images with conversion 
00825     template < class SrcIterator, class SrcAccessor, class T >
00826     void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00827                            Encoder * enc, 
00828                            const ImageExportInfo & info, 
00829                            T zero)
00830     {
00831         double fromMin, fromMax, toMin, toMax;
00832         if(info.getFromMin() < info.getFromMax())
00833         {
00834             fromMin = info.getFromMin();
00835             fromMax = info.getFromMax();
00836         }
00837         else
00838         {
00839             typedef typename SrcAccessor::value_type SrcValue;
00840             FindMinMax<SrcValue> minmax;
00841             inspectImage( sul, slr, sget, minmax );
00842             
00843             fromMin = (double)minmax.min;
00844             fromMax = (double)minmax.max;
00845             if(fromMax <= fromMin)
00846                 fromMax = fromMin + 1.0;
00847        }
00848         
00849         if(info.getToMin() < info.getToMax())
00850         {
00851             toMin = info.getToMin();
00852             toMax = info.getToMax();
00853         }
00854         else
00855         {
00856             toMin = (double)NumericTraits<T>::min();
00857             toMax = (double)NumericTraits<T>::max();
00858         }
00859         
00860         double scale = (toMax - toMin) / (fromMax - fromMin);
00861         double offset = (toMin / scale) - fromMin;
00862         BasicImage<T> image(slr-sul);
00863         transformImage( sul, slr, sget, image.upperLeft(), image.accessor(), 
00864                         linearIntensityTransform(scale, offset));
00865         write_band( enc, image.upperLeft(),
00866                     image.lowerRight(), image.accessor(), zero );
00867     }
00868 
00869     // export vector images without conversion
00870     template < class SrcIterator, class SrcAccessor, class T >
00871     void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00872                            Encoder * enc, T zero)
00873     {
00874         int bands = sget.size(sul);
00875         vigra_precondition(isBandNumberSupported(enc->getFileType(), bands),
00876            "exportImage(): file format does not support requested number of bands (color channels)");
00877         write_bands( enc, sul, slr, sget, zero );
00878     }
00879     
00880     // export vector images with conversion
00881     template < class SrcIterator, class SrcAccessor, class T >
00882     void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00883                            Encoder * enc, 
00884                            const ImageExportInfo & info, 
00885                            T zero)
00886     {
00887         unsigned int bands = sget.size(sul);
00888         vigra_precondition(isBandNumberSupported(enc->getFileType(), bands),
00889            "exportImage(): file format does not support requested number of bands (color channels)");
00890 
00891         typedef typename SrcAccessor::ElementAccessor SrcElementAccessor;
00892         typedef typename SrcElementAccessor::value_type SrcComponent;
00893         double fromMin, fromMax, toMin, toMax;
00894         if(info.getFromMin() < info.getFromMax())
00895         {
00896             fromMin = info.getFromMin();
00897             fromMax = info.getFromMax();
00898         }
00899         else
00900         {
00901             FindMinMax<SrcComponent> minmax;
00902             for(unsigned int i=0; i<bands; ++i)
00903             {
00904                 SrcElementAccessor band(i, sget);
00905                 inspectImage( sul, slr, band, minmax );
00906             }
00907 
00908             fromMin = (double)minmax.min;
00909             fromMax = (double)minmax.max;
00910             if(fromMax <= fromMin)
00911                 fromMax = fromMin + 1.0;
00912         }
00913         
00914         if(info.getToMin() < info.getToMax())
00915         {
00916             toMin = info.getToMin();
00917             toMax = info.getToMax();
00918         }
00919         else
00920         {
00921             toMin = (double)NumericTraits<T>::min();
00922             toMax = (double)NumericTraits<T>::max();
00923         }
00924 
00925         double scale = (toMax - toMin) / (fromMax - fromMin);
00926         double offset = (toMin / scale) - fromMin;
00927         int w = slr.x - sul.x;
00928         int h = slr.y - sul.y;
00929 
00930         typedef vigra::MultiArray<3, T> MArray;
00931         MArray array(typename MArray::difference_type(w, h, bands));
00932 
00933         for(unsigned int i=0; i<bands; ++i)
00934         {
00935             BasicImageView<T> subImage = makeBasicImageView(array.bindOuter(i));
00936             SrcElementAccessor band(i, sget);
00937             transformImage( sul, slr, band, subImage.upperLeft(), subImage.accessor(),
00938                             linearIntensityTransform( scale, offset ) );
00939         }
00940         write_bands( enc, array, zero );
00941     }
00942 
00943 } // namespace detail
00944 
00945 
00946     /*!
00947       \brief Deprecated.
00948 
00949         Use \ref exportImage() instead.
00950 
00951         <b> Declaration:</b>
00952 
00953         \code
00954         namespace vigra {
00955             template < class SrcIterator, class SrcAccessor >
00956             void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00957                                             const ImageExportInfo & info )
00958         }
00959         \endcode
00960     */
00961 doxygen_overloaded_function(template <...> void exportFloatingVectorImage)
00962 
00963     template < class SrcIterator, class SrcAccessor >
00964     void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00965                                     const ImageExportInfo & info )
00966     {
00967         exportImage(sul, slr, sget, info);
00968     }
00969 
00970     /*!
00971       \brief Deprecated.
00972 
00973         Use \ref exportImage() instead.
00974 
00975         <b> Declaration:</b>
00976 
00977         \code
00978         namespace vigra {
00979             template < class SrcIterator, class SrcAccessor >
00980             void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00981                                             const ImageExportInfo & info )
00982         }
00983         \endcode
00984     */
00985 doxygen_overloaded_function(template <...> void exportIntegralVectorImage)
00986 
00987     template < class SrcIterator, class SrcAccessor >
00988     void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
00989                                     const ImageExportInfo & info )
00990     {
00991         exportImage(sul, slr, sget, info);
00992     }
00993 
00994     /*!
00995       \brief Deprecated.
00996 
00997         Use \ref exportImage() instead.
00998 
00999         <b> Declaration:</b>
01000 
01001         \code
01002         namespace vigra {
01003             template < class SrcIterator, class SrcAccessor >
01004             void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01005                                             const ImageExportInfo & info )
01006         }
01007         \endcode
01008     */
01009 doxygen_overloaded_function(template <...> void exportFloatingScalarImage)
01010 
01011     template < class SrcIterator, class SrcAccessor >
01012     void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01013                                     const ImageExportInfo & info )
01014     {
01015         exportImage(sul, slr, sget, info);
01016     }
01017 
01018     /*!
01019       \brief Deprecated.
01020 
01021         Use \ref exportImage() instead.
01022 
01023         <b> Declaration:</b>
01024 
01025         \code
01026         namespace vigra {
01027             template < class SrcIterator, class SrcAccessor >
01028             void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01029                                             const ImageExportInfo & info )
01030         }
01031         \endcode
01032     */
01033 doxygen_overloaded_function(template <...> void exportIntegralScalarImage)
01034 
01035     template < class SrcIterator, class SrcAccessor >
01036     void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01037                                     const ImageExportInfo & info )
01038     {
01039         exportImage(sul, slr, sget, info);
01040     }
01041 
01042 /********************************************************/
01043 /*                                                      */
01044 /*                     exportImage                      */
01045 /*                                                      */
01046 /********************************************************/
01047 
01048 /** \brief Write an image, given an \ref vigra::ImageExportInfo object.
01049 
01050     If the file format to be exported to supports the pixel type of the
01051     source image, the pixel type will be kept (e.g. <tt>float</tt>
01052     can be stored as TIFF without conversion, in contrast to most other
01053     image export toolkits). Otherwise, the pixel values are transformed
01054     to the range 0.255 and converted to <tt>unsigned char</tt>. Currently,
01055     the following file formats are supported. The pixel types given in
01056     brackets are those that are written without conversion:
01057 
01058     <DL>
01059     <DT>"BMP"<DD> Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB).
01060     <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color (pixel types: UINT8 as gray and RGB).
01061     <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format; compressed 24-bit color
01062                   (pixel types: UINT8 as gray and RGB). (only available if libjpeg is installed)
01063     <DT>"PNG"<DD> Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels).
01064                   (only available if libpng is installed)
01065     <DT>"PBM"<DD> Portable bitmap format (black and white).
01066     <DT>"PGM"<DD> Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale)).
01067     <DT>"PNM"<DD> Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB).
01068     <DT>"PPM"<DD> Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB).
01069     <DT>"SUN"<DD> SUN Rasterfile (pixel types: UINT8 as gray and RGB).
01070     <DT>"TIFF"<DD> Tagged Image File Format
01071                 (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels).
01072                 (only available if libtiff is installed.)
01073     <DT>"VIFF"<DD> Khoros Visualization image file
01074         (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels).
01075     </DL>
01076 
01077     <b> Declarations:</b>
01078 
01079     pass arguments explicitly:
01080     \code
01081     namespace vigra {
01082         template <class SrcIterator, class SrcAccessor>
01083         void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01084                          ImageExportInfo const & info)
01085     }
01086     \endcode
01087 
01088 
01089     use argument objects in conjunction with \ref ArgumentObjectFactories :
01090     \code
01091     namespace vigra {
01092         template <class SrcIterator, class SrcAccessor>
01093         void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01094                          ImageExportInfo const & info)
01095     }
01096     \endcode
01097 
01098     <b> Usage:</b>
01099 
01100     <b>\#include</b> <vigra/impex.hxx><br>
01101     Namespace: vigra
01102 
01103     \code
01104 
01105 
01106     vigra::BRGBImage out(w, h);
01107     ...
01108 
01109     // write as JPEG image, using compression quality 80
01110     vigra::exportImage(srcImageRange(out),
01111                       vigra::ImageExportInfo("myimage.jpg").setCompression("80"));
01112 
01113 
01114     // force it to a particular pixel type (the pixel type must be supported by the
01115     // desired image file format, otherwise an \ref vigra::PreconditionViolation exception will be thrown)
01116     vigra::exportImage(srcImageRange(out),
01117                       vigra::ImageExportInfo("myINT16image.tif").setPixelType("INT16"));
01118     \endcode
01119 
01120     <b> Preconditions:</b>
01121 
01122     <UL>
01123 
01124     <LI> the image file must be writable.
01125     <LI> the file type must be one of the supported file types.
01126 
01127 
01128     </UL>
01129 **/
01130 doxygen_overloaded_function(template <...> void exportImage)
01131 
01132     template < class SrcIterator, class SrcAccessor >
01133     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01134                       const ImageExportInfo & info )
01135     {
01136         typedef typename NumericTraits<typename SrcAccessor::value_type>::isScalar is_scalar;
01137 
01138         try
01139         {
01140             exportImage( sul, slr, sget, info, is_scalar() );
01141         }
01142         catch(Encoder::TIFFCompressionException &)
01143         {
01144             const_cast<ImageExportInfo &>(info).setCompression("");
01145             exportImage( sul, slr, sget, info, is_scalar() );
01146         }
01147     }
01148 
01149     template < class SrcIterator, class SrcAccessor >
01150     inline
01151     void exportImage( triple<SrcIterator, SrcIterator, SrcAccessor> src,
01152                       const ImageExportInfo & info )
01153     {
01154         exportImage( src.first, src.second, src.third, info );
01155     }
01156 
01157     template < class SrcIterator, class SrcAccessor >
01158     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01159                       const ImageExportInfo & info, VigraFalseType /*not scalar */)
01160     {
01161         typedef typename SrcAccessor::value_type AccessorValueType;
01162         typedef typename AccessorValueType::value_type SrcValueType;
01163         std::string pixeltype = info.getPixelType();
01164         std::auto_ptr<Encoder> enc = encoder(info);
01165         bool downcast = negotiatePixelType(enc->getFileType(),
01166                         TypeAsString<SrcValueType>::result(), pixeltype);
01167         enc->setPixelType(pixeltype);
01168         if(downcast || info.hasForcedRangeMapping())
01169         {
01170             if(pixeltype == "UINT8")
01171                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (UInt8)0);
01172             else if(pixeltype == "INT16")
01173                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, Int16());
01174             else if(pixeltype == "UINT16")
01175                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (UInt16)0);
01176             else if(pixeltype == "INT32")
01177                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, Int32());
01178             else if(pixeltype == "UINT32")
01179                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (UInt32)0);
01180             else if(pixeltype == "FLOAT")
01181                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, float());
01182             else if(pixeltype == "DOUBLE")
01183                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, double());
01184         }
01185         else
01186         {
01187             if(pixeltype == "UINT8")
01188                 detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt8)0);
01189             else if(pixeltype == "INT16")
01190                 detail::exportVectorImage( sul, slr, sget, enc.get(), Int16());
01191             else if(pixeltype == "UINT16")
01192                 detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt16)0);
01193             else if(pixeltype == "INT32")
01194                 detail::exportVectorImage( sul, slr, sget, enc.get(), Int32());
01195             else if(pixeltype == "UINT32")
01196                 detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt32)0);
01197             else if(pixeltype == "FLOAT")
01198                 detail::exportVectorImage( sul, slr, sget, enc.get(), float());
01199             else if(pixeltype == "DOUBLE")
01200                 detail::exportVectorImage( sul, slr, sget, enc.get(), double());
01201         }
01202         enc->close();
01203     }
01204 
01205     template < class SrcIterator, class SrcAccessor >
01206     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
01207                       const ImageExportInfo & info, VigraTrueType /*scalar*/ )
01208     {
01209         typedef typename SrcAccessor::value_type SrcValueType;
01210         std::string pixeltype = info.getPixelType();
01211         std::auto_ptr<Encoder> enc = encoder(info);
01212         bool downcast = negotiatePixelType(enc->getFileType(),
01213                            TypeAsString<SrcValueType>::result(), pixeltype);
01214         enc->setPixelType(pixeltype);
01215         if(downcast || info.hasForcedRangeMapping())
01216         {
01217             if(pixeltype == "UINT8")
01218                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (UInt8)0);
01219             else if(pixeltype == "INT16")
01220                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, Int16());
01221             else if(pixeltype == "UINT16")
01222                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (UInt16)0);
01223             else if(pixeltype == "INT32")
01224                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, Int32());
01225             else if(pixeltype == "UINT32")
01226                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (UInt32)0);
01227             else if(pixeltype == "FLOAT")
01228                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, float());
01229             else if(pixeltype == "DOUBLE")
01230                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, double());
01231         }
01232         else
01233         {
01234             if(pixeltype == "UINT8")
01235                 detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt8)0);
01236             else if(pixeltype == "INT16")
01237                 detail::exportScalarImage( sul, slr, sget, enc.get(), Int16());
01238             else if(pixeltype == "UINT16")
01239                 detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt16)0);
01240             else if(pixeltype == "INT32")
01241                 detail::exportScalarImage( sul, slr, sget, enc.get(), Int32());
01242             else if(pixeltype == "UINT32")
01243                 detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt32)0);
01244             else if(pixeltype == "FLOAT")
01245                 detail::exportScalarImage( sul, slr, sget, enc.get(), float());
01246             else if(pixeltype == "DOUBLE")
01247                 detail::exportScalarImage( sul, slr, sget, enc.get(), double());
01248         }
01249         enc->close();
01250     }
01251 
01252 //@}
01253 
01254 } // namespace vigra
01255 
01256 #endif /* VIGRA_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.8.0 (20 Sep 2011)