[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/impex.hxx VIGRA

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)