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

details vigra/impex.hxx VIGRA

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)