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>
200 importImage(
const ImageImportInfo& import_info,
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>
239 importImage(
const ImageImportInfo& import_info,
240 ImageIterator image_iterator, ImageAccessor image_accessor,
243 vigra_precondition(import_info.numBands() == image_accessor.size(image_iterator) ||
244 import_info.numBands() == 1,
245 "importImage(): Number of channels in input and destination image don't match.");
247 VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
249 switch (pixel_t_of_string(decoder->getPixelType()))
252 read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor);
254 case UNSIGNED_INT_16:
255 read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor);
257 case UNSIGNED_INT_32:
258 read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor);
261 read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor);
264 read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor);
267 read_image_bands<float>(decoder.get(), image_iterator, image_accessor);
270 read_image_bands<double>(decoder.get(), image_iterator, image_accessor);
273 vigra_fail(
"vigra::detail::importImage<non-scalar>: not reached");
279 template<
class ValueType,
280 class ImageIterator,
class ImageAccessor,
class ImageScaler>
282 write_image_band(Encoder* encoder,
283 ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
284 const ImageScaler& image_scaler)
288 typedef RequiresExplicitCast<ValueType> explicit_cast;
290 vigra_precondition(image_lower_right.x >= image_upper_left.x,
291 "vigra::detail::write_image_band: negative width");
292 vigra_precondition(image_lower_right.y >= image_upper_left.y,
293 "vigra::detail::write_image_band: negative height");
295 const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
296 const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
298 encoder->setWidth(width);
299 encoder->setHeight(height);
300 encoder->setNumBands(1);
301 encoder->finalizeSettings();
303 const unsigned offset(encoder->getOffset());
308 ImageIterator image_iterator(image_upper_left);
310 for (
unsigned y = 0U; y != height; ++y)
312 ValueType* scanline =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(0));
314 ImageRowIterator is(image_iterator.rowIterator());
315 const ImageRowIterator is_end(is + width);
319 *scanline = explicit_cast::cast(image_scaler(image_accessor(is)));
324 encoder->nextScanline();
331 template<
class ValueType,
332 class ImageIterator,
class ImageAccessor,
class ImageScaler>
334 write_image_bands(Encoder* encoder,
335 ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
336 const ImageScaler& image_scaler)
339 typedef RequiresExplicitCast<ValueType> explicit_cast;
341 vigra_precondition(image_lower_right.x >= image_upper_left.x,
342 "vigra::detail::write_image_bands: negative width");
343 vigra_precondition(image_lower_right.y >= image_upper_left.y,
344 "vigra::detail::write_image_bands: negative height");
346 const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
347 const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
348 const unsigned accessor_size(image_accessor.size(image_upper_left));
350 encoder->setWidth(width);
351 encoder->setHeight(height);
352 encoder->setNumBands(accessor_size);
353 encoder->finalizeSettings();
355 const unsigned offset(encoder->getOffset());
360 ImageIterator image_iterator(image_upper_left);
364 if (accessor_size == 3U)
366 ValueType* scanline_0;
367 ValueType* scanline_1;
368 ValueType* scanline_2;
370 for (
unsigned y = 0U; y != height; ++y)
372 scanline_0 =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(0));
373 scanline_1 =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(1));
374 scanline_2 =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(2));
376 ImageRowIterator is(image_iterator.rowIterator());
377 const ImageRowIterator is_end(is + width);
381 *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
382 *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
383 *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
385 scanline_0 += offset;
386 scanline_1 += offset;
387 scanline_2 += offset;
392 encoder->nextScanline();
399 std::vector<ValueType*> scanlines(accessor_size);
401 for (
unsigned y = 0U; y != height; ++y)
403 for (
unsigned i = 0U; i != accessor_size; ++i)
405 scanlines[i] =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(i));
408 ImageRowIterator is(image_iterator.rowIterator());
409 const ImageRowIterator is_end(is + width);
413 for (
unsigned i = 0U; i != accessor_size; ++i)
415 *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
416 scanlines[i] += offset;
421 encoder->nextScanline();
429 template <
class ImageIterator,
class ImageAccessor>
431 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
432 const ImageExportInfo& export_info,
435 typedef typename ImageAccessor::value_type ImageValueType;
437 VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
439 std::string pixel_type(export_info.getPixelType());
440 const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
441 const pixel_t type(pixel_t_of_string(pixel_type));
443 encoder->setPixelType(pixel_type);
445 const range_t image_source_range(find_source_value_range(export_info,
446 image_upper_left, image_lower_right, image_accessor));
447 const range_t destination_range(find_destination_value_range(export_info, type));
449 if ((downcast || export_info.hasForcedRangeMapping()) &&
450 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
452 const linear_transform image_rescaler(image_source_range, destination_range);
457 write_image_band<UInt8>(encoder.get(),
458 image_upper_left, image_lower_right, image_accessor, image_rescaler);
460 case UNSIGNED_INT_16:
461 write_image_band<UInt16>(encoder.get(),
462 image_upper_left, image_lower_right, image_accessor, image_rescaler);
464 case UNSIGNED_INT_32:
465 write_image_band<UInt32>(encoder.get(),
466 image_upper_left, image_lower_right, image_accessor, image_rescaler);
469 write_image_band<Int16>(encoder.get(),
470 image_upper_left, image_lower_right, image_accessor, image_rescaler);
473 write_image_band<Int32>(encoder.get(),
474 image_upper_left, image_lower_right, image_accessor, image_rescaler);
477 write_image_band<float>(encoder.get(),
478 image_upper_left, image_lower_right, image_accessor, image_rescaler);
481 write_image_band<double>(encoder.get(),
482 image_upper_left, image_lower_right, image_accessor, image_rescaler);
485 vigra_fail(
"vigra::detail::exportImage<scalar>: not reached");
493 write_image_band<UInt8>(encoder.get(),
494 image_upper_left, image_lower_right, image_accessor, identity());
496 case UNSIGNED_INT_16:
497 write_image_band<UInt16>(encoder.get(),
498 image_upper_left, image_lower_right, image_accessor, identity());
500 case UNSIGNED_INT_32:
501 write_image_band<UInt32>(encoder.get(),
502 image_upper_left, image_lower_right, image_accessor, identity());
505 write_image_band<Int16>(encoder.get(),
506 image_upper_left, image_lower_right, image_accessor, identity());
509 write_image_band<Int32>(encoder.get(),
510 image_upper_left, image_lower_right, image_accessor, identity());
513 write_image_band<float>(encoder.get(),
514 image_upper_left, image_lower_right, image_accessor, identity());
517 write_image_band<double>(encoder.get(),
518 image_upper_left, image_lower_right, image_accessor, identity());
521 vigra_fail(
"vigra::detail::exportImage<scalar>: not reached");
529 template <
class ImageIterator,
class ImageAccessor>
531 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
532 const ImageExportInfo& export_info,
535 typedef typename ImageAccessor::value_type ImageBaseType;
536 typedef typename ImageBaseType::value_type ImageValueType;
538 VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
540 std::string pixel_type(export_info.getPixelType());
541 const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
542 const pixel_t type(pixel_t_of_string(pixel_type));
544 encoder->setPixelType(pixel_type);
546 vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
547 "exportImage(): file format does not support requested number of bands (color channels)");
549 const range_t image_source_range(find_source_value_range(export_info,
550 image_upper_left, image_lower_right, image_accessor));
551 const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
553 if ((downcast || export_info.hasForcedRangeMapping()) &&
554 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
556 const linear_transform image_rescaler(image_source_range, destination_range);
561 write_image_bands<UInt8>(encoder.get(),
562 image_upper_left, image_lower_right, image_accessor, image_rescaler);
564 case UNSIGNED_INT_16:
565 write_image_bands<UInt16>(encoder.get(),
566 image_upper_left, image_lower_right, image_accessor, image_rescaler);
568 case UNSIGNED_INT_32:
569 write_image_bands<UInt32>(encoder.get(),
570 image_upper_left, image_lower_right, image_accessor, image_rescaler);
573 write_image_bands<Int16>(encoder.get(),
574 image_upper_left, image_lower_right, image_accessor, image_rescaler);
577 write_image_bands<Int32>(encoder.get(),
578 image_upper_left, image_lower_right, image_accessor, image_rescaler);
581 write_image_bands<float>(encoder.get(),
582 image_upper_left, image_lower_right, image_accessor, image_rescaler);
585 write_image_bands<double>(encoder.get(),
586 image_upper_left, image_lower_right, image_accessor, image_rescaler);
589 vigra_fail(
"vigra::detail::exportImage<non-scalar>: not reached");
597 write_image_bands<UInt8>(encoder.get(),
598 image_upper_left, image_lower_right, image_accessor, identity());
600 case UNSIGNED_INT_16:
601 write_image_bands<UInt16>(encoder.get(),
602 image_upper_left, image_lower_right, image_accessor, identity());
604 case UNSIGNED_INT_32:
605 write_image_bands<UInt32>(encoder.get(),
606 image_upper_left, image_lower_right, image_accessor, identity());
609 write_image_bands<Int16>(encoder.get(),
610 image_upper_left, image_lower_right, image_accessor, identity());
613 write_image_bands<Int32>(encoder.get(),
614 image_upper_left, image_lower_right, image_accessor, identity());
617 write_image_bands<float>(encoder.get(),
618 image_upper_left, image_lower_right, image_accessor, identity());
621 write_image_bands<double>(encoder.get(),
622 image_upper_left, image_lower_right, image_accessor, identity());
625 vigra_fail(
"vigra::detail::exportImage<non-scalar>: not reached");
785 doxygen_overloaded_function(template <...>
void importImage)
788 template <
class ImageIterator,
class ImageAccessor>
790 importImage(
const ImageImportInfo& import_info,
791 ImageIterator image_iterator, ImageAccessor image_accessor)
793 typedef typename ImageAccessor::value_type ImageValueType;
794 typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
796 detail::importImage(import_info,
797 image_iterator, image_accessor,
802 template <
class ImageIterator,
class ImageAccessor>
804 importImage(ImageImportInfo
const & import_info,
805 pair<ImageIterator, ImageAccessor> image)
807 importImage(import_info,
808 image.first, image.second);
811 template <
class T,
class S>
813 importImage(ImageImportInfo
const & import_info,
814 MultiArrayView<2, T, S> image)
816 vigra_precondition(import_info.shape() == image.shape(),
817 "importImage(): shape mismatch between input and output.");
818 importImage(import_info, destImage(image));
821 template <
class T,
class A>
823 importImage(
char const * name,
824 MultiArray<2, T, A> & image)
826 ImageImportInfo info(name);
827 image.reshape(info.shape());
828 importImage(info, destImage(image));
831 template <
class T,
class A>
833 importImage(std::string
const & name,
834 MultiArray<2, T, A> & image)
836 importImage(name.c_str(), image);
959 doxygen_overloaded_function(template <...>
void exportImage)
962 template <
class ImageIterator,
class ImageAccessor>
964 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
965 const ImageExportInfo& export_info)
967 typedef typename ImageAccessor::value_type ImageValueType;
968 typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
972 detail::exportImage(image_upper_left, image_lower_right, image_accessor,
976 catch (Encoder::TIFFCompressionException&)
978 ImageExportInfo info(export_info);
980 info.setCompression(
"");
981 detail::exportImage(image_upper_left, image_lower_right, image_accessor,
987 template <
class ImageIterator,
class ImageAccessor>
989 exportImage(triple<ImageIterator, ImageIterator, ImageAccessor> image,
990 ImageExportInfo
const & export_info)
992 exportImage(image.first, image.second, image.third,
996 template <
class T,
class S>
998 exportImage(MultiArrayView<2, T, S>
const & image,
999 ImageExportInfo
const & export_info)
1001 exportImage(srcImageRange(image), export_info);
1004 template <
class T,
class S>
1006 exportImage(MultiArrayView<2, T, S>
const & image,
1009 ImageExportInfo export_info(name);
1010 exportImage(srcImageRange(image), export_info);
1013 template <
class T,
class S>
1015 exportImage(MultiArrayView<2, T, S>
const & image,
1016 std::string
const & name)
1018 ImageExportInfo export_info(name.c_str());
1019 exportImage(srcImageRange(image), export_info);
1026 #endif // VIGRA_IMPEX_HXX RowIteratorSelector::res row_iterator
Definition: imageiterator.hxx:605
Definition: accessor.hxx:43