[ 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)