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