48 #ifndef VIGRA_IMPEX_HXX
49 #define VIGRA_IMPEX_HXX
51 #include "stdimage.hxx"
52 #include "imageinfo.hxx"
53 #include "impexbase.hxx"
62 template <
class ValueType,
63 class ImageIterator,
class ImageAccessor>
65 read_image_band(Decoder* decoder,
66 ImageIterator image_iterator, ImageAccessor image_accessor)
70 const unsigned width(decoder->getWidth());
71 const unsigned height(decoder->getHeight());
72 const unsigned offset(decoder->getOffset());
74 for (
unsigned y = 0U; y != height; ++y)
76 decoder->nextScanline();
78 const ValueType* scanline =
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(0));
80 ImageRowIterator is(image_iterator.rowIterator());
81 const ImageRowIterator is_end(is + width);
85 image_accessor.set(*scanline, is);
95 template <
class ValueType,
96 class ImageIterator,
class ImageAccessor>
98 read_image_bands(Decoder* decoder,
99 ImageIterator image_iterator, ImageAccessor image_accessor)
103 const unsigned width(decoder->getWidth());
104 const unsigned height(decoder->getHeight());
105 const unsigned offset(decoder->getOffset());
106 const unsigned accessor_size(image_accessor.size(image_iterator));
110 if (accessor_size == 3U)
112 const ValueType* scanline_0;
113 const ValueType* scanline_1;
114 const ValueType* scanline_2;
116 for (
unsigned y = 0U; y != height; ++y)
118 decoder->nextScanline();
120 scanline_0 =
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(0));
121 scanline_1 =
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(1));
122 scanline_2 =
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(2));
124 ImageRowIterator is(image_iterator.rowIterator());
125 const ImageRowIterator is_end(is + width);
129 image_accessor.setComponent(*scanline_0, is, 0);
130 image_accessor.setComponent(*scanline_1, is, 1);
131 image_accessor.setComponent(*scanline_2, is, 2);
133 scanline_0 += offset;
134 scanline_1 += offset;
135 scanline_2 += offset;
145 std::vector<const ValueType*> scanlines(accessor_size);
147 for (
unsigned y = 0U; y != height; ++y)
149 decoder->nextScanline();
151 for (
unsigned i = 0U; i != accessor_size; ++i)
153 scanlines[i] =
static_cast<const ValueType*
>(decoder->currentScanlineOfBand(i));
156 ImageRowIterator is(image_iterator.rowIterator());
157 const ImageRowIterator is_end(is + width);
161 for (
unsigned i = 0U; i != accessor_size; ++i)
163 image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i));
164 scanlines[i] += offset;
175 template <
class ImageIterator,
class ImageAccessor>
178 ImageIterator image_iterator, ImageAccessor image_accessor,
181 VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
183 switch (pixel_t_of_string(decoder->getPixelType()))
186 read_image_band<UInt8>(decoder.get(), image_iterator, image_accessor);
188 case UNSIGNED_INT_16:
189 read_image_band<UInt16>(decoder.get(), image_iterator, image_accessor);
191 case UNSIGNED_INT_32:
192 read_image_band<UInt32>(decoder.get(), image_iterator, image_accessor);
195 read_image_band<Int16>(decoder.get(), image_iterator, image_accessor);
198 read_image_band<Int32>(decoder.get(), image_iterator, image_accessor);
201 read_image_band<float>(decoder.get(), image_iterator, image_accessor);
204 read_image_band<double>(decoder.get(), image_iterator, image_accessor);
207 vigra_fail(
"detail::importImage<scalar>: not reached");
214 template <
class ImageIterator,
class ImageAccessor>
217 ImageIterator image_iterator, ImageAccessor image_accessor,
220 VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
222 switch (pixel_t_of_string(decoder->getPixelType()))
225 read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor);
227 case UNSIGNED_INT_16:
228 read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor);
230 case UNSIGNED_INT_32:
231 read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor);
234 read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor);
237 read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor);
240 read_image_bands<float>(decoder.get(), image_iterator, image_accessor);
243 read_image_bands<double>(decoder.get(), image_iterator, image_accessor);
246 vigra_fail(
"vigra::detail::importImage<non-scalar>: not reached");
252 template<
class ValueType,
253 class ImageIterator,
class ImageAccessor,
class ImageScaler>
255 write_image_band(Encoder* encoder,
256 ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
257 const ImageScaler& image_scaler)
260 typedef typename ImageAccessor::value_type ImageValueType;
262 typedef RequiresExplicitCast<ValueType> explicit_cast;
264 vigra_precondition(image_lower_right.x >= image_upper_left.x,
265 "vigra::detail::write_image_band: negative width");
266 vigra_precondition(image_lower_right.y >= image_upper_left.y,
267 "vigra::detail::write_image_band: negative height");
269 const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
270 const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
272 encoder->setWidth(width);
273 encoder->setHeight(height);
274 encoder->setNumBands(1);
275 encoder->finalizeSettings();
277 const unsigned offset(encoder->getOffset());
282 ImageIterator image_iterator(image_upper_left);
284 for (
unsigned y = 0U; y != height; ++y)
286 ValueType* scanline =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(0));
288 ImageRowIterator is(image_iterator.rowIterator());
289 const ImageRowIterator is_end(is + width);
293 *scanline = explicit_cast::cast(image_scaler(image_accessor(is)));
298 encoder->nextScanline();
305 template<
class ValueType,
306 class ImageIterator,
class ImageAccessor,
class ImageScaler>
308 write_image_bands(Encoder* encoder,
309 ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
310 const ImageScaler& image_scaler)
313 typedef RequiresExplicitCast<ValueType> explicit_cast;
315 vigra_precondition(image_lower_right.x >= image_upper_left.x,
316 "vigra::detail::write_image_bands: negative width");
317 vigra_precondition(image_lower_right.y >= image_upper_left.y,
318 "vigra::detail::write_image_bands: negative height");
320 const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
321 const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
322 const unsigned accessor_size(image_accessor.size(image_upper_left));
324 encoder->setWidth(width);
325 encoder->setHeight(height);
326 encoder->setNumBands(accessor_size);
327 encoder->finalizeSettings();
329 const unsigned offset(encoder->getOffset());
334 ImageIterator image_iterator(image_upper_left);
338 if (accessor_size == 3U)
340 ValueType* scanline_0;
341 ValueType* scanline_1;
342 ValueType* scanline_2;
344 for (
unsigned y = 0U; y != height; ++y)
346 scanline_0 =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(0));
347 scanline_1 =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(1));
348 scanline_2 =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(2));
350 ImageRowIterator is(image_iterator.rowIterator());
351 const ImageRowIterator is_end(is + width);
355 *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
356 *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
357 *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
359 scanline_0 += offset;
360 scanline_1 += offset;
361 scanline_2 += offset;
366 encoder->nextScanline();
373 std::vector<ValueType*> scanlines(accessor_size);
375 for (
unsigned y = 0U; y != height; ++y)
377 for (
unsigned i = 0U; i != accessor_size; ++i)
379 scanlines[i] =
static_cast<ValueType*
>(encoder->currentScanlineOfBand(i));
382 ImageRowIterator is(image_iterator.rowIterator());
383 const ImageRowIterator is_end(is + width);
387 for (
unsigned i = 0U; i != accessor_size; ++i)
389 *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
390 scanlines[i] += offset;
395 encoder->nextScanline();
403 template <
class ImageIterator,
class ImageAccessor>
405 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
406 const ImageExportInfo& export_info,
409 typedef typename ImageAccessor::value_type ImageValueType;
411 VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
413 std::string pixel_type(export_info.getPixelType());
414 const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
415 const pixel_t type(pixel_t_of_string(pixel_type));
417 encoder->setPixelType(pixel_type);
419 const range_t image_source_range(find_source_value_range(export_info,
420 image_upper_left, image_lower_right, image_accessor));
421 const range_t destination_range(find_destination_value_range(export_info, type));
423 if ((downcast || export_info.hasForcedRangeMapping()) &&
424 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
426 const linear_transform image_rescaler(image_source_range, destination_range);
431 write_image_band<UInt8>(encoder.get(),
432 image_upper_left, image_lower_right, image_accessor, image_rescaler);
434 case UNSIGNED_INT_16:
435 write_image_band<UInt16>(encoder.get(),
436 image_upper_left, image_lower_right, image_accessor, image_rescaler);
438 case UNSIGNED_INT_32:
439 write_image_band<UInt32>(encoder.get(),
440 image_upper_left, image_lower_right, image_accessor, image_rescaler);
443 write_image_band<Int16>(encoder.get(),
444 image_upper_left, image_lower_right, image_accessor, image_rescaler);
447 write_image_band<Int32>(encoder.get(),
448 image_upper_left, image_lower_right, image_accessor, image_rescaler);
451 write_image_band<float>(encoder.get(),
452 image_upper_left, image_lower_right, image_accessor, image_rescaler);
455 write_image_band<double>(encoder.get(),
456 image_upper_left, image_lower_right, image_accessor, image_rescaler);
459 vigra_fail(
"vigra::detail::exportImage<scalar>: not reached");
467 write_image_band<UInt8>(encoder.get(),
468 image_upper_left, image_lower_right, image_accessor, identity());
470 case UNSIGNED_INT_16:
471 write_image_band<UInt16>(encoder.get(),
472 image_upper_left, image_lower_right, image_accessor, identity());
474 case UNSIGNED_INT_32:
475 write_image_band<UInt32>(encoder.get(),
476 image_upper_left, image_lower_right, image_accessor, identity());
479 write_image_band<Int16>(encoder.get(),
480 image_upper_left, image_lower_right, image_accessor, identity());
483 write_image_band<Int32>(encoder.get(),
484 image_upper_left, image_lower_right, image_accessor, identity());
487 write_image_band<float>(encoder.get(),
488 image_upper_left, image_lower_right, image_accessor, identity());
491 write_image_band<double>(encoder.get(),
492 image_upper_left, image_lower_right, image_accessor, identity());
495 vigra_fail(
"vigra::detail::exportImage<scalar>: not reached");
503 template <
class ImageIterator,
class ImageAccessor>
505 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
506 const ImageExportInfo& export_info,
509 typedef typename ImageAccessor::value_type ImageBaseType;
510 typedef typename ImageBaseType::value_type ImageValueType;
512 VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
514 std::string pixel_type(export_info.getPixelType());
515 const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
516 const pixel_t type(pixel_t_of_string(pixel_type));
518 encoder->setPixelType(pixel_type);
520 vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
521 "exportImage(): file format does not support requested number of bands (color channels)");
523 const range_t image_source_range(find_source_value_range(export_info,
524 image_upper_left, image_lower_right, image_accessor));
525 const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
527 if ((downcast || export_info.hasForcedRangeMapping()) &&
528 (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
530 const linear_transform image_rescaler(image_source_range, destination_range);
535 write_image_bands<UInt8>(encoder.get(),
536 image_upper_left, image_lower_right, image_accessor, image_rescaler);
538 case UNSIGNED_INT_16:
539 write_image_bands<UInt16>(encoder.get(),
540 image_upper_left, image_lower_right, image_accessor, image_rescaler);
542 case UNSIGNED_INT_32:
543 write_image_bands<UInt32>(encoder.get(),
544 image_upper_left, image_lower_right, image_accessor, image_rescaler);
547 write_image_bands<Int16>(encoder.get(),
548 image_upper_left, image_lower_right, image_accessor, image_rescaler);
551 write_image_bands<Int32>(encoder.get(),
552 image_upper_left, image_lower_right, image_accessor, image_rescaler);
555 write_image_bands<float>(encoder.get(),
556 image_upper_left, image_lower_right, image_accessor, image_rescaler);
559 write_image_bands<double>(encoder.get(),
560 image_upper_left, image_lower_right, image_accessor, image_rescaler);
563 vigra_fail(
"vigra::detail::exportImage<non-scalar>: not reached");
571 write_image_bands<UInt8>(encoder.get(),
572 image_upper_left, image_lower_right, image_accessor, identity());
574 case UNSIGNED_INT_16:
575 write_image_bands<UInt16>(encoder.get(),
576 image_upper_left, image_lower_right, image_accessor, identity());
578 case UNSIGNED_INT_32:
579 write_image_bands<UInt32>(encoder.get(),
580 image_upper_left, image_lower_right, image_accessor, identity());
583 write_image_bands<Int16>(encoder.get(),
584 image_upper_left, image_lower_right, image_accessor, identity());
587 write_image_bands<Int32>(encoder.get(),
588 image_upper_left, image_lower_right, image_accessor, identity());
591 write_image_bands<float>(encoder.get(),
592 image_upper_left, image_lower_right, image_accessor, identity());
595 write_image_bands<double>(encoder.get(),
596 image_upper_left, image_lower_right, image_accessor, identity());
599 vigra_fail(
"vigra::detail::exportImage<non-scalar>: not reached");
681 doxygen_overloaded_function(template <...>
inline void importImage)
684 template <
class ImageIterator,
class ImageAccessor>
687 ImageIterator image_iterator, ImageAccessor image_accessor)
689 typedef typename ImageAccessor::value_type ImageValueType;
690 typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
692 detail::importImage(import_info,
693 image_iterator, image_accessor,
698 template <
class ImageIterator,
class ImageAccessor>
701 const vigra::pair<ImageIterator, ImageAccessor>& image)
704 image.first, image.second);
781 doxygen_overloaded_function(template <...>
inline void exportImage)
784 template <
class ImageIterator,
class ImageAccessor>
786 exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
787 const ImageExportInfo& export_info)
789 typedef typename ImageAccessor::value_type ImageValueType;
790 typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
794 detail::exportImage(image_upper_left, image_lower_right, image_accessor,
798 catch (Encoder::TIFFCompressionException&)
800 ImageExportInfo info(export_info);
802 info.setCompression(
"");
803 detail::exportImage(image_upper_left, image_lower_right, image_accessor,
810 template <
class ImageIterator,
class ImageAccessor>
812 exportImage(
const vigra::triple<ImageIterator, ImageIterator, ImageAccessor>& image,
813 const ImageExportInfo& export_info)
815 exportImage(image.first, image.second, image.third,
823 #endif // VIGRA_IMPEX_HXX
RowIteratorSelector::res row_iterator
Definition: imageiterator.hxx:606
void exportImage(...)
Write an image given a vigra::ImageExportInfo object.
void importImage(...)
Read the image specified by the given vigra::ImageImportInfo object.