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