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.