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