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