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