48 #ifndef VIGRA_IMPEX_HXX 
   49 #define VIGRA_IMPEX_HXX 
   51 #include "stdimage.hxx" 
   52 #include "imageinfo.hxx" 
   53 #include "impexbase.hxx" 
   54 #include "multi_shape.hxx" 
   63         template <
class ValueType,
 
   64                   class ImageIterator, 
class ImageAccessor>
 
   66         read_image_band(Decoder* decoder,
 
   67                         ImageIterator image_iterator, ImageAccessor image_accessor)
 
   71             const unsigned width(decoder->getWidth());
 
   72             const unsigned height(decoder->getHeight());
 
   73             const unsigned offset(decoder->getOffset());
 
   75             for (
unsigned y = 0U; y != height; ++y)
 
   77                 decoder->nextScanline();
 
   79                 const ValueType* scanline = 
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(0));
 
   81                 ImageRowIterator is(image_iterator.rowIterator());
 
   82                 const ImageRowIterator is_end(is + width);
 
   86                     image_accessor.set(*scanline, is);
 
   96         template <
class ValueType,
 
   97                   class ImageIterator, 
class ImageAccessor>
 
   99         read_image_bands(Decoder* decoder,
 
  100                          ImageIterator image_iterator, ImageAccessor image_accessor)
 
  104             const unsigned width(decoder->getWidth());
 
  105             const unsigned height(decoder->getHeight());
 
  106             const unsigned bands(decoder->getNumBands());
 
  107             const unsigned offset(decoder->getOffset());
 
  108             const unsigned accessor_size(image_accessor.size(image_iterator));
 
  112             if (accessor_size == 3U)
 
  114                 const ValueType* scanline_0;
 
  115                 const ValueType* scanline_1;
 
  116                 const ValueType* scanline_2;
 
  118                 for (
unsigned y = 0U; y != height; ++y)
 
  120                     decoder->nextScanline();
 
  122                     scanline_0 = 
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(0));
 
  126                         scanline_1 = scanline_0;
 
  127                         scanline_2 = scanline_0;
 
  131                         scanline_1 = 
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(1));
 
  132                         scanline_2 = 
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(2));
 
  135                     ImageRowIterator is(image_iterator.rowIterator());
 
  136                     const ImageRowIterator is_end(is + width);
 
  140                         image_accessor.setComponent(*scanline_0, is, 0);
 
  141                         image_accessor.setComponent(*scanline_1, is, 1);
 
  142                         image_accessor.setComponent(*scanline_2, is, 2);
 
  144                         scanline_0 += offset;
 
  145                         scanline_1 += offset;
 
  146                         scanline_2 += offset;
 
  156                 std::vector<const ValueType*> scanlines(accessor_size);
 
  158                 for (
unsigned y = 0U; y != height; ++y)
 
  160                     decoder->nextScanline();
 
  162                     scanlines[0] = 
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(0));
 
  166                         for (
unsigned i = 1U; i != accessor_size; ++i)
 
  168                             scanlines[i] = scanlines[0];
 
  173                         for (
unsigned i = 1U; i != accessor_size; ++i)
 
  175                             scanlines[i] = 
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(i));
 
  179                     ImageRowIterator is(image_iterator.rowIterator());
 
  180                     const ImageRowIterator is_end(is + width);
 
  184                         for (
unsigned i = 0U; i != accessor_size; ++i)
 
  186                             image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i));
 
  187                             scanlines[i] += offset;
 
  198         template <
class ImageIterator, 
class ImageAccessor>
 
  201                     ImageIterator image_iterator, ImageAccessor image_accessor,
 
  204             VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
 
  206             switch (pixel_t_of_string(decoder->getPixelType()))
 
  209                 read_image_band<UInt8>(decoder.get(), image_iterator, image_accessor);
 
  211             case UNSIGNED_INT_16:
 
  212                 read_image_band<UInt16>(decoder.get(), image_iterator, image_accessor);
 
  214             case UNSIGNED_INT_32:
 
  215                 read_image_band<UInt32>(decoder.get(), image_iterator, image_accessor);
 
  218                 read_image_band<Int16>(decoder.get(), image_iterator, image_accessor);
 
  221                 read_image_band<Int32>(decoder.get(), image_iterator, image_accessor);
 
  224                 read_image_band<float>(decoder.get(), image_iterator, image_accessor);
 
  227                 read_image_band<double>(decoder.get(), image_iterator, image_accessor);
 
  230                 vigra_fail(
"detail::importImage<scalar>: not reached");
 
  237         template <
class ImageIterator, 
class ImageAccessor>
 
  240                     ImageIterator image_iterator, ImageAccessor image_accessor,
 
  243             vigra_precondition((static_cast<unsigned int>(import_info.numBands())
 
  244                                 == image_accessor.size(image_iterator)) ||
 
  245                                import_info.numBands() == 1,
 
  246                 "importImage(): Number of channels in input and destination image don't match.");
 
  248             VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
 
  250             switch (pixel_t_of_string(decoder->getPixelType()))
 
  253                 read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor);
 
  255             case UNSIGNED_INT_16:
 
  256                 read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor);
 
  258             case UNSIGNED_INT_32:
 
  259                 read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor);
 
  262                 read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor);
 
  265                 read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor);
 
  268                 read_image_bands<float>(decoder.get(), image_iterator, image_accessor);
 
  271                 read_image_bands<double>(decoder.get(), image_iterator, image_accessor);
 
  274                 vigra_fail(
"vigra::detail::importImage<non-scalar>: not reached");
 
  280         template<
class ValueType,
 
  281                  class ImageIterator, 
class ImageAccessor, 
class ImageScaler>
 
  283         write_image_band(Encoder* encoder,
 
  284                          ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
 
  285                          const ImageScaler& image_scaler)
 
  289             typedef RequiresExplicitCast<ValueType> explicit_cast;
 
  291             vigra_precondition(image_lower_right.x >= image_upper_left.x,
 
  292                                "vigra::detail::write_image_band: negative width");
 
  293             vigra_precondition(image_lower_right.y >= image_upper_left.y,
 
  294                                "vigra::detail::write_image_band: negative height");
 
  296             const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
 
  297             const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
 
  299             encoder->setWidth(width);
 
  300             encoder->setHeight(height);
 
  301             encoder->setNumBands(1);
 
  302             encoder->finalizeSettings();
 
  304             const unsigned offset(encoder->getOffset()); 
 
  309             ImageIterator image_iterator(image_upper_left);
 
  311             for (
unsigned y = 0U; y != height; ++y)
 
  313                 ValueType* scanline = 
static_cast<ValueType*
>(encoder->currentScanlineOfBand(0));
 
  315                 ImageRowIterator is(image_iterator.rowIterator());
 
  316                 const ImageRowIterator is_end(is + width);
 
  320                     *scanline = explicit_cast::cast(image_scaler(image_accessor(is)));
 
  325                 encoder->nextScanline();
 
  332         template<
class ValueType,
 
  333                  class ImageIterator, 
class ImageAccessor, 
class ImageScaler>
 
  335         write_image_bands(Encoder* encoder,
 
  336                           ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
 
  337                           const ImageScaler& image_scaler)
 
  340             typedef RequiresExplicitCast<ValueType> explicit_cast;
 
  342             vigra_precondition(image_lower_right.x >= image_upper_left.x,
 
  343                                "vigra::detail::write_image_bands: negative width");
 
  344             vigra_precondition(image_lower_right.y >= image_upper_left.y,
 
  345                                "vigra::detail::write_image_bands: negative height");
 
  347             const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
 
  348             const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
 
  349             const unsigned accessor_size(image_accessor.size(image_upper_left));
 
  351             encoder->setWidth(width);
 
  352             encoder->setHeight(height);
 
  353             encoder->setNumBands(accessor_size);
 
  354             encoder->finalizeSettings();
 
  356             const unsigned offset(encoder->getOffset()); 
 
  361             ImageIterator image_iterator(image_upper_left);
 
  365             if (accessor_size == 3U)
 
  367                 ValueType* scanline_0;
 
  368                 ValueType* scanline_1;
 
  369                 ValueType* scanline_2;
 
  371                 for (
unsigned y = 0U; y != height; ++y)
 
  373                     scanline_0 = 
static_cast<ValueType*
>(encoder->currentScanlineOfBand(0));
 
  374                     scanline_1 = 
static_cast<ValueType*
>(encoder->currentScanlineOfBand(1));
 
  375                     scanline_2 = 
static_cast<ValueType*
>(encoder->currentScanlineOfBand(2));
 
  377                     ImageRowIterator is(image_iterator.rowIterator());
 
  378                     const ImageRowIterator is_end(is + width);
 
  382                         *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
 
  383                         *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
 
  384                         *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
 
  386                         scanline_0 += offset;
 
  387                         scanline_1 += offset;
 
  388                         scanline_2 += offset;
 
  393                     encoder->nextScanline();
 
  400                 std::vector<ValueType*> scanlines(accessor_size);
 
  402                 for (
unsigned y = 0U; y != height; ++y)
 
  404                     for (
unsigned i = 0U; i != accessor_size; ++i)
 
  406                         scanlines[i] = 
static_cast<ValueType*
>(encoder->currentScanlineOfBand(i));
 
  409                     ImageRowIterator is(image_iterator.rowIterator());
 
  410                     const ImageRowIterator is_end(is + width);
 
  414                         for (
unsigned i = 0U; i != accessor_size; ++i)
 
  416                             *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
 
  417                             scanlines[i] += offset;
 
  422                     encoder->nextScanline();
 
  430         template <
class ImageIterator, 
class ImageAccessor>
 
  432         exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
 
  433                     const ImageExportInfo& export_info,
 
  436             typedef typename ImageAccessor::value_type ImageValueType;
 
  438             VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
 
  440             std::string pixel_type(export_info.getPixelType());
 
  441             const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
 
  442             const pixel_t type(pixel_t_of_string(pixel_type));
 
  444             encoder->setPixelType(pixel_type);
 
  446             const range_t image_source_range(find_source_value_range(export_info,
 
  447                                                                      image_upper_left, image_lower_right, image_accessor));
 
  448             const range_t destination_range(find_destination_value_range(export_info, type));
 
  450             if ((downcast || export_info.hasForcedRangeMapping()) &&
 
  451                 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
 
  453                 const linear_transform image_rescaler(image_source_range, destination_range);
 
  458                     write_image_band<UInt8>(encoder.get(),
 
  459                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  461                 case UNSIGNED_INT_16:
 
  462                     write_image_band<UInt16>(encoder.get(),
 
  463                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  465                 case UNSIGNED_INT_32:
 
  466                     write_image_band<UInt32>(encoder.get(),
 
  467                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  470                     write_image_band<Int16>(encoder.get(),
 
  471                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  474                     write_image_band<Int32>(encoder.get(),
 
  475                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  478                     write_image_band<float>(encoder.get(),
 
  479                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  482                     write_image_band<double>(encoder.get(),
 
  483                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  486                     vigra_fail(
"vigra::detail::exportImage<scalar>: not reached");
 
  494                     write_image_band<UInt8>(encoder.get(),
 
  495                                             image_upper_left, image_lower_right, image_accessor, identity());
 
  497                 case UNSIGNED_INT_16:
 
  498                     write_image_band<UInt16>(encoder.get(),
 
  499                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  501                 case UNSIGNED_INT_32:
 
  502                     write_image_band<UInt32>(encoder.get(),
 
  503                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  506                     write_image_band<Int16>(encoder.get(),
 
  507                                             image_upper_left, image_lower_right, image_accessor, identity());
 
  510                     write_image_band<Int32>(encoder.get(),
 
  511                                             image_upper_left, image_lower_right, image_accessor, identity());
 
  514                     write_image_band<float>(encoder.get(),
 
  515                                             image_upper_left, image_lower_right, image_accessor, identity());
 
  518                     write_image_band<double>(encoder.get(),
 
  519                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  522                     vigra_fail(
"vigra::detail::exportImage<scalar>: not reached");
 
  530         template <
class ImageIterator, 
class ImageAccessor>
 
  532         exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
 
  533                     const ImageExportInfo& export_info,
 
  536             typedef typename ImageAccessor::value_type ImageBaseType;
 
  537             typedef typename ImageBaseType::value_type ImageValueType;
 
  539             VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
 
  541             std::string pixel_type(export_info.getPixelType());
 
  542             const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
 
  543             const pixel_t type(pixel_t_of_string(pixel_type));
 
  545             encoder->setPixelType(pixel_type);
 
  547             vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
 
  548                                "exportImage(): file format does not support requested number of bands (color channels)");
 
  550             const range_t image_source_range(find_source_value_range(export_info,
 
  551                                                                      image_upper_left, image_lower_right, image_accessor));
 
  552             const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
 
  554             if ((downcast || export_info.hasForcedRangeMapping()) &&
 
  555                 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
 
  557                 const linear_transform image_rescaler(image_source_range, destination_range);
 
  562                     write_image_bands<UInt8>(encoder.get(),
 
  563                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  565                 case UNSIGNED_INT_16:
 
  566                     write_image_bands<UInt16>(encoder.get(),
 
  567                                               image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  569                 case UNSIGNED_INT_32:
 
  570                     write_image_bands<UInt32>(encoder.get(),
 
  571                                               image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  574                     write_image_bands<Int16>(encoder.get(),
 
  575                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  578                     write_image_bands<Int32>(encoder.get(),
 
  579                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  582                     write_image_bands<float>(encoder.get(),
 
  583                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  586                     write_image_bands<double>(encoder.get(),
 
  587                                               image_upper_left, image_lower_right, image_accessor, image_rescaler);
 
  590                     vigra_fail(
"vigra::detail::exportImage<non-scalar>: not reached");
 
  598                     write_image_bands<UInt8>(encoder.get(),
 
  599                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  601                 case UNSIGNED_INT_16:
 
  602                     write_image_bands<UInt16>(encoder.get(),
 
  603                                               image_upper_left, image_lower_right, image_accessor, identity());
 
  605                 case UNSIGNED_INT_32:
 
  606                     write_image_bands<UInt32>(encoder.get(),
 
  607                                               image_upper_left, image_lower_right, image_accessor, identity());
 
  610                     write_image_bands<Int16>(encoder.get(),
 
  611                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  614                     write_image_bands<Int32>(encoder.get(),
 
  615                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  618                     write_image_bands<float>(encoder.get(),
 
  619                                              image_upper_left, image_lower_right, image_accessor, identity());
 
  622                     write_image_bands<double>(encoder.get(),
 
  623                                               image_upper_left, image_lower_right, image_accessor, identity());
 
  626                     vigra_fail(
"vigra::detail::exportImage<non-scalar>: not reached");
 
  789     template <
class ImageIterator, 
class ImageAccessor>
 
  792                 ImageIterator image_iterator, ImageAccessor image_accessor)
 
  794         typedef typename ImageAccessor::value_type ImageValueType;
 
  795         typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
 
  797         detail::importImage(import_info,
 
  798                     image_iterator, image_accessor,
 
  803     template <
class ImageIterator, 
class ImageAccessor>
 
  806                 pair<ImageIterator, ImageAccessor> image)
 
  809                     image.first, image.second);
 
  812     template <
class T, 
class S>
 
  815                 MultiArrayView<2, T, S> image)
 
  817         vigra_precondition(import_info.shape() == image.shape(),
 
  818             "importImage(): shape mismatch between input and output.");
 
  822     template <
class T, 
class A>
 
  825                 MultiArray<2, T, A> & image)
 
  827         ImageImportInfo info(name);
 
  828         image.reshape(info.shape());
 
  832     template <
class T, 
class A>
 
  835                 MultiArray<2, T, A> & image)
 
  963     template <
class ImageIterator, 
class ImageAccessor>
 
  965     exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
 
  966                 const ImageExportInfo& export_info)
 
  968         typedef typename ImageAccessor::value_type ImageValueType;
 
  969         typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
 
  973             detail::exportImage(image_upper_left, image_lower_right, image_accessor,
 
  977         catch (Encoder::TIFFCompressionException&)
 
  979             ImageExportInfo info(export_info);
 
  981             info.setCompression(
"");
 
  982             detail::exportImage(image_upper_left, image_lower_right, image_accessor,
 
  988     template <
class ImageIterator, 
class ImageAccessor>
 
  990     exportImage(triple<ImageIterator, ImageIterator, ImageAccessor> image,
 
  991                 ImageExportInfo 
const & export_info)
 
  993         exportImage(image.first, image.second, image.third,
 
  997     template <
class T, 
class S>
 
 1000                 ImageExportInfo 
const & export_info)
 
 1005     template <
class T, 
class S>
 
 1007     exportImage(MultiArrayView<2, T, S> 
const & image,
 
 1010         ImageExportInfo export_info(name);
 
 1014     template <
class T, 
class S>
 
 1016     exportImage(MultiArrayView<2, T, S> 
const & image,
 
 1017                 std::string 
const & name)
 
 1019         ImageExportInfo export_info(name.c_str());
 
 1027 #endif // VIGRA_IMPEX_HXX 
RowIteratorSelector::res row_iterator
Definition: imageiterator.hxx:605
void exportImage(...)
Write an image to a file. 
void importImage(...)
Read an image from a file. 
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.