[ 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) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)