VIGRA - VIGRA: vigra/impex.hxx Source File

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

# vigra/impex.hxx

Go to the documentation of this file.

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 2001-2002 by Gunnar Kedenburg                */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.6.0, Aug 13 2008 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@informatik.uni-hamburg.de                               */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037 /* Modifications by Pablo d'Angelo
    00038  * updated to vigra 1.4 by Douglas Wilkins
    00039  * as of 18 Febuary 2006:
    00040  *  - Added import/export of UINT16 and UINT32 image types.
    00041  * Modifications by Andrew Mihal
    00042  * updated to vigra 1.4 by Douglas Wilkins
    00043  * as of 18 Febuary 2006:
    00044  *  - Moved some RowIterator declarations around to avoid using default ctors
    00045  *    (cachedfileimages do not have default ctors for row iterators).
    00046  *  - Added some case-specific optimizations
    00047  */
    00048
    00049 /*!
    00050   \file  impex.hxx
    00051   \brief image import and export functions
    00052
    00053   this file provides the declarations and implementations of importImage()
    00054   and exportImage(). the matching implementation for the given datatype is
    00055   selected by template metacode.
    00056 */
    00057
    00058 #ifndef VIGRA_IMPEX_HXX
    00059 #define VIGRA_IMPEX_HXX
    00060
    00061 #if defined(_MSC_VER)
    00062 #pragma warning (disable: 4267)
    00063 #endif
    00064
    00065 #include "sized_int.hxx"
    00066 #include "stdimage.hxx"
    00067 #include "tinyvector.hxx"
    00068 #include "imageinfo.hxx"
    00069 #include "numerictraits.hxx"
    00070 #include "codec.hxx"
    00071 #include "accessor.hxx"
    00072 #include "inspectimage.hxx"
    00073 #include "transformimage.hxx"
    00074 #include "copyimage.hxx"
    00075 #include "multi_array.hxx"
    00076
    00077 // TODO
    00078 // next refactoring: pluggable conversion algorithms
    00079
    00080 namespace vigra
    00081 {
    00082 /** \addtogroup VigraImpex
    00083 **/
    00084 //@{
    00085
    00086     /*!
    00087       \brief used for reading bands after the source data type has been figured out.
    00088
    00089         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00090         Namespace: vigra
    00091
    00092         <b> Declaration:</b>
    00093
    00094         \code
    00095         namespace vigra {
    00096             template< class ImageIterator, class Accessor, class SrcValueType >
    00097             void read_bands( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
    00098         }
    00099         \endcode
    00100
    00101       \param dec decoder object through which the source data will be accessed
    00102       \param ys  image iterator referencing the upper left pixel of the destination image
    00103       \param a   image accessor for the destination image
    00104     */
    00105     template< class ImageIterator, class Accessor, class SrcValueType >
    00106     void read_bands( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
    00107     {
    00108         typedef unsigned int size_type;
    00109         typedef typename ImageIterator::row_iterator DstRowIterator;
    00110         typedef typename Accessor::value_type  AccessorValueType;
    00111         typedef typename AccessorValueType::value_type DstValueType;
    00112
    00113         const size_type width = dec->getWidth();
    00114         const size_type height = dec->getHeight();
    00115         const size_type num_bands = dec->getNumBands();
    00116
    00117         vigra_precondition(num_bands == a.size(ys),
    00118            "importImage(): number of bands (color channels) in file and destination image differ.");
    00119
    00120         SrcValueType const * scanline;
    00121         // MIHAL no default constructor available for cachedfileimages.
    00122         DstRowIterator xs = ys.rowIterator();
    00123
    00124         // iterate
    00125         if (num_bands == 4) {
    00126             // Speedup for this particular case
    00127             unsigned int offset = dec->getOffset();
    00128             SrcValueType const * scanline0;
    00129             SrcValueType const * scanline1;
    00130             SrcValueType const * scanline2;
    00131             SrcValueType const * scanline3;
    00132             for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00133                 dec->nextScanline();
    00134                 xs = ys.rowIterator();
    00135                 scanline0 = static_cast< SrcValueType const * >
    00136                     (dec->currentScanlineOfBand(0));
    00137                 scanline1 = static_cast< SrcValueType const * >
    00138                     (dec->currentScanlineOfBand(1));
    00139                 scanline2 = static_cast< SrcValueType const * >
    00140                     (dec->currentScanlineOfBand(2));
    00141                 scanline3 = static_cast< SrcValueType const * >
    00142                     (dec->currentScanlineOfBand(3));
    00143                 for( size_type x = 0; x < width; ++x, ++xs ) {
    00144 /*
    00145                     a.template setComponent<SrcValueType, DstRowIterator, 0>( *scanline0, xs );
    00146                     a.template setComponent<SrcValueType, DstRowIterator, 1>( *scanline1, xs );
    00147                     a.template setComponent<SrcValueType, DstRowIterator, 2>( *scanline2, xs );
    00148                     a.template setComponent<SrcValueType, DstRowIterator, 3>( *scanline3, xs );
    00149 */
    00150                     a.setComponent( *scanline0, xs, 0);
    00151                     a.setComponent( *scanline1, xs, 1);
    00152                     a.setComponent( *scanline2, xs, 2);
    00153                     a.setComponent( *scanline3, xs, 3);
    00154                     scanline0 += offset;
    00155                     scanline1 += offset;
    00156                     scanline2 += offset;
    00157                     scanline3 += offset;
    00158                 }
    00159             }
    00160         }
    00161         else {
    00162             // General case
    00163         for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00164             dec->nextScanline();
    00165             for( size_type b = 0; b < num_bands; ++b ) {
    00166                 xs = ys.rowIterator();
    00167                 scanline = static_cast< SrcValueType const * >
    00168                     (dec->currentScanlineOfBand(b));
    00169                 for( size_type x = 0; x < width; ++x, ++xs ) {
    00170                     a.setComponent( *scanline, xs, b );
    00171                     scanline += dec->getOffset();
    00172                 }
    00173             }
    00174         }
    00175         }
    00176     } // read_bands()
    00177
    00178     /*!
    00179       \brief used for reading bands after the source data type has been figured out.
    00180
    00181         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00182         Namespace: vigra
    00183
    00184         <b> Declaration:</b>
    00185
    00186         \code
    00187         namespace vigra {
    00188             template< class ImageIterator, class Accessor, class SrcValueType >
    00189             void read_band( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
    00190         }
    00191         \endcode
    00192
    00193       \param dec decoder object through which the source data will be accessed
    00194       \param ys  image iterator referencing the upper left pixel of the destination image
    00195       \param a   image accessor for the destination image
    00196     */
    00197     template< class ImageIterator, class Accessor, class SrcValueType >
    00198     void read_band( Decoder * dec, ImageIterator ys, Accessor a, SrcValueType )
    00199     {
    00200         typedef unsigned int size_type;
    00201         typedef typename ImageIterator::row_iterator DstRowIterator;
    00202         typedef typename Accessor::value_type DstValueType;
    00203         const size_type width = dec->getWidth();
    00204         const size_type height = dec->getHeight();
    00205
    00206         SrcValueType const * scanline;
    00207         // MIHAL no default constructor available for cachedfileimages.
    00208         DstRowIterator xs = ys.rowIterator();
    00209
    00210         for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00211             dec->nextScanline();
    00212             xs = ys.rowIterator();
    00213             scanline = static_cast< SrcValueType const * >(dec->currentScanlineOfBand(0));
    00214             for( size_type x = 0; x < width; ++x, ++xs )
    00215                 a.set( scanline[x], xs );
    00216         }
    00217     } // read_band()
    00218
    00219     /*!
    00220       \brief used for reading images of vector type, such as integer of float rgb.
    00221
    00222         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00223         Namespace: vigra
    00224
    00225         <b> Declaration:</b>
    00226
    00227         \code
    00228         namespace vigra {
    00229             template< class ImageIterator, class Accessor >
    00230             void importVectorImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00231         }
    00232         \endcode
    00233
    00234         <b> Paramters:</b>
    00235
    00236         <DL>
    00237         <DT>ImageIterator<DD> the image iterator type for the destination image
    00238         <DT>Accessor<DD> the image accessor type for the destination image
    00239         <DT>info<DD> user supplied image import information
    00240         <DT>iter<DD> image iterator referencing the upper left pixel of the destination image
    00241         <DT>a<DD> image accessor for the destination image
    00242         </DL>
    00243     */
    00244 doxygen_overloaded_function(template <...> void importVectorImage)
    00245
    00246     template< class ImageIterator, class Accessor >
    00247     void importVectorImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00248     {
    00249         std::auto_ptr<Decoder> dec = decoder(info);
    00250         std::string pixeltype = dec->getPixelType();
    00251
    00252         if ( pixeltype == "UINT8" )
    00253             read_bands( dec.get(), iter, a, (UInt8)0 );
    00254         else if ( pixeltype == "INT16" )
    00255             read_bands( dec.get(), iter, a, Int16() );
    00256         else if ( pixeltype == "UINT16" )
    00257             read_bands( dec.get(), iter, a, (UInt16)0 );
    00258         else if ( pixeltype == "INT32" )
    00259             read_bands( dec.get(), iter, a, Int32() );
    00260         else if ( pixeltype == "UINT32" )
    00261             read_bands( dec.get(), iter, a, (UInt32)0 );
    00262         else if ( pixeltype == "FLOAT" )
    00263             read_bands( dec.get(), iter, a, float() );
    00264         else if ( pixeltype == "DOUBLE" )
    00265             read_bands( dec.get(), iter, a, double() );
    00266         else
    00267             vigra_precondition( false, "invalid pixeltype" );
    00268
    00269         // close the decoder
    00270         dec->close();
    00271     }
    00272
    00273     /*!
    00274       \brief used for reading images of  scalar type, such as integer and float grayscale.
    00275
    00276         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00277         Namespace: vigra
    00278
    00279         <b> Declaration:</b>
    00280
    00281         \code
    00282         namespace vigra {
    00283             template < class ImageIterator, class Accessor >
    00284             void importScalarImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00285         }
    00286         \endcode
    00287
    00288         <b> Paramters:</b>
    00289
    00290         <DL>
    00291         <DT>ImageIterator<DD> the image iterator type for the destination image
    00292         <DT>Accessor<DD> the image accessor type for the destination image
    00293         <DT>info<DD> user supplied image import information
    00294         <DT>iter<DD> image iterator referencing the upper left pixel of the destination image
    00295         <DT>a<DD> image accessor for the destination image
    00296         </DL>
    00297     */
    00298 doxygen_overloaded_function(template <...> void importScalarImage)
    00299
    00300     template < class ImageIterator, class Accessor >
    00301     void importScalarImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00302     {
    00303         std::auto_ptr<Decoder> dec = decoder(info);
    00304         std::string pixeltype = dec->getPixelType();
    00305
    00306         if ( pixeltype == "UINT8" )
    00307             read_band( dec.get(), iter, a, (UInt8)0 );
    00308         else if ( pixeltype == "INT16" )
    00309             read_band( dec.get(), iter, a, Int16() );
    00310         else if ( pixeltype == "UINT16" )
    00311             read_band( dec.get(), iter, a, (UInt16)0 );
    00312         else if ( pixeltype == "INT32" )
    00313             read_band( dec.get(), iter, a, Int32() );
    00314         else if ( pixeltype == "UINT32" )
    00315             read_band( dec.get(), iter, a, (UInt32)0 );
    00316         else if ( pixeltype == "FLOAT" )
    00317             read_band( dec.get(), iter, a, float() );
    00318         else if ( pixeltype == "DOUBLE" )
    00319             read_band( dec.get(), iter, a, double() );
    00320         else
    00321             vigra_precondition( false, "invalid pixeltype" );
    00322
    00323         // close the decoder
    00324         dec->close();
    00325     }
    00326
    00327 /********************************************************/
    00328 /*                                                      */
    00329 /*                     importImage                      */
    00330 /*                                                      */
    00331 /********************************************************/
    00332
    00333     /** \brief Read the image specified by the given \ref vigra::ImageImportInfo object.
    00334
    00335         <b> Declarations:</b>
    00336
    00337         pass arguments explicitly:
    00338         \code
    00339         namespace vigra {
    00340             template <class ImageIterator, class Accessor>
    00341             void
    00342             importImage(ImageImportInfo const & image, ImageIterator iter, Accessor a)
    00343         }
    00344         \endcode
    00345
    00346         use argument objects in conjunction with \ref ArgumentObjectFactories :
    00347         \code
    00348         namespace vigra {
    00349             template <class ImageIterator, class Accessor>
    00350             inline void
    00351             importImage(ImageImportInfo const & image, pair<ImageIterator, Accessor> dest)
    00352         }
    00353         \endcode
    00354
    00355         <b> Usage:</b>
    00356
    00357         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00358         Namespace: vigra
    00359
    00360         \code
    00361
    00362         vigra::ImageImportInfo info("myimage.gif");
    00363
    00364         if(info.isGrayscale())
    00365         {
    00366             // create byte image of appropriate size
    00367             vigra::BImage in(info.width(), info.height());
    00368
    00369             vigra::importImage(info, destImage(in)); // read the image
    00370             ...
    00371         }
    00372         else
    00373         {
    00374             // create byte RGB image of appropriate size
    00375             vigra::BRGBImage in(info.width(), info.height());
    00376
    00377             vigra::importImage(info, destImage(in)); // read the image
    00378             ...
    00379         }
    00380
    00381         \endcode
    00382
    00383         <b> Preconditions:</b>
    00384
    00385         <UL>
    00386
    00387         <LI> the image file must be readable
    00388         <LI> the file type must be one of
    00389
    00390                 <DL>
    00391                 <DT>"BMP"<DD> Microsoft Windows bitmap image file.
    00392                 <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color.
    00393                 <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format; compressed 24-bit color. (only available if libjpeg is installed)
    00394                 <DT>"PNG"<DD> Portable Network Graphic. (only available if libpng is installed)
    00395                 <DT>"PBM"<DD> Portable bitmap format (black and white).
    00396                 <DT>"PGM"<DD> Portable graymap format (gray scale).
    00397                 <DT>"PNM"<DD> Portable anymap.
    00398                 <DT>"PPM"<DD> Portable pixmap format (color).
    00399                 <DT>"SUN"<DD> SUN Rasterfile.
    00400                 <DT>"TIFF"<DD> Tagged Image File Format. (only available if libtiff is installed.)
    00401                 <DT>"VIFF"<DD> Khoros Visualization image file.
    00402                 </DL>
    00403         </UL>
    00404     **/
    00405 doxygen_overloaded_function(template <...> void importImage)
    00406
    00407     template < class ImageIterator, class Accessor >
    00408     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00409     {
    00410         typedef typename NumericTraits<typename Accessor::value_type>::isScalar is_scalar;
    00411         importImage( info, iter, a, is_scalar() );
    00412     }
    00413
    00414     template < class ImageIterator, class Accessor >
    00415     void importImage( const ImageImportInfo & info, pair< ImageIterator, Accessor > dest )
    00416     {
    00417         importImage( info, dest.first, dest.second );
    00418     }
    00419
    00420     template < class ImageIterator, class Accessor >
    00421     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraFalseType )
    00422     {
    00423         importVectorImage( info, iter, a );
    00424     }
    00425
    00426     template < class ImageIterator, class Accessor >
    00427     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraTrueType )
    00428     {
    00429         importScalarImage( info, iter, a );
    00430     }
    00431
    00432     /*!
    00433       \brief used for writing bands after the source data type has been figured out.
    00434
    00435         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00436         Namespace: vigra
    00437
    00438         <b> Declaration:</b>
    00439
    00440         \code
    00441         namespace vigra {
    00442             template< class ImageIterator, class Accessor, class DstValueType >
    00443             void write_bands( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
    00444         }
    00445         \endcode
    00446
    00447       \param enc encoder object through which the destination data will be accessed
    00448       \param ul  image iterator referencing the upper left pixel of the source image
    00449       \param lr  image iterator referencing the lower right pixel of the source image
    00450       \param a   image accessor for the source image
    00451     */
    00452     template< class ImageIterator, class Accessor, class DstValueType >
    00453     void write_bands( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType)
    00454     {
    00455         typedef unsigned int size_type;
    00456         typedef typename ImageIterator::row_iterator SrcRowIterator;
    00457         typedef typename Accessor::value_type  AccessorValueType;
    00458         typedef typename AccessorValueType::value_type SrcValueType;
    00459
    00460         // complete decoder settings
    00461         const size_type width = lr.x - ul.x;
    00462         const size_type height = lr.y - ul.y;
    00463         enc->setWidth(width);
    00464         enc->setHeight(height);
    00465         const size_type num_bands = a.size(ul);
    00466         enc->setNumBands(num_bands);
    00467         enc->finalizeSettings();
    00468
    00469         DstValueType * scanline;
    00470
    00471         // iterate
    00472         ImageIterator ys(ul);
    00473         // MIHAL no default constructor available for cachedfileimages
    00474         SrcRowIterator xs = ys.rowIterator();
    00475
    00476         if (num_bands == 4) {
    00477             // Speedup for this particular case
    00478             unsigned int offset = enc->getOffset();
    00479             DstValueType * scanline0;
    00480             DstValueType * scanline1;
    00481             DstValueType * scanline2;
    00482             DstValueType * scanline3;
    00483             for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00484                 xs = ys.rowIterator();
    00485                 scanline0 = static_cast< DstValueType * >
    00486                         (enc->currentScanlineOfBand(0));
    00487                 scanline1 = static_cast< DstValueType * >
    00488                         (enc->currentScanlineOfBand(1));
    00489                 scanline2 = static_cast< DstValueType * >
    00490                         (enc->currentScanlineOfBand(2));
    00491                 scanline3 = static_cast< DstValueType * >
    00492                         (enc->currentScanlineOfBand(3));
    00493                 for( size_type x = 0; x < width; ++x, ++xs) {
    00494 /*
    00495                     *scanline0 = a.template getComponent<SrcRowIterator, 0>( xs );
    00496                     *scanline1 = a.template getComponent<SrcRowIterator, 1>( xs );
    00497                     *scanline2 = a.template getComponent<SrcRowIterator, 2>( xs );
    00498                     *scanline3 = a.template getComponent<SrcRowIterator, 3>( xs );
    00499 */
    00500                     *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
    00501                     *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
    00502                     *scanline2 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 2));
    00503                     *scanline3 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 3));
    00504                     scanline0 += offset;
    00505                     scanline1 += offset;
    00506                     scanline2 += offset;
    00507                     scanline3 += offset;
    00508                 }
    00509                 enc->nextScanline();
    00510             }
    00511         }
    00512         else {
    00513             // General case
    00514         for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00515             for( size_type b = 0; b < num_bands; ++b ) {
    00516                 xs = ys.rowIterator();
    00517                 scanline = static_cast< DstValueType * >
    00518                     (enc->currentScanlineOfBand(b));
    00519                 for( size_type x = 0; x < width; ++x, ++xs ) {
    00520                     *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, b ));
    00521                     scanline += enc->getOffset();
    00522                 }
    00523             }
    00524             enc->nextScanline();
    00525         }
    00526         }
    00527     } // write_bands()
    00528
    00529     template< class MArray, class DstValueType >
    00530     void write_bands( Encoder * enc, MArray const & array, DstValueType)
    00531     {
    00532         typedef unsigned int size_type;
    00533
    00534         // complete decoder settings
    00535         const size_type width = array.shape(0);
    00536         const size_type height = array.shape(1);
    00537         enc->setWidth(width);
    00538         enc->setHeight(height);
    00539         const size_type num_bands = array.shape(2);
    00540         enc->setNumBands(num_bands);
    00541         enc->finalizeSettings();
    00542
    00543         DstValueType * scanline;
    00544
    00545         // iterate
    00546         for( size_type y = 0; y < height; ++y ) {
    00547             for( size_type b = 0; b < num_bands; ++b ) {
    00548                 scanline = static_cast< DstValueType * >
    00549                     (enc->currentScanlineOfBand(b));
    00550                 for( size_type x = 0; x < width; ++x) {
    00551                     *scanline = array(x, y, b);
    00552                     scanline += enc->getOffset();
    00553                 }
    00554             }
    00555             enc->nextScanline();
    00556         }
    00557     } // write_bands()
    00558
    00559     /*!
    00560       \brief used for writing bands after the source data type has been figured out.
    00561
    00562         <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00563         Namespace: vigra
    00564
    00565         <b> Declaration:</b>
    00566
    00567         \code
    00568         namespace vigra {
    00569             template< class ImageIterator, class Accessor, class DstValueType >
    00570             void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
    00571         }
    00572         \endcode
    00573
    00574       \param enc encoder object through which the destination data will be accessed
    00575       \param ul  image iterator referencing the upper left pixel of the source image
    00576       \param lr  image iterator referencing the lower right pixel of the source image
    00577       \param a   image accessor for the source image
    00578     */
    00579     template< class ImageIterator, class Accessor, class DstValueType >
    00580     void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType)
    00581     {
    00582         typedef unsigned int size_type;
    00583         typedef typename ImageIterator::row_iterator SrcRowIterator;
    00584         typedef typename Accessor::value_type SrcValueType;
    00585
    00586         // complete decoder settings
    00587         const size_type width = lr.x - ul.x;
    00588         const size_type height = lr.y - ul.y;
    00589         enc->setWidth(width);
    00590         enc->setHeight(height);
    00591         enc->setNumBands(1);
    00592         enc->finalizeSettings();
    00593
    00594         DstValueType * scanline;
    00595
    00596         // iterate
    00597         ImageIterator ys(ul);
    00598         // MIHAL no default constructor available for cachedfileimages.
    00599         SrcRowIterator xs = ys.rowIterator();
    00600         size_type y;
    00601         for(  y = 0; y < height; ++y, ++ys.y ) {
    00602             xs = ys.rowIterator();
    00603             scanline = static_cast< DstValueType * >(enc->currentScanlineOfBand(0));
    00604             for( size_type x = 0; x < width; ++x, ++xs, ++scanline )
    00605                 *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a(xs));
    00606             enc->nextScanline();
    00607         }
    00608     } // write_band()
    00609
    00610 namespace detail {
    00611
    00612     // export scalar images without conversion
    00613     template < class SrcIterator, class SrcAccessor, class T >
    00614     void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00615                            Encoder * enc, T zero)
    00616     {
    00617         write_band( enc, sul, slr, sget, zero );
    00618     }
    00619
    00620     // export scalar images with conversion
    00621     template < class SrcIterator, class SrcAccessor, class T >
    00622     void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00623                            Encoder * enc,
    00624                            const ImageExportInfo & info,
    00625                            T zero)
    00626     {
    00627         double fromMin, fromMax, toMin, toMax;
    00628         if(info.hasForcedRangeMapping())
    00629         {
    00630             fromMin = info.getFromMin();
    00631             fromMax = info.getFromMax();
    00632             toMin = info.getToMin();
    00633             toMax = info.getToMax();
    00634         }
    00635         else
    00636         {
    00637             typedef typename SrcAccessor::value_type SrcValue;
    00638             FindMinMax<SrcValue> minmax;
    00639             inspectImage( sul, slr, sget, minmax );
    00640
    00641             fromMin = (double)minmax.min;
    00642             fromMax = (double)minmax.max;
    00643             toMin = (double)NumericTraits<T>::min();
    00644             toMax = (double)NumericTraits<T>::max();
    00645         }
    00646         double scale = (toMax - toMin) / (fromMax - fromMin);
    00647         double offset = (toMin / scale) - fromMin;
    00648         BasicImage<T> image(slr-sul);
    00649         transformImage( sul, slr, sget, image.upperLeft(), image.accessor(),
    00650                         linearIntensityTransform(scale, offset));
    00651         write_band( enc, image.upperLeft(),
    00652                     image.lowerRight(), image.accessor(), zero );
    00653     }
    00654
    00655     // export vector images without conversion
    00656     template < class SrcIterator, class SrcAccessor, class T >
    00657     void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00658                            Encoder * enc, T zero)
    00659     {
    00660         int bands = sget.size(sul);
    00661         vigra_precondition(isBandNumberSupported(enc->getFileType(), bands),
    00662            "exportImage(): file format does not support requested number of bands (color channels)");
    00663         write_bands( enc, sul, slr, sget, zero );
    00664     }
    00665
    00666     // export vector images with conversion
    00667     template < class SrcIterator, class SrcAccessor, class T >
    00668     void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00669                            Encoder * enc,
    00670                            const ImageExportInfo & info,
    00671                            T zero)
    00672     {
    00673         unsigned int bands = sget.size(sul);
    00674         vigra_precondition(isBandNumberSupported(enc->getFileType(), bands),
    00675            "exportImage(): file format does not support requested number of bands (color channels)");
    00676
    00677         typedef typename SrcAccessor::value_type SrcValue;
    00678         double fromMin, fromMax, toMin, toMax;
    00679         if(info.hasForcedRangeMapping())
    00680         {
    00681             fromMin = info.getFromMin();
    00682             fromMax = info.getFromMax();
    00683             toMin = info.getToMin();
    00684             toMax = info.getToMax();
    00685         }
    00686         else
    00687         {
    00688             typedef typename SrcValue::value_type SrcComponent;
    00689
    00690             FindMinMax<SrcComponent> minmax;
    00691             for(unsigned int i=0; i<bands; ++i)
    00692             {
    00693                 VectorComponentValueAccessor<SrcValue> band(i);
    00694                 inspectImage( sul, slr, band, minmax );
    00695             }
    00696
    00697             fromMin = (double)minmax.min;
    00698             fromMax = (double)minmax.max;
    00699             toMin = (double)NumericTraits<T>::min();
    00700             toMax = (double)NumericTraits<T>::max();
    00701         }
    00702         double scale = (toMax - toMin) / (fromMax - fromMin);
    00703         double offset = (toMin / scale) - fromMin;
    00704         int w = slr.x - sul.x;
    00705         int h = slr.y - sul.y;
    00706
    00707         typedef vigra::MultiArray<3, T> MArray;
    00708         MArray array(typename MArray::difference_type(w, h, bands));
    00709
    00710         for(unsigned int i=0; i<bands; ++i)
    00711         {
    00712             BasicImageView<T> subImage = makeBasicImageView(array.bindOuter(i));
    00713             VectorComponentValueAccessor<SrcValue> band(i);
    00714             transformImage( sul, slr, band, subImage.upperLeft(), subImage.accessor(),
    00715                             linearIntensityTransform( scale, offset ) );
    00716         }
    00717         write_bands( enc, array, zero );
    00718     }
    00719
    00720 } // namespace detail
    00721
    00722
    00723     /*!
    00724       \brief Deprecated.
    00725
    00726         Use \ref exportImage() instead.
    00727
    00728         <b> Declaration:</b>
    00729
    00730         \code
    00731         namespace vigra {
    00732             template < class SrcIterator, class SrcAccessor >
    00733             void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00734                                             const ImageExportInfo & info )
    00735         }
    00736         \endcode
    00737     */
    00738 doxygen_overloaded_function(template <...> void exportFloatingVectorImage)
    00739
    00740     template < class SrcIterator, class SrcAccessor >
    00741     void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00742                                     const ImageExportInfo & info )
    00743     {
    00744         exportImage(sul, slr, sget, info);
    00745     }
    00746
    00747     /*!
    00748       \brief Deprecated.
    00749
    00750         Use \ref exportImage() instead.
    00751
    00752         <b> Declaration:</b>
    00753
    00754         \code
    00755         namespace vigra {
    00756             template < class SrcIterator, class SrcAccessor >
    00757             void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00758                                             const ImageExportInfo & info )
    00759         }
    00760         \endcode
    00761     */
    00762 doxygen_overloaded_function(template <...> void exportIntegralVectorImage)
    00763
    00764     template < class SrcIterator, class SrcAccessor >
    00765     void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00766                                     const ImageExportInfo & info )
    00767     {
    00768         exportImage(sul, slr, sget, info);
    00769     }
    00770
    00771     /*!
    00772       \brief Deprecated.
    00773
    00774         Use \ref exportImage() instead.
    00775
    00776         <b> Declaration:</b>
    00777
    00778         \code
    00779         namespace vigra {
    00780             template < class SrcIterator, class SrcAccessor >
    00781             void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00782                                             const ImageExportInfo & info )
    00783         }
    00784         \endcode
    00785     */
    00786 doxygen_overloaded_function(template <...> void exportFloatingScalarImage)
    00787
    00788     template < class SrcIterator, class SrcAccessor >
    00789     void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00790                                     const ImageExportInfo & info )
    00791     {
    00792         exportImage(sul, slr, sget, info);
    00793     }
    00794
    00795     /*!
    00796       \brief Deprecated.
    00797
    00798         Use \ref exportImage() instead.
    00799
    00800         <b> Declaration:</b>
    00801
    00802         \code
    00803         namespace vigra {
    00804             template < class SrcIterator, class SrcAccessor >
    00805             void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00806                                             const ImageExportInfo & info )
    00807         }
    00808         \endcode
    00809     */
    00810 doxygen_overloaded_function(template <...> void exportIntegralScalarImage)
    00811
    00812     template < class SrcIterator, class SrcAccessor >
    00813     void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00814                                     const ImageExportInfo & info )
    00815     {
    00816         exportImage(sul, slr, sget, info);
    00817     }
    00818
    00819 /********************************************************/
    00820 /*                                                      */
    00821 /*                     exportImage                      */
    00822 /*                                                      */
    00823 /********************************************************/
    00824
    00825 /** \brief Write an image, given an \ref vigra::ImageExportInfo object.
    00826
    00827     If the file format to be exported to supports the pixel type of the
    00828     source image, the pixel type will be kept (e.g. <tt>float</tt>
    00829     can be stored as TIFF without conversion, in contrast to most other
    00830     image export toolkits). Otherwise, the pixel values are transformed
    00831     to the range 0.255 and converted to <tt>unsigned char</tt>. Currently,
    00832     the following file formats are supported. The pixel types given in
    00833     brackets are those that are written without conversion:
    00834
    00835     <DL>
    00836     <DT>"BMP"<DD> Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB).
    00837     <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color (pixel types: UINT8 as gray and RGB).
    00838     <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format; compressed 24-bit color
    00839                   (pixel types: UINT8 as gray and RGB). (only available if libjpeg is installed)
    00840     <DT>"PNG"<DD> Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels).
    00841                   (only available if libpng is installed)
    00842     <DT>"PBM"<DD> Portable bitmap format (black and white).
    00843     <DT>"PGM"<DD> Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale)).
    00844     <DT>"PNM"<DD> Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB).
    00845     <DT>"PPM"<DD> Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB).
    00846     <DT>"SUN"<DD> SUN Rasterfile (pixel types: UINT8 as gray and RGB).
    00847     <DT>"TIFF"<DD> Tagged Image File Format
    00848                 (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels).
    00849                 (only available if libtiff is installed.)
    00850     <DT>"VIFF"<DD> Khoros Visualization image file
    00851         (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels).
    00852     </DL>
    00853
    00854     <b> Declarations:</b>
    00855
    00856     pass arguments explicitly:
    00857     \code
    00858     namespace vigra {
    00859         template <class SrcIterator, class SrcAccessor>
    00860         void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00861                          ImageExportInfo const & info)
    00862     }
    00863     \endcode
    00864
    00865
    00866     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00867     \code
    00868     namespace vigra {
    00869         template <class SrcIterator, class SrcAccessor>
    00870         void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00871                          ImageExportInfo const & info)
    00872     }
    00873     \endcode
    00874
    00875     <b> Usage:</b>
    00876
    00877     <b>\#include</b> <<a href="impex_8hxx-source.html">vigra/impex.hxx</a>><br>
    00878     Namespace: vigra
    00879
    00880     \code
    00881
    00882
    00883     vigra::BRGBImage out(w, h);
    00884     ...
    00885
    00886     // write as JPEG image, using compression quality 80
    00887     vigra::exportImage(srcImageRange(out),
    00888                       vigra::ImageExportInfo("myimage.jpg").setCompression("80"));
    00889
    00890
    00891     // force it to a particular pixel type (the pixel type must be supported by the
    00892     // desired image file format, otherwise an \ref vigra::PreconditionViolation exception will be thrown)
    00893     vigra::exportImage(srcImageRange(out),
    00894                       vigra::ImageExportInfo("myINT16image.tif").setPixelType("INT16"));
    00895     \endcode
    00896
    00897     <b> Preconditions:</b>
    00898
    00899     <UL>
    00900
    00901     <LI> the image file must be writable.
    00902     <LI> the file type must be one of the supported file types.
    00903
    00904
    00905     </UL>
    00906 **/
    00907 doxygen_overloaded_function(template <...> void exportImage)
    00908
    00909     template < class SrcIterator, class SrcAccessor >
    00910     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00911                       const ImageExportInfo & info )
    00912     {
    00913         typedef typename NumericTraits<typename SrcAccessor::value_type>::isScalar is_scalar;
    00914
    00915         try
    00916         {
    00917             exportImage( sul, slr, sget, info, is_scalar() );
    00918         }
    00919         catch(Encoder::TIFFCompressionException &)
    00920         {
    00921             const_cast<ImageExportInfo &>(info).setCompression("");
    00922             exportImage( sul, slr, sget, info, is_scalar() );
    00923         }
    00924     }
    00925
    00926     template < class SrcIterator, class SrcAccessor >
    00927     inline
    00928     void exportImage( triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00929                       const ImageExportInfo & info )
    00930     {
    00931         exportImage( src.first, src.second, src.third, info );
    00932     }
    00933
    00934     template < class SrcIterator, class SrcAccessor >
    00935     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00936                       const ImageExportInfo & info, VigraFalseType /*not scalar */)
    00937     {
    00938         typedef typename SrcAccessor::value_type AccessorValueType;
    00939         typedef typename AccessorValueType::value_type SrcValueType;
    00940         std::string pixeltype = info.getPixelType();
    00941         std::auto_ptr<Encoder> enc = encoder(info);
    00942         bool downcast = negotiatePixelType(enc->getFileType(),
    00943                         TypeAsString<SrcValueType>::result(), pixeltype);
    00944         enc->setPixelType(pixeltype);
    00945         if(downcast || info.hasForcedRangeMapping())
    00946         {
    00947             if(pixeltype == "UINT8")
    00948                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (UInt8)0);
    00949             else if(pixeltype == "INT16")
    00950                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, Int16());
    00951             else if(pixeltype == "UINT16")
    00952                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (UInt16)0);
    00953             else if(pixeltype == "INT32")
    00954                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, Int32());
    00955             else if(pixeltype == "UINT32")
    00956                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (UInt32)0);
    00957             else if(pixeltype == "FLOAT")
    00958                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, float());
    00959             else if(pixeltype == "DOUBLE")
    00960                 detail::exportVectorImage( sul, slr, sget, enc.get(), info, double());
    00961         }
    00962         else
    00963         {
    00964             if(pixeltype == "UINT8")
    00965                 detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt8)0);
    00966             else if(pixeltype == "INT16")
    00967                 detail::exportVectorImage( sul, slr, sget, enc.get(), Int16());
    00968             else if(pixeltype == "UINT16")
    00969                 detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt16)0);
    00970             else if(pixeltype == "INT32")
    00971                 detail::exportVectorImage( sul, slr, sget, enc.get(), Int32());
    00972             else if(pixeltype == "UINT32")
    00973                 detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt32)0);
    00974             else if(pixeltype == "FLOAT")
    00975                 detail::exportVectorImage( sul, slr, sget, enc.get(), float());
    00976             else if(pixeltype == "DOUBLE")
    00977                 detail::exportVectorImage( sul, slr, sget, enc.get(), double());
    00978         }
    00979         enc->close();
    00980     }
    00981
    00982     template < class SrcIterator, class SrcAccessor >
    00983     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00984                       const ImageExportInfo & info, VigraTrueType /*scalar*/ )
    00985     {
    00986         typedef typename SrcAccessor::value_type SrcValueType;
    00987         std::string pixeltype = info.getPixelType();
    00988         std::auto_ptr<Encoder> enc = encoder(info);
    00989         bool downcast = negotiatePixelType(enc->getFileType(),
    00990                            TypeAsString<SrcValueType>::result(), pixeltype);
    00991         enc->setPixelType(pixeltype);
    00992         if(downcast || info.hasForcedRangeMapping())
    00993         {
    00994             if(pixeltype == "UINT8")
    00995                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (UInt8)0);
    00996             else if(pixeltype == "INT16")
    00997                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, Int16());
    00998             else if(pixeltype == "UINT16")
    00999                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (UInt16)0);
    01000             else if(pixeltype == "INT32")
    01001                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, Int32());
    01002             else if(pixeltype == "UINT32")
    01003                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (UInt32)0);
    01004             else if(pixeltype == "FLOAT")
    01005                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, float());
    01006             else if(pixeltype == "DOUBLE")
    01007                 detail::exportScalarImage( sul, slr, sget, enc.get(), info, double());
    01008         }
    01009         else
    01010         {
    01011             if(pixeltype == "UINT8")
    01012                 detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt8)0);
    01013             else if(pixeltype == "INT16")
    01014                 detail::exportScalarImage( sul, slr, sget, enc.get(), Int16());
    01015             else if(pixeltype == "UINT16")
    01016                 detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt16)0);
    01017             else if(pixeltype == "INT32")
    01018                 detail::exportScalarImage( sul, slr, sget, enc.get(), Int32());
    01019             else if(pixeltype == "UINT32")
    01020                 detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt32)0);
    01021             else if(pixeltype == "FLOAT")
    01022                 detail::exportScalarImage( sul, slr, sget, enc.get(), float());
    01023             else if(pixeltype == "DOUBLE")
    01024                 detail::exportScalarImage( sul, slr, sget, enc.get(), double());
    01025         }
    01026         enc->close();
    01027     }
    01028
    01029 //@}
    01030
    01031 } // namespace vigra
    01032
    01033 #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.6.0 (13 Aug 2008)