[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/impex.hxx | ![]() |
Go to the documentation of this file.
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 2001-2002 by Gunnar Kedenburg */ 00004 /* Copyright 2012 Christoph Spiel and Ullrich Koethe */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* The VIGRA Website is */ 00008 /* http://hci.iwr.uni-heidelberg.de/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 00037 00038 /*! 00039 * \file impex.hxx 00040 * \brief image import and export functions 00041 * 00042 * This module implements functions importImage() and exportImage(). 00043 * The matching implementation for any given datatype is selected by 00044 * template meta code. 00045 * 00046 */ 00047 00048 #ifndef VIGRA_IMPEX_HXX 00049 #define VIGRA_IMPEX_HXX 00050 00051 #include "stdimage.hxx" 00052 #include "imageinfo.hxx" 00053 #include "impexbase.hxx" 00054 00055 namespace vigra 00056 { 00057 /** \addtogroup VigraImpex 00058 * @{ 00059 */ 00060 namespace detail 00061 { 00062 template <class ValueType, 00063 class ImageIterator, class ImageAccessor> 00064 void 00065 read_image_band(Decoder* decoder, 00066 ImageIterator image_iterator, ImageAccessor image_accessor) 00067 { 00068 typedef typename ImageIterator::row_iterator ImageRowIterator; 00069 00070 const unsigned width(decoder->getWidth()); 00071 const unsigned height(decoder->getHeight()); 00072 const unsigned offset(decoder->getOffset()); 00073 00074 for (unsigned y = 0U; y != height; ++y) 00075 { 00076 decoder->nextScanline(); 00077 00078 const ValueType* scanline = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0)); 00079 00080 ImageRowIterator is(image_iterator.rowIterator()); 00081 const ImageRowIterator is_end(is + width); 00082 00083 while (is != is_end) 00084 { 00085 image_accessor.set(*scanline, is); 00086 scanline += offset; 00087 ++is; 00088 } 00089 00090 ++image_iterator.y; 00091 } 00092 } 00093 00094 00095 template <class ValueType, 00096 class ImageIterator, class ImageAccessor> 00097 void 00098 read_image_bands(Decoder* decoder, 00099 ImageIterator image_iterator, ImageAccessor image_accessor) 00100 { 00101 typedef typename ImageIterator::row_iterator ImageRowIterator; 00102 00103 const unsigned width(decoder->getWidth()); 00104 const unsigned height(decoder->getHeight()); 00105 const unsigned offset(decoder->getOffset()); 00106 const unsigned accessor_size(image_accessor.size(image_iterator)); 00107 00108 // OPTIMIZATION: Specialization for the most common case 00109 // of an RGB-image, i.e. 3 channels. 00110 if (accessor_size == 3U) 00111 { 00112 const ValueType* scanline_0; 00113 const ValueType* scanline_1; 00114 const ValueType* scanline_2; 00115 00116 for (unsigned y = 0U; y != height; ++y) 00117 { 00118 decoder->nextScanline(); 00119 00120 scanline_0 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0)); 00121 scanline_1 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(1)); 00122 scanline_2 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(2)); 00123 00124 ImageRowIterator is(image_iterator.rowIterator()); 00125 const ImageRowIterator is_end(is + width); 00126 00127 while (is != is_end) 00128 { 00129 image_accessor.setComponent(*scanline_0, is, 0); 00130 image_accessor.setComponent(*scanline_1, is, 1); 00131 image_accessor.setComponent(*scanline_2, is, 2); 00132 00133 scanline_0 += offset; 00134 scanline_1 += offset; 00135 scanline_2 += offset; 00136 00137 ++is; 00138 } 00139 00140 ++image_iterator.y; 00141 } 00142 } 00143 else 00144 { 00145 std::vector<const ValueType*> scanlines(accessor_size); 00146 00147 for (unsigned y = 0U; y != height; ++y) 00148 { 00149 decoder->nextScanline(); 00150 00151 for (unsigned i = 0U; i != accessor_size; ++i) 00152 { 00153 scanlines[i] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(i)); 00154 } 00155 00156 ImageRowIterator is(image_iterator.rowIterator()); 00157 const ImageRowIterator is_end(is + width); 00158 00159 while (is != is_end) 00160 { 00161 for (unsigned i = 0U; i != accessor_size; ++i) 00162 { 00163 image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i)); 00164 scanlines[i] += offset; 00165 } 00166 ++is; 00167 } 00168 00169 ++image_iterator.y; 00170 } 00171 } 00172 } 00173 00174 00175 template <class ImageIterator, class ImageAccessor> 00176 void 00177 importImage(const ImageImportInfo& import_info, 00178 ImageIterator image_iterator, ImageAccessor image_accessor, 00179 /* isScalar? */ VigraTrueType) 00180 { 00181 VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info)); 00182 00183 switch (pixel_t_of_string(decoder->getPixelType())) 00184 { 00185 case UNSIGNED_INT_8: 00186 read_image_band<UInt8>(decoder.get(), image_iterator, image_accessor); 00187 break; 00188 case UNSIGNED_INT_16: 00189 read_image_band<UInt16>(decoder.get(), image_iterator, image_accessor); 00190 break; 00191 case UNSIGNED_INT_32: 00192 read_image_band<UInt32>(decoder.get(), image_iterator, image_accessor); 00193 break; 00194 case SIGNED_INT_16: 00195 read_image_band<Int16>(decoder.get(), image_iterator, image_accessor); 00196 break; 00197 case SIGNED_INT_32: 00198 read_image_band<Int32>(decoder.get(), image_iterator, image_accessor); 00199 break; 00200 case IEEE_FLOAT_32: 00201 read_image_band<float>(decoder.get(), image_iterator, image_accessor); 00202 break; 00203 case IEEE_FLOAT_64: 00204 read_image_band<double>(decoder.get(), image_iterator, image_accessor); 00205 break; 00206 default: 00207 vigra_fail("detail::importImage<scalar>: not reached"); 00208 } 00209 00210 decoder->close(); 00211 } 00212 00213 00214 template <class ImageIterator, class ImageAccessor> 00215 void 00216 importImage(const ImageImportInfo& import_info, 00217 ImageIterator image_iterator, ImageAccessor image_accessor, 00218 /* isScalar? */ VigraFalseType) 00219 { 00220 VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info)); 00221 00222 switch (pixel_t_of_string(decoder->getPixelType())) 00223 { 00224 case UNSIGNED_INT_8: 00225 read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor); 00226 break; 00227 case UNSIGNED_INT_16: 00228 read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor); 00229 break; 00230 case UNSIGNED_INT_32: 00231 read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor); 00232 break; 00233 case SIGNED_INT_16: 00234 read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor); 00235 break; 00236 case SIGNED_INT_32: 00237 read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor); 00238 break; 00239 case IEEE_FLOAT_32: 00240 read_image_bands<float>(decoder.get(), image_iterator, image_accessor); 00241 break; 00242 case IEEE_FLOAT_64: 00243 read_image_bands<double>(decoder.get(), image_iterator, image_accessor); 00244 break; 00245 default: 00246 vigra_fail("vigra::detail::importImage<non-scalar>: not reached"); 00247 } 00248 00249 decoder->close(); 00250 } 00251 00252 template<class ValueType, 00253 class ImageIterator, class ImageAccessor, class ImageScaler> 00254 void 00255 write_image_band(Encoder* encoder, 00256 ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, 00257 const ImageScaler& image_scaler) 00258 { 00259 typedef typename ImageIterator::row_iterator ImageRowIterator; 00260 typedef typename ImageAccessor::value_type ImageValueType; 00261 00262 typedef RequiresExplicitCast<ValueType> explicit_cast; 00263 00264 vigra_precondition(image_lower_right.x >= image_upper_left.x, 00265 "vigra::detail::write_image_band: negative width"); 00266 vigra_precondition(image_lower_right.y >= image_upper_left.y, 00267 "vigra::detail::write_image_band: negative height"); 00268 00269 const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x)); 00270 const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y)); 00271 00272 encoder->setWidth(width); 00273 encoder->setHeight(height); 00274 encoder->setNumBands(1); 00275 encoder->finalizeSettings(); 00276 00277 const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings() 00278 00279 // IMPLEMENTATION NOTE: We avoid calling the default 00280 // constructor to allow classes ImageIterator that do not 00281 // define one. 00282 ImageIterator image_iterator(image_upper_left); 00283 00284 for (unsigned y = 0U; y != height; ++y) 00285 { 00286 ValueType* scanline = static_cast<ValueType*>(encoder->currentScanlineOfBand(0)); 00287 00288 ImageRowIterator is(image_iterator.rowIterator()); 00289 const ImageRowIterator is_end(is + width); 00290 00291 while (is != is_end) 00292 { 00293 *scanline = explicit_cast::cast(image_scaler(image_accessor(is))); 00294 scanline += offset; 00295 ++is; 00296 } 00297 00298 encoder->nextScanline(); 00299 00300 ++image_iterator.y; 00301 } 00302 } 00303 00304 00305 template<class ValueType, 00306 class ImageIterator, class ImageAccessor, class ImageScaler> 00307 void 00308 write_image_bands(Encoder* encoder, 00309 ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, 00310 const ImageScaler& image_scaler) 00311 { 00312 typedef typename ImageIterator::row_iterator ImageRowIterator; 00313 typedef RequiresExplicitCast<ValueType> explicit_cast; 00314 00315 vigra_precondition(image_lower_right.x >= image_upper_left.x, 00316 "vigra::detail::write_image_bands: negative width"); 00317 vigra_precondition(image_lower_right.y >= image_upper_left.y, 00318 "vigra::detail::write_image_bands: negative height"); 00319 00320 const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x)); 00321 const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y)); 00322 const unsigned accessor_size(image_accessor.size(image_upper_left)); 00323 00324 encoder->setWidth(width); 00325 encoder->setHeight(height); 00326 encoder->setNumBands(accessor_size); 00327 encoder->finalizeSettings(); 00328 00329 const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings() 00330 00331 // IMPLEMENTATION NOTE: We avoid calling the default 00332 // constructor to allow classes ImageIterator that do not 00333 // define one. 00334 ImageIterator image_iterator(image_upper_left); 00335 00336 // OPTIMIZATION: Specialization for the most common case 00337 // of an RGB-image, i.e. 3 channels. 00338 if (accessor_size == 3U) 00339 { 00340 ValueType* scanline_0; 00341 ValueType* scanline_1; 00342 ValueType* scanline_2; 00343 00344 for (unsigned y = 0U; y != height; ++y) 00345 { 00346 scanline_0 = static_cast<ValueType*>(encoder->currentScanlineOfBand(0)); 00347 scanline_1 = static_cast<ValueType*>(encoder->currentScanlineOfBand(1)); 00348 scanline_2 = static_cast<ValueType*>(encoder->currentScanlineOfBand(2)); 00349 00350 ImageRowIterator is(image_iterator.rowIterator()); 00351 const ImageRowIterator is_end(is + width); 00352 00353 while (is != is_end) 00354 { 00355 *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0))); 00356 *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1))); 00357 *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2))); 00358 00359 scanline_0 += offset; 00360 scanline_1 += offset; 00361 scanline_2 += offset; 00362 00363 ++is; 00364 } 00365 00366 encoder->nextScanline(); 00367 00368 ++image_iterator.y; 00369 } 00370 } 00371 else 00372 { 00373 std::vector<ValueType*> scanlines(accessor_size); 00374 00375 for (unsigned y = 0U; y != height; ++y) 00376 { 00377 for (unsigned i = 0U; i != accessor_size; ++i) 00378 { 00379 scanlines[i] = static_cast<ValueType*>(encoder->currentScanlineOfBand(i)); 00380 } 00381 00382 ImageRowIterator is(image_iterator.rowIterator()); 00383 const ImageRowIterator is_end(is + width); 00384 00385 while (is != is_end) 00386 { 00387 for (unsigned i = 0U; i != accessor_size; ++i) 00388 { 00389 *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i)))); 00390 scanlines[i] += offset; 00391 } 00392 ++is; 00393 } 00394 00395 encoder->nextScanline(); 00396 00397 ++image_iterator.y; 00398 } 00399 } 00400 } 00401 00402 00403 template <class ImageIterator, class ImageAccessor> 00404 void 00405 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, 00406 const ImageExportInfo& export_info, 00407 /* isScalar? */ VigraTrueType) 00408 { 00409 typedef typename ImageAccessor::value_type ImageValueType; 00410 00411 VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info)); 00412 00413 std::string pixel_type(export_info.getPixelType()); 00414 const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type)); 00415 const pixel_t type(pixel_t_of_string(pixel_type)); 00416 00417 encoder->setPixelType(pixel_type); 00418 00419 const range_t image_source_range(find_source_value_range(export_info, 00420 image_upper_left, image_lower_right, image_accessor)); 00421 const range_t destination_range(find_destination_value_range(export_info, type)); 00422 00423 if ((downcast || export_info.hasForcedRangeMapping()) && 00424 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second)) 00425 { 00426 const linear_transform image_rescaler(image_source_range, destination_range); 00427 00428 switch (type) 00429 { 00430 case UNSIGNED_INT_8: 00431 write_image_band<UInt8>(encoder.get(), 00432 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00433 break; 00434 case UNSIGNED_INT_16: 00435 write_image_band<UInt16>(encoder.get(), 00436 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00437 break; 00438 case UNSIGNED_INT_32: 00439 write_image_band<UInt32>(encoder.get(), 00440 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00441 break; 00442 case SIGNED_INT_16: 00443 write_image_band<Int16>(encoder.get(), 00444 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00445 break; 00446 case SIGNED_INT_32: 00447 write_image_band<Int32>(encoder.get(), 00448 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00449 break; 00450 case IEEE_FLOAT_32: 00451 write_image_band<float>(encoder.get(), 00452 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00453 break; 00454 case IEEE_FLOAT_64: 00455 write_image_band<double>(encoder.get(), 00456 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00457 break; 00458 default: 00459 vigra_fail("vigra::detail::exportImage<scalar>: not reached"); 00460 } 00461 } 00462 else 00463 { 00464 switch (type) 00465 { 00466 case UNSIGNED_INT_8: 00467 write_image_band<UInt8>(encoder.get(), 00468 image_upper_left, image_lower_right, image_accessor, identity()); 00469 break; 00470 case UNSIGNED_INT_16: 00471 write_image_band<UInt16>(encoder.get(), 00472 image_upper_left, image_lower_right, image_accessor, identity()); 00473 break; 00474 case UNSIGNED_INT_32: 00475 write_image_band<UInt32>(encoder.get(), 00476 image_upper_left, image_lower_right, image_accessor, identity()); 00477 break; 00478 case SIGNED_INT_16: 00479 write_image_band<Int16>(encoder.get(), 00480 image_upper_left, image_lower_right, image_accessor, identity()); 00481 break; 00482 case SIGNED_INT_32: 00483 write_image_band<Int32>(encoder.get(), 00484 image_upper_left, image_lower_right, image_accessor, identity()); 00485 break; 00486 case IEEE_FLOAT_32: 00487 write_image_band<float>(encoder.get(), 00488 image_upper_left, image_lower_right, image_accessor, identity()); 00489 break; 00490 case IEEE_FLOAT_64: 00491 write_image_band<double>(encoder.get(), 00492 image_upper_left, image_lower_right, image_accessor, identity()); 00493 break; 00494 default: 00495 vigra_fail("vigra::detail::exportImage<scalar>: not reached"); 00496 } 00497 } 00498 00499 encoder->close(); 00500 } 00501 00502 00503 template <class ImageIterator, class ImageAccessor> 00504 void 00505 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, 00506 const ImageExportInfo& export_info, 00507 /* isScalar? */ VigraFalseType) 00508 { 00509 typedef typename ImageAccessor::value_type ImageBaseType; 00510 typedef typename ImageBaseType::value_type ImageValueType; 00511 00512 VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info)); 00513 00514 std::string pixel_type(export_info.getPixelType()); 00515 const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type)); 00516 const pixel_t type(pixel_t_of_string(pixel_type)); 00517 00518 encoder->setPixelType(pixel_type); 00519 00520 vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)), 00521 "exportImage(): file format does not support requested number of bands (color channels)"); 00522 00523 const range_t image_source_range(find_source_value_range(export_info, 00524 image_upper_left, image_lower_right, image_accessor)); 00525 const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type))); 00526 00527 if ((downcast || export_info.hasForcedRangeMapping()) && 00528 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second)) 00529 { 00530 const linear_transform image_rescaler(image_source_range, destination_range); 00531 00532 switch (type) 00533 { 00534 case UNSIGNED_INT_8: 00535 write_image_bands<UInt8>(encoder.get(), 00536 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00537 break; 00538 case UNSIGNED_INT_16: 00539 write_image_bands<UInt16>(encoder.get(), 00540 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00541 break; 00542 case UNSIGNED_INT_32: 00543 write_image_bands<UInt32>(encoder.get(), 00544 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00545 break; 00546 case SIGNED_INT_16: 00547 write_image_bands<Int16>(encoder.get(), 00548 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00549 break; 00550 case SIGNED_INT_32: 00551 write_image_bands<Int32>(encoder.get(), 00552 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00553 break; 00554 case IEEE_FLOAT_32: 00555 write_image_bands<float>(encoder.get(), 00556 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00557 break; 00558 case IEEE_FLOAT_64: 00559 write_image_bands<double>(encoder.get(), 00560 image_upper_left, image_lower_right, image_accessor, image_rescaler); 00561 break; 00562 default: 00563 vigra_fail("vigra::detail::exportImage<non-scalar>: not reached"); 00564 } 00565 } 00566 else 00567 { 00568 switch (type) 00569 { 00570 case UNSIGNED_INT_8: 00571 write_image_bands<UInt8>(encoder.get(), 00572 image_upper_left, image_lower_right, image_accessor, identity()); 00573 break; 00574 case UNSIGNED_INT_16: 00575 write_image_bands<UInt16>(encoder.get(), 00576 image_upper_left, image_lower_right, image_accessor, identity()); 00577 break; 00578 case UNSIGNED_INT_32: 00579 write_image_bands<UInt32>(encoder.get(), 00580 image_upper_left, image_lower_right, image_accessor, identity()); 00581 break; 00582 case SIGNED_INT_16: 00583 write_image_bands<Int16>(encoder.get(), 00584 image_upper_left, image_lower_right, image_accessor, identity()); 00585 break; 00586 case SIGNED_INT_32: 00587 write_image_bands<Int32>(encoder.get(), 00588 image_upper_left, image_lower_right, image_accessor, identity()); 00589 break; 00590 case IEEE_FLOAT_32: 00591 write_image_bands<float>(encoder.get(), 00592 image_upper_left, image_lower_right, image_accessor, identity()); 00593 break; 00594 case IEEE_FLOAT_64: 00595 write_image_bands<double>(encoder.get(), 00596 image_upper_left, image_lower_right, image_accessor, identity()); 00597 break; 00598 default: 00599 vigra_fail("vigra::detail::exportImage<non-scalar>: not reached"); 00600 } 00601 } 00602 00603 encoder->close(); 00604 } 00605 } // end namespace detail 00606 00607 /*! 00608 * \brief Read the image specified by the given \ref 00609 * vigra::ImageImportInfo object. 00610 * 00611 * <B>Declarations</B> 00612 * 00613 * Pass arguments explicitly: 00614 * \code 00615 * namespace vigra { 00616 * template <class ImageIterator, class Accessor> 00617 * void 00618 * importImage(const ImageImportInfo& importInfo, 00619 * ImageIterator imageIterator, Accessor imageAccessor) 00620 * } 00621 * \endcode 00622 * 00623 * Use argument objects in conjunction with \ref ArgumentObjectFactories : 00624 * \code 00625 * namespace vigra { 00626 * template <class ImageIterator, class Accessor> 00627 * inline void 00628 * importImage(const ImageImportInfo& importInfo, 00629 * const pair<ImageIterator, Accessor>& image) 00630 * } 00631 * \endcode 00632 * 00633 * <B>Usage</B> 00634 * 00635 * <B>\#include <vigra/impex.hxx></B> 00636 * 00637 * Namespace: vigra 00638 * 00639 * \code 00640 * ImageImportInfo info("myimage.gif"); 00641 * 00642 * if (info.isGrayscale()) 00643 * { 00644 * // create byte image of appropriate size 00645 * BImage image(info.width(), info.height()); 00646 * 00647 * importImage(info, destImage(image)); 00648 * ... 00649 * } 00650 * else 00651 * { 00652 * // create byte RGB image of appropriate size 00653 * BRGBImage image(info.width(), info.height()); 00654 * 00655 * importImage(info, destImage(image)); 00656 * ... 00657 * } 00658 * \endcode 00659 * 00660 * <B>Preconditions</B> 00661 * 00662 * - The image file must be readable and 00663 * - the file type must be one of the following: 00664 * 00665 * | Type | Extension | Name | Support Library | 00666 * |------|-----------|------------------------------------------------------------|-----------------| 00667 * | BMP | bmp | Microsoft Windows bitmap image file | | 00668 * | EXR | exr | OpenEXR high dynamic range image format | libopenexr | 00669 * | GIF | gif | CompuServe graphics interchange format, 8-bit color | | 00670 * | HDR | hdr | Radiance RGBE high dynamic range image format | libexr? | 00671 * | JPEG | jpg, jpeg | Joint Photographic Experts Group JFIF format, 24-bit color | libjpeg | 00672 * | PBM | pbm | Portable bitmap format (black and white) | | 00673 * | PGM | pgm | Portable graymap format (gray scale) | | 00674 * | PNG | png | Portable Network Graphic | libpng | 00675 * | PNM | pnm | Portable anymap | | 00676 * | PPM | ppm | Portable pixmap format (color) | | 00677 * | SUN | ras | SUN Rasterfile | | 00678 * | TIFF | tif, tiff | Tagged Image File Format | libtiff | 00679 * | VIFF | xv | Khoros Visualization image file | | 00680 */ 00681 doxygen_overloaded_function(template <...> inline void importImage) 00682 00683 00684 template <class ImageIterator, class ImageAccessor> 00685 inline void 00686 importImage(const ImageImportInfo& import_info, 00687 ImageIterator image_iterator, ImageAccessor image_accessor) 00688 { 00689 typedef typename ImageAccessor::value_type ImageValueType; 00690 typedef typename NumericTraits<ImageValueType>::isScalar is_scalar; 00691 00692 detail::importImage(import_info, 00693 image_iterator, image_accessor, 00694 is_scalar()); 00695 } 00696 00697 00698 template <class ImageIterator, class ImageAccessor> 00699 inline void 00700 importImage(const ImageImportInfo& import_info, 00701 const vigra::pair<ImageIterator, ImageAccessor>& image) 00702 { 00703 importImage(import_info, 00704 image.first, image.second); 00705 } 00706 00707 /*! 00708 * \brief Write an image given a \ref vigra::ImageExportInfo object. 00709 * 00710 * If the file format to be exported to supports the pixel type of 00711 * the source image, the pixel type will be kept 00712 * (e.g. <tt>float</tt> can be stored as TIFF without conversion, 00713 * in contrast to most other image export toolkits). Otherwise, 00714 * the pixel values are transformed to the range 0..255 and 00715 * converted to <tt>unsigned char</tt>. Currently, the following 00716 * file formats are supported. The pixel types given in brackets 00717 * are those that are written without conversion: 00718 * - BMP: Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB); 00719 * - GIF: CompuServe graphics interchange format, 8-bit color (pixel types: UINT8 as gray and RGB); 00720 * - JPEG: Joint Photographic Experts Group JFIF format, compressed 24-bit color 00721 * (pixel types: UINT8 as gray and RGB), only available if libjpeg is installed; 00722 * - PNG: Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels), 00723 * only available if libpng is installed; 00724 * - PBM: Portable bitmap format (black and white); 00725 * - PGM: Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale); 00726 * - PNM: Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB); 00727 * - PPM: Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB); 00728 * - SUN: SUN Rasterfile (pixel types: UINT8 as gray and RGB); 00729 * - TIFF: Tagged Image File Format 00730 * (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels), 00731 * only available if libtiff is installed; 00732 * - VIFF: Khoros Visualization image file 00733 * (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels); 00734 * 00735 * <B>Declarations</B> 00736 * 00737 * Pass arguments explicitly: 00738 * \code 00739 * namespace vigra { 00740 * template <class ImageIterator, class ImageAccessor> 00741 * void 00742 * exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor, 00743 * const ImageExportInfo& exportInfo) 00744 * } 00745 * \endcode 00746 * 00747 * Use argument objects in conjunction with \ref ArgumentObjectFactories : 00748 * \code 00749 * namespace vigra { 00750 * template <class ImageIterator, class ImageAccessor> 00751 * void exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor, 00752 * const ImageExportInfo& exportInfo) 00753 * } 00754 * \endcode 00755 * 00756 * <B>Usage</B> 00757 * 00758 * <B>\#include <vigra/impex.hxx></B> 00759 * 00760 * Namespace: vigra 00761 * \code 00762 * BRGBImage image(width, height); 00763 * ... 00764 * 00765 * // write as JPEG image, using compression quality 80 00766 * exportImage(srcImageRange(image), 00767 * ImageExportInfo("my-image.jpg").setCompression("80")); 00768 * 00769 * // Force it to a particular pixel type. The pixel type must be supported by the 00770 * // desired image file format, otherwise an \ref vigra::PreconditionViolation 00771 * // exception will be thrown. 00772 * exportImage(srcImageRange(image), 00773 * ImageExportInfo("my-INT16-image.tif").setPixelType("INT16")); 00774 * \endcode 00775 * 00776 * <B>Preconditions</B> 00777 * 00778 * - The image file must be writable and 00779 * - the file type must be one of the supported file types. 00780 */ 00781 doxygen_overloaded_function(template <...> inline void exportImage) 00782 00783 00784 template <class ImageIterator, class ImageAccessor> 00785 inline void 00786 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, 00787 const ImageExportInfo& export_info) 00788 { 00789 typedef typename ImageAccessor::value_type ImageValueType; 00790 typedef typename NumericTraits<ImageValueType>::isScalar is_scalar; 00791 00792 try 00793 { 00794 detail::exportImage(image_upper_left, image_lower_right, image_accessor, 00795 export_info, 00796 is_scalar()); 00797 } 00798 catch (Encoder::TIFFCompressionException&) 00799 { 00800 ImageExportInfo info(export_info); 00801 00802 info.setCompression(""); 00803 detail::exportImage(image_upper_left, image_lower_right, image_accessor, 00804 info, 00805 is_scalar()); 00806 } 00807 } 00808 00809 00810 template <class ImageIterator, class ImageAccessor> 00811 inline void 00812 exportImage(const vigra::triple<ImageIterator, ImageIterator, ImageAccessor>& image, 00813 const ImageExportInfo& export_info) 00814 { 00815 exportImage(image.first, image.second, image.third, 00816 export_info); 00817 } 00818 00819 /** @} */ 00820 00821 } // end namespace vigra 00822 00823 #endif // VIGRA_IMPEX_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|