[ VIGRA Homepage | Class Index | Function Index | File Index | 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.5.0, Dec 07 2006 )                                    */
    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 /*        koethe@informatik.uni-hamburg.de          or                  */
    00012 /*        vigra@kogs1.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       \param ImageIterator the image iterator type for the destination image
    00235       \param Accessor      the image accessor type for the destination image
    00236       \param info          user supplied image import information
    00237       \param iter          image iterator referencing the upper left pixel of the destination image
    00238       \param a             image accessor for the destination image
    00239     */
    00240     template< class ImageIterator, class Accessor >
    00241     void importVectorImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00242     {
    00243         std::auto_ptr<Decoder> dec = decoder(info);
    00244         std::string pixeltype = dec->getPixelType();
    00245
    00246         if ( pixeltype == "UINT8" )
    00247             read_bands( dec.get(), iter, a, (UInt8)0 );
    00248         else if ( pixeltype == "INT16" )
    00249             read_bands( dec.get(), iter, a, Int16() );
    00250         else if ( pixeltype == "UINT16" )
    00251             read_bands( dec.get(), iter, a, (UInt16)0 );
    00252         else if ( pixeltype == "INT32" )
    00253             read_bands( dec.get(), iter, a, Int32() );
    00254         else if ( pixeltype == "UINT32" )
    00255             read_bands( dec.get(), iter, a, (UInt32)0 );
    00256         else if ( pixeltype == "FLOAT" )
    00257             read_bands( dec.get(), iter, a, float() );
    00258         else if ( pixeltype == "DOUBLE" )
    00259             read_bands( dec.get(), iter, a, double() );
    00260         else
    00261             vigra_precondition( false, "invalid pixeltype" );
    00262
    00263         // close the decoder
    00264         dec->close();
    00265     }
    00266
    00267     /*!
    00268       \brief used for reading images of  scalar type, such as integer and float grayscale.
    00269
    00270         <b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx</a>"<br>
    00271         Namespace: vigra
    00272
    00273         <b> Declaration:</b>
    00274
    00275         \code
    00276         namespace vigra {
    00277             template < class ImageIterator, class Accessor >
    00278             void importScalarImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00279         }
    00280         \endcode
    00281
    00282       \param ImageIterator the image iterator type for the destination image
    00283       \param Accessor      the image accessor type for the destination image
    00284       \param info          user supplied image import information
    00285       \param iter          image iterator referencing the upper left pixel of the destination image
    00286       \param a             image accessor for the destination image
    00287     */
    00288     template < class ImageIterator, class Accessor >
    00289     void importScalarImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00290     {
    00291         std::auto_ptr<Decoder> dec = decoder(info);
    00292         std::string pixeltype = dec->getPixelType();
    00293
    00294         if ( pixeltype == "UINT8" )
    00295             read_band( dec.get(), iter, a, (UInt8)0 );
    00296         else if ( pixeltype == "INT16" )
    00297             read_band( dec.get(), iter, a, Int16() );
    00298         else if ( pixeltype == "UINT16" )
    00299             read_band( dec.get(), iter, a, (UInt16)0 );
    00300         else if ( pixeltype == "INT32" )
    00301             read_band( dec.get(), iter, a, Int32() );
    00302         else if ( pixeltype == "UINT32" )
    00303             read_band( dec.get(), iter, a, (UInt32)0 );
    00304         else if ( pixeltype == "FLOAT" )
    00305             read_band( dec.get(), iter, a, float() );
    00306         else if ( pixeltype == "DOUBLE" )
    00307             read_band( dec.get(), iter, a, double() );
    00308         else
    00309             vigra_precondition( false, "invalid pixeltype" );
    00310
    00311         // close the decoder
    00312         dec->close();
    00313     }
    00314
    00315     template < class ImageIterator, class Accessor >
    00316     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraFalseType )
    00317     {
    00318         importVectorImage( info, iter, a );
    00319     }
    00320
    00321     template < class ImageIterator, class Accessor >
    00322     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraTrueType )
    00323     {
    00324         importScalarImage( info, iter, a );
    00325     }
    00326
    00327 /********************************************************/
    00328 /*                                                      */
    00329 /*                     importImage                      */
    00330 /*                                                      */
    00331 /********************************************************/
    00332
    00333     /** \brief Read an image, given an \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     template < class ImageIterator, class Accessor >
    00406     void importImage( const ImageImportInfo & info, ImageIterator iter, Accessor a )
    00407     {
    00408         typedef typename NumericTraits<typename Accessor::value_type>::isScalar is_scalar;
    00409         importImage( info, iter, a, is_scalar() );
    00410     }
    00411
    00412     template < class ImageIterator, class Accessor >
    00413     void importImage( const ImageImportInfo & info, pair< ImageIterator, Accessor > dest )
    00414     {
    00415         importImage( info, dest.first, dest.second );
    00416     }
    00417
    00418     /*!
    00419       \brief used for writing bands after the source data type has been figured out.
    00420
    00421         <b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx</a>"<br>
    00422         Namespace: vigra
    00423
    00424         <b> Declaration:</b>
    00425
    00426         \code
    00427         namespace vigra {
    00428             template< class ImageIterator, class Accessor, class DstValueType >
    00429             void write_bands( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
    00430         }
    00431         \endcode
    00432
    00433       \param enc encoder object through which the destination data will be accessed
    00434       \param ul  image iterator referencing the upper left pixel of the source image
    00435       \param lr  image iterator referencing the lower right pixel of the source image
    00436       \param a   image accessor for the source image
    00437     */
    00438     template< class ImageIterator, class Accessor, class DstValueType >
    00439     void write_bands( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType)
    00440     {
    00441         typedef unsigned int size_type;
    00442         typedef typename ImageIterator::row_iterator SrcRowIterator;
    00443         typedef typename Accessor::value_type  AccessorValueType;
    00444         typedef typename AccessorValueType::value_type SrcValueType;
    00445
    00446         // complete decoder settings
    00447         const size_type width = lr.x - ul.x;
    00448         const size_type height = lr.y - ul.y;
    00449         enc->setWidth(width);
    00450         enc->setHeight(height);
    00451         const size_type num_bands = a.size(ul);
    00452         enc->setNumBands(num_bands);
    00453         enc->finalizeSettings();
    00454
    00455         DstValueType * scanline;
    00456
    00457         // iterate
    00458         ImageIterator ys(ul);
    00459         // MIHAL no default constructor available for cachedfileimages
    00460         SrcRowIterator xs = ys.rowIterator();
    00461
    00462         if (num_bands == 4) {
    00463             // Speedup for this particular case
    00464             unsigned int offset = enc->getOffset();
    00465             DstValueType * scanline0;
    00466             DstValueType * scanline1;
    00467             DstValueType * scanline2;
    00468             DstValueType * scanline3;
    00469             for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00470                 xs = ys.rowIterator();
    00471                 scanline0 = static_cast< DstValueType * >
    00472                         (enc->currentScanlineOfBand(0));
    00473                 scanline1 = static_cast< DstValueType * >
    00474                         (enc->currentScanlineOfBand(1));
    00475                 scanline2 = static_cast< DstValueType * >
    00476                         (enc->currentScanlineOfBand(2));
    00477                 scanline3 = static_cast< DstValueType * >
    00478                         (enc->currentScanlineOfBand(3));
    00479                 for( size_type x = 0; x < width; ++x, ++xs) {
    00480 /*
    00481                     *scanline0 = a.template getComponent<SrcRowIterator, 0>( xs );
    00482                     *scanline1 = a.template getComponent<SrcRowIterator, 1>( xs );
    00483                     *scanline2 = a.template getComponent<SrcRowIterator, 2>( xs );
    00484                     *scanline3 = a.template getComponent<SrcRowIterator, 3>( xs );
    00485 */
    00486                     *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
    00487                     *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
    00488                     *scanline2 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 2));
    00489                     *scanline3 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 3));
    00490                     scanline0 += offset;
    00491                     scanline1 += offset;
    00492                     scanline2 += offset;
    00493                     scanline3 += offset;
    00494                 }
    00495                 enc->nextScanline();
    00496             }
    00497         }
    00498         else {
    00499             // General case
    00500         for( size_type y = 0; y < height; ++y, ++ys.y ) {
    00501             for( size_type b = 0; b < num_bands; ++b ) {
    00502                 xs = ys.rowIterator();
    00503                 scanline = static_cast< DstValueType * >
    00504                     (enc->currentScanlineOfBand(b));
    00505                 for( size_type x = 0; x < width; ++x, ++xs ) {
    00506                     *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, b ));
    00507                     scanline += enc->getOffset();
    00508                 }
    00509             }
    00510             enc->nextScanline();
    00511         }
    00512         }
    00513     } // write_bands()
    00514
    00515     template< class MArray, class DstValueType >
    00516     void write_bands( Encoder * enc, MArray const & array, DstValueType)
    00517     {
    00518         typedef unsigned int size_type;
    00519
    00520         // complete decoder settings
    00521         const size_type width = array.shape(0);
    00522         const size_type height = array.shape(1);
    00523         enc->setWidth(width);
    00524         enc->setHeight(height);
    00525         const size_type num_bands = array.shape(2);
    00526         enc->setNumBands(num_bands);
    00527         enc->finalizeSettings();
    00528
    00529         DstValueType * scanline;
    00530
    00531         // iterate
    00532         for( size_type y = 0; y < height; ++y ) {
    00533             for( size_type b = 0; b < num_bands; ++b ) {
    00534                 scanline = static_cast< DstValueType * >
    00535                     (enc->currentScanlineOfBand(b));
    00536                 for( size_type x = 0; x < width; ++x) {
    00537                     *scanline = array(x, y, b);
    00538                     scanline += enc->getOffset();
    00539                 }
    00540             }
    00541             enc->nextScanline();
    00542         }
    00543     } // write_bands()
    00544
    00545     /*!
    00546       \brief used for writing bands after the source data type has been figured out.
    00547
    00548         <b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx</a>"<br>
    00549         Namespace: vigra
    00550
    00551         <b> Declaration:</b>
    00552
    00553         \code
    00554         namespace vigra {
    00555             template< class ImageIterator, class Accessor, class DstValueType >
    00556             void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
    00557         }
    00558         \endcode
    00559
    00560       \param enc encoder object through which the destination data will be accessed
    00561       \param ul  image iterator referencing the upper left pixel of the source image
    00562       \param lr  image iterator referencing the lower right pixel of the source image
    00563       \param a   image accessor for the source image
    00564     */
    00565     template< class ImageIterator, class Accessor, class DstValueType >
    00566     void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType)
    00567     {
    00568         typedef unsigned int size_type;
    00569         typedef typename ImageIterator::row_iterator SrcRowIterator;
    00570         typedef typename Accessor::value_type SrcValueType;
    00571
    00572         // complete decoder settings
    00573         const size_type width = lr.x - ul.x;
    00574         const size_type height = lr.y - ul.y;
    00575         enc->setWidth(width);
    00576         enc->setHeight(height);
    00577         enc->setNumBands(1);
    00578         enc->finalizeSettings();
    00579
    00580         DstValueType * scanline;
    00581
    00582         // iterate
    00583         ImageIterator ys(ul);
    00584         // MIHAL no default constructor available for cachedfileimages.
    00585         SrcRowIterator xs = ys.rowIterator();
    00586         size_type y;
    00587         for(  y = 0; y < height; ++y, ++ys.y ) {
    00588             xs = ys.rowIterator();
    00589             scanline = static_cast< DstValueType * >(enc->currentScanlineOfBand(0));
    00590             for( size_type x = 0; x < width; ++x, ++xs, ++scanline )
    00591                 *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a(xs));
    00592             enc->nextScanline();
    00593         }
    00594     } // write_band()
    00595
    00596 namespace detail {
    00597
    00598     template < class SrcIterator, class SrcAccessor,
    00599                class DestIterator, class DestAccessor >
    00600     void mapScalarImageToLowerPixelType( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00601                                          DestIterator dul, DestAccessor dget )
    00602     {
    00603         typedef typename SrcAccessor::value_type SrcValue;
    00604         typedef typename DestAccessor::value_type DestValue;
    00605         typedef typename NumericTraits<SrcValue>::RealPromote PromoteValue;
    00606
    00607         FindMinMax<SrcValue> minmax;
    00608         inspectImage( sul, slr, sget, minmax );
    00609         double scale = (double)NumericTraits<DestValue>::max() / (minmax.max - minmax.min) -
    00610                        (double)NumericTraits<DestValue>::min() / (minmax.max - minmax.min);
    00611         double offset = (NumericTraits<DestValue>::min() / scale) - minmax.min ;
    00612         transformImage( sul, slr, sget, dul, dget,
    00613                         linearIntensityTransform( scale, offset ) );
    00614     }
    00615
    00616     // export scalar images with conversion (if necessary)
    00617     template < class SrcIterator, class SrcAccessor, class T >
    00618     void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00619                            Encoder * enc, bool downcast, T zero)
    00620     {
    00621         if (!downcast) {
    00622             write_band( enc, sul, slr, sget, zero );
    00623         } else {
    00624             // convert to unsigned char in the usual way
    00625             BasicImage<T> image(slr-sul);
    00626             mapScalarImageToLowerPixelType(sul, slr, sget, image.upperLeft(), image.accessor());
    00627             write_band( enc, image.upperLeft(),
    00628                         image.lowerRight(), image.accessor(), zero );
    00629         }
    00630     }
    00631
    00632     template < class SrcIterator, class SrcAccessor,
    00633                class MArray>
    00634     void mapVectorImageToLowerPixelType( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00635                                          MArray & array )
    00636     {
    00637         typedef typename SrcAccessor::value_type SrcValue;
    00638         typedef typename SrcValue::value_type SrcComponent;
    00639         typedef typename MArray::value_type DestValue;
    00640
    00641         FindMinMax<SrcComponent> minmax;
    00642         for(unsigned int i=0; i<sget.size(sul); ++i)
    00643         {
    00644             // FIXME dangelo - This will break with vector accessors that have a "by value" interface.
    00645             // use VectorComponentValueAccessor instead, since it should work in both cases, even
    00646             // if it might be a bit slower..
    00647             //VectorElementAccessor<SrcAccessor> band(i, sget);
    00648             VectorComponentValueAccessor<typename SrcAccessor::value_type> band(i);
    00649             inspectImage( sul, slr, band, minmax );
    00650         }
    00651         double scale = (double)NumericTraits<DestValue>::max() / (minmax.max - minmax.min) -
    00652                        (double)NumericTraits<DestValue>::min() / (minmax.max - minmax.min);
    00653 // FIXME DGSW - Original was not correct. Is this what was intended?
    00654 //        double offset = -minmax.min + NumericTraits<DestValue>::min() / scale;
    00655         double offset = (NumericTraits<DestValue>::min() / scale) - minmax.min ;
    00656         for(unsigned int i=0; i<sget.size(sul); ++i)
    00657         {
    00658             BasicImageView<DestValue> subImage = makeBasicImageView(array.bindOuter(i));
    00659             // FIXME dangelo: use VectorComponentValueAccessor
    00660             //VectorElementAccessor<SrcAccessor> band(i, sget);
    00661             VectorComponentValueAccessor<typename SrcAccessor::value_type> band(i);
    00662             transformImage( sul, slr, band, subImage.upperLeft(), subImage.accessor(),
    00663                             linearIntensityTransform( scale, offset ) );
    00664         }
    00665     }
    00666
    00667     // export vector images with conversion (if necessary)
    00668     template < class SrcIterator, class SrcAccessor, class T >
    00669     void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00670                            Encoder * enc, bool downcast, T zero)
    00671     {
    00672         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         if ( !downcast )
    00676         {
    00677             write_bands( enc, sul, slr, sget, zero );
    00678         }
    00679         else
    00680         {
    00681             // convert to unsigned char in the usual way
    00682             int w = slr.x - sul.x;
    00683             int h = slr.y - sul.y;
    00684
    00685             typedef vigra::MultiArray<3, T> MArray;
    00686             MArray array(typename MArray::difference_type(w, h, bands));
    00687
    00688             mapVectorImageToLowerPixelType(sul, slr, sget, array);
    00689
    00690             write_bands( enc, array, zero );
    00691         }
    00692     }
    00693 } // namespace detail
    00694
    00695
    00696     /*!
    00697       \brief Deprecated.
    00698
    00699         Use \ref exportImage() instead.
    00700
    00701         <b> Declaration:</b>
    00702
    00703         \code
    00704         namespace vigra {
    00705             template < class SrcIterator, class SrcAccessor >
    00706             void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00707                                             const ImageExportInfo & info )
    00708         }
    00709         \endcode
    00710     */
    00711     template < class SrcIterator, class SrcAccessor >
    00712     void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00713                                     const ImageExportInfo & info )
    00714     {
    00715         exportImage(sul, slr, sget, info);
    00716     }
    00717
    00718     /*!
    00719       \brief Deprecated.
    00720
    00721         Use \ref exportImage() instead.
    00722
    00723         <b> Declaration:</b>
    00724
    00725         \code
    00726         namespace vigra {
    00727             template < class SrcIterator, class SrcAccessor >
    00728             void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00729                                             const ImageExportInfo & info )
    00730         }
    00731         \endcode
    00732     */
    00733     template < class SrcIterator, class SrcAccessor >
    00734     void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00735                                     const ImageExportInfo & info )
    00736     {
    00737         exportImage(sul, slr, sget, info);
    00738     }
    00739
    00740     /*!
    00741       \brief Deprecated.
    00742
    00743         Use \ref exportImage() instead.
    00744
    00745         <b> Declaration:</b>
    00746
    00747         \code
    00748         namespace vigra {
    00749             template < class SrcIterator, class SrcAccessor >
    00750             void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00751                                             const ImageExportInfo & info )
    00752         }
    00753         \endcode
    00754     */
    00755     template < class SrcIterator, class SrcAccessor >
    00756     void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00757                                     const ImageExportInfo & info )
    00758     {
    00759         exportImage(sul, slr, sget, info);
    00760     }
    00761
    00762     /*!
    00763       \brief Deprecated.
    00764
    00765         Use \ref exportImage() instead.
    00766
    00767         <b> Declaration:</b>
    00768
    00769         \code
    00770         namespace vigra {
    00771             template < class SrcIterator, class SrcAccessor >
    00772             void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00773                                             const ImageExportInfo & info )
    00774         }
    00775         \endcode
    00776     */
    00777     template < class SrcIterator, class SrcAccessor >
    00778     void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00779                                     const ImageExportInfo & info )
    00780     {
    00781         exportImage(sul, slr, sget, info);
    00782     }
    00783
    00784     template < class SrcIterator, class SrcAccessor >
    00785     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00786                       const ImageExportInfo & info, VigraFalseType /*not scalar */)
    00787     {
    00788         typedef typename SrcAccessor::value_type AccessorValueType;
    00789         typedef typename AccessorValueType::value_type SrcValueType;
    00790         std::string pixeltype = info.getPixelType();
    00791         std::auto_ptr<Encoder> enc = encoder(info);
    00792         bool downcast = negotiatePixelType(enc->getFileType(),
    00793                         TypeAsString<SrcValueType>::result(), pixeltype);
    00794         enc->setPixelType(pixeltype);
    00795         if(pixeltype == "UINT8")
    00796             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, (UInt8)0);
    00797         else if(pixeltype == "INT16")
    00798             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, Int16());
    00799         else if(pixeltype == "UINT16")
    00800             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, (UInt16)0);
    00801         else if(pixeltype == "INT32")
    00802             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, Int32());
    00803         else if(pixeltype == "UINT32")
    00804             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, (UInt32)0);
    00805         else if(pixeltype == "FLOAT")
    00806             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, float());
    00807         else if(pixeltype == "DOUBLE")
    00808             detail::exportVectorImage( sul, slr, sget, enc.get(), downcast, double());
    00809         enc->close();
    00810     }
    00811
    00812     template < class SrcIterator, class SrcAccessor >
    00813     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00814                       const ImageExportInfo & info, VigraTrueType /*scalar*/ )
    00815     {
    00816         typedef typename SrcAccessor::value_type SrcValueType;
    00817         std::string pixeltype = info.getPixelType();
    00818         std::auto_ptr<Encoder> enc = encoder(info);
    00819         bool downcast = negotiatePixelType(enc->getFileType(),
    00820                            TypeAsString<SrcValueType>::result(), pixeltype);
    00821         enc->setPixelType(pixeltype);
    00822         if(pixeltype == "UINT8")
    00823             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, (UInt8)0);
    00824         else if(pixeltype == "INT16")
    00825             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, Int16());
    00826         else if(pixeltype == "UINT16")
    00827             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, (UInt16)0);
    00828         else if(pixeltype == "INT32")
    00829             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, Int32());
    00830         else if(pixeltype == "UINT32")
    00831             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, (UInt32)0);
    00832         else if(pixeltype == "FLOAT")
    00833             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, float());
    00834         else if(pixeltype == "DOUBLE")
    00835             detail::exportScalarImage( sul, slr, sget, enc.get(), downcast, double());
    00836         enc->close();
    00837     }
    00838
    00839 /********************************************************/
    00840 /*                                                      */
    00841 /*                     exportImage                      */
    00842 /*                                                      */
    00843 /********************************************************/
    00844
    00845 /** \brief Write an image, given an \ref vigra::ImageExportInfo object.
    00846
    00847     If the file format to be exported to supports the pixel type of the
    00848     source image, the pixel type will be kept (e.g. <tt>float</tt>
    00849     can be stored as TIFF without conversion, in contrast to most other
    00850     image export toolkits). Otherwise, the pixel values are transformed
    00851     to the range 0.255 and converted to <tt>unsigned char</tt>. Currently,
    00852     the following file formats are supported. The pixel types given in
    00853     brackets are those that are written without conversion:
    00854
    00855     <DL>
    00856     <DT>"BMP"<DD> Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB).
    00857     <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color (pixel types: UINT8 as gray and RGB).
    00858     <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format; compressed 24-bit color
    00859                   (pixel types: UINT8 as gray and RGB). (only available if libjpeg is installed)
    00860     <DT>"PNG"<DD> Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels).
    00861                   (only available if libpng is installed)
    00862     <DT>"PBM"<DD> Portable bitmap format (black and white).
    00863     <DT>"PGM"<DD> Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale)).
    00864     <DT>"PNM"<DD> Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB).
    00865     <DT>"PPM"<DD> Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB).
    00866     <DT>"SUN"<DD> SUN Rasterfile (pixel types: UINT8 as gray and RGB).
    00867     <DT>"TIFF"<DD> Tagged Image File Format
    00868                 (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels).
    00869                 (only available if libtiff is installed.)
    00870     <DT>"VIFF"<DD> Khoros Visualization image file
    00871         (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels).
    00872     </DL>
    00873
    00874     <b> Declarations:</b>
    00875
    00876     pass arguments explicitly:
    00877     \code
    00878     namespace vigra {
    00879         template <class SrcIterator, class SrcAccessor>
    00880         void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00881                          ImageExportInfo const & info)
    00882     }
    00883     \endcode
    00884
    00885
    00886     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00887     \code
    00888     namespace vigra {
    00889         template <class SrcIterator, class SrcAccessor>
    00890         void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00891                          ImageExportInfo const & info)
    00892     }
    00893     \endcode
    00894
    00895     <b> Usage:</b>
    00896
    00897     <b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx</a>"<br>
    00898     Namespace: vigra
    00899
    00900     \code
    00901
    00902
    00903     vigra::BRGBImage out(w, h);
    00904     ...
    00905
    00906     // write as JPEG image, using compression quality 80
    00907     vigra::exportImage(srcImageRange(out),
    00908                       vigra::ImageExportInfo("myimage.jpg").setCompression("80"));
    00909
    00910
    00911     // force it to a particular pixel type (the pixel type must be supported by the
    00912     // desired image file format, otherwise an \ref vigra::PreconditionViolation exception will be thrown)
    00913     vigra::exportImage(srcImageRange(out),
    00914                       vigra::ImageExportInfo("myINT16image.tif").setPixelType("INT16"));
    00915     \endcode
    00916
    00917     <b> Preconditions:</b>
    00918
    00919     <UL>
    00920
    00921     <LI> the image file must be writable.
    00922     <LI> the file type must be one of the supported file types.
    00923
    00924
    00925     </UL>
    00926 **/
    00927     template < class SrcIterator, class SrcAccessor >
    00928     inline
    00929     void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
    00930                       const ImageExportInfo & info )
    00931     {
    00932         typedef typename NumericTraits<typename SrcAccessor::value_type>::isScalar is_scalar;
    00933
    00934         try
    00935         {
    00936             exportImage( sul, slr, sget, info, is_scalar() );
    00937         }
    00938         catch(Encoder::TIFFCompressionException &)
    00939         {
    00940             const_cast<ImageExportInfo &>(info).setCompression("");
    00941             exportImage( sul, slr, sget, info, is_scalar() );
    00942         }
    00943     }
    00944
    00945     template < class SrcIterator, class SrcAccessor >
    00946     inline
    00947     void exportImage( triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00948                       const ImageExportInfo & info )
    00949     {
    00950         exportImage( src.first, src.second, src.third, info );
    00951     }
    00952
    00953 //@}
    00954
    00955 } // namespace vigra
    00956
    00957 #endif /* VIGRA_IMPEX_HXX */

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.5.0 (7 Dec 2006)