56 #ifndef VIGRA_IMPEX_HXX
57 #define VIGRA_IMPEX_HXX
59 #include "sized_int.hxx"
60 #include "stdimage.hxx"
61 #include "tinyvector.hxx"
62 #include "imageinfo.hxx"
63 #include "numerictraits.hxx"
65 #include "accessor.hxx"
66 #include "inspectimage.hxx"
67 #include "transformimage.hxx"
68 #include "copyimage.hxx"
69 #include "multi_array.hxx"
99 template<
class ImageIterator,
class Accessor,
class SrcValueType >
102 typedef unsigned int size_type;
104 typedef typename Accessor::value_type AccessorValueType;
105 typedef typename AccessorValueType::value_type DstValueType;
107 const size_type width = dec->getWidth();
108 const size_type height = dec->getHeight();
109 const size_type num_bands = dec->getNumBands();
111 vigra_precondition(num_bands == (size_type)a.size(ys),
112 "importImage(): number of bands (color channels) in file and destination image differ.");
114 SrcValueType
const * scanline;
116 DstRowIterator xs = ys.rowIterator();
119 if (num_bands == 4) {
121 unsigned int offset = dec->getOffset();
122 SrcValueType
const * scanline0;
123 SrcValueType
const * scanline1;
124 SrcValueType
const * scanline2;
125 SrcValueType
const * scanline3;
126 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
128 xs = ys.rowIterator();
129 scanline0 =
static_cast< SrcValueType
const *
>
130 (dec->currentScanlineOfBand(0));
131 scanline1 =
static_cast< SrcValueType
const *
>
132 (dec->currentScanlineOfBand(1));
133 scanline2 =
static_cast< SrcValueType
const *
>
134 (dec->currentScanlineOfBand(2));
135 scanline3 =
static_cast< SrcValueType
const *
>
136 (dec->currentScanlineOfBand(3));
137 for( size_type x = 0; x < width; ++x, ++xs ) {
144 a.setComponent( *scanline0, xs, 0);
145 a.setComponent( *scanline1, xs, 1);
146 a.setComponent( *scanline2, xs, 2);
147 a.setComponent( *scanline3, xs, 3);
157 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
159 for( size_type b = 0; b < num_bands; ++b ) {
160 xs = ys.rowIterator();
161 scanline =
static_cast< SrcValueType
const *
>
162 (dec->currentScanlineOfBand(b));
163 for( size_type x = 0; x < width; ++x, ++xs ) {
164 a.setComponent( *scanline, xs, b );
165 scanline += dec->getOffset();
191 template<
class ImageIterator,
class Accessor,
class SrcValueType >
194 typedef unsigned int size_type;
196 typedef typename Accessor::value_type DstValueType;
197 const size_type width = dec->getWidth();
198 const size_type height = dec->getHeight();
200 SrcValueType
const * scanline;
202 DstRowIterator xs = ys.rowIterator();
204 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
206 xs = ys.rowIterator();
207 scanline =
static_cast< SrcValueType
const *
>(dec->currentScanlineOfBand(0));
208 for( size_type x = 0; x < width; ++x, ++xs )
209 a.set( scanline[x], xs );
240 template<
class ImageIterator,
class Accessor >
241 void importVectorImage(
const ImageImportInfo & info, ImageIterator iter, Accessor a )
243 std::auto_ptr<Decoder> dec = decoder(info);
244 std::string pixeltype = dec->getPixelType();
246 if ( pixeltype ==
"UINT8" )
248 else if ( pixeltype ==
"INT16" )
250 else if ( pixeltype ==
"UINT16" )
252 else if ( pixeltype ==
"INT32" )
254 else if ( pixeltype ==
"UINT32" )
256 else if ( pixeltype ==
"FLOAT" )
258 else if ( pixeltype ==
"DOUBLE" )
261 vigra_precondition(
false,
"invalid pixeltype" );
294 template <
class ImageIterator,
class Accessor >
295 void importScalarImage(
const ImageImportInfo & info, ImageIterator iter, Accessor a )
297 std::auto_ptr<Decoder> dec = decoder(info);
298 std::string pixeltype = dec->getPixelType();
300 if ( pixeltype ==
"UINT8" )
302 else if ( pixeltype ==
"INT16" )
304 else if ( pixeltype ==
"UINT16" )
306 else if ( pixeltype ==
"INT32" )
308 else if ( pixeltype ==
"UINT32" )
310 else if ( pixeltype ==
"FLOAT" )
311 read_band( dec.get(), iter, a, float() );
312 else if ( pixeltype ==
"DOUBLE" )
313 read_band( dec.get(), iter, a, double() );
315 vigra_precondition(
false,
"invalid pixeltype" );
401 template <
class ImageIterator,
class Accessor >
402 void importImage(
const ImageImportInfo & info, ImageIterator iter, Accessor a )
404 typedef typename NumericTraits<typename Accessor::value_type>::isScalar is_scalar;
408 template <
class ImageIterator,
class Accessor >
409 void importImage(
const ImageImportInfo & info, pair< ImageIterator, Accessor > dest )
414 template <
class ImageIterator,
class Accessor >
415 void importImage(
const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraFalseType )
420 template <
class ImageIterator,
class Accessor >
421 void importImage(
const ImageImportInfo & info, ImageIterator iter, Accessor a, VigraTrueType )
446 template<
class ImageIterator,
class Accessor,
class DstValueType >
449 typedef unsigned int size_type;
451 typedef typename Accessor::value_type AccessorValueType;
452 typedef typename AccessorValueType::value_type SrcValueType;
455 const size_type width = lr.
x - ul.
x;
456 const size_type height = lr.
y - ul.
y;
457 enc->setWidth(width);
458 enc->setHeight(height);
459 const size_type num_bands = a.size(ul);
460 enc->setNumBands(num_bands);
461 enc->finalizeSettings();
463 DstValueType * scanline;
468 SrcRowIterator xs = ys.rowIterator();
475 unsigned int offset = enc->getOffset();
476 DstValueType * scanline0;
477 DstValueType * scanline1;
478 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
479 xs = ys.rowIterator();
480 scanline0 =
static_cast< DstValueType *
>
481 (enc->currentScanlineOfBand(0));
482 scanline1 =
static_cast< DstValueType *
>
483 (enc->currentScanlineOfBand(1));
484 for( size_type x = 0; x < width; ++x, ++xs) {
485 *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
486 *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
497 unsigned int offset = enc->getOffset();
498 DstValueType * scanline0;
499 DstValueType * scanline1;
500 DstValueType * scanline2;
501 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
502 xs = ys.rowIterator();
503 scanline0 =
static_cast< DstValueType *
>
504 (enc->currentScanlineOfBand(0));
505 scanline1 =
static_cast< DstValueType *
>
506 (enc->currentScanlineOfBand(1));
507 scanline2 =
static_cast< DstValueType *
>
508 (enc->currentScanlineOfBand(2));
509 for( size_type x = 0; x < width; ++x, ++xs) {
510 *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
511 *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
512 *scanline2 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 2));
523 unsigned int offset = enc->getOffset();
524 DstValueType * scanline0;
525 DstValueType * scanline1;
526 DstValueType * scanline2;
527 DstValueType * scanline3;
528 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
529 xs = ys.rowIterator();
530 scanline0 =
static_cast< DstValueType *
>
531 (enc->currentScanlineOfBand(0));
532 scanline1 =
static_cast< DstValueType *
>
533 (enc->currentScanlineOfBand(1));
534 scanline2 =
static_cast< DstValueType *
>
535 (enc->currentScanlineOfBand(2));
536 scanline3 =
static_cast< DstValueType *
>
537 (enc->currentScanlineOfBand(3));
538 for( size_type x = 0; x < width; ++x, ++xs) {
539 *scanline0 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 0));
540 *scanline1 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 1));
541 *scanline2 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 2));
542 *scanline3 = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, 3));
555 for( size_type y = 0; y < height; ++y, ++ys.
y ) {
556 for( size_type b = 0; b < num_bands; ++b ) {
557 xs = ys.rowIterator();
558 scanline =
static_cast< DstValueType *
>
559 (enc->currentScanlineOfBand(b));
560 for( size_type x = 0; x < width; ++x, ++xs ) {
561 *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a.getComponent( xs, b ));
562 scanline += enc->getOffset();
571 template<
class MArray,
class DstValueType >
572 void write_bands( Encoder * enc, MArray
const & array, DstValueType)
574 typedef unsigned int size_type;
577 const size_type width = array.shape(0);
578 const size_type height = array.shape(1);
579 enc->setWidth(width);
580 enc->setHeight(height);
581 const size_type num_bands = array.shape(2);
582 enc->setNumBands(num_bands);
583 enc->finalizeSettings();
585 DstValueType * scanline;
588 for( size_type y = 0; y < height; ++y ) {
589 for( size_type b = 0; b < num_bands; ++b ) {
590 scanline =
static_cast< DstValueType *
>
591 (enc->currentScanlineOfBand(b));
592 for( size_type x = 0; x < width; ++x) {
593 *scanline = array(x, y, b);
594 scanline += enc->getOffset();
621 template<
class ImageIterator,
class Accessor,
class DstValueType >
624 typedef unsigned int size_type;
626 typedef typename Accessor::value_type SrcValueType;
629 const size_type width = size_type(lr.
x - ul.
x);
630 const size_type height = size_type(lr.
y - ul.
y);
631 enc->setWidth(width);
632 enc->setHeight(height);
634 enc->finalizeSettings();
636 DstValueType * scanline;
641 SrcRowIterator xs = ys.rowIterator();
643 for( y = 0; y < height; ++y, ++ys.
y ) {
644 xs = ys.rowIterator();
645 scanline =
static_cast< DstValueType *
>(enc->currentScanlineOfBand(0));
646 for( size_type x = 0; x < width; ++x, ++xs, ++scanline )
647 *scanline = detail::RequiresExplicitCast<DstValueType>::cast(a(xs));
655 template <
class SrcIterator,
class SrcAccessor,
class T >
656 void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
657 Encoder * enc, T zero)
663 template <
class SrcIterator,
class SrcAccessor,
class T >
664 void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
666 const ImageExportInfo & info,
669 double fromMin, fromMax, toMin, toMax;
670 if(info.getFromMin() < info.getFromMax())
672 fromMin = info.getFromMin();
673 fromMax = info.getFromMax();
677 typedef typename SrcAccessor::value_type SrcValue;
678 FindMinMax<SrcValue> minmax;
681 fromMin = (double)minmax.min;
682 fromMax = (
double)minmax.max;
683 if(fromMax <= fromMin)
684 fromMax = fromMin + 1.0;
687 if(info.getToMin() < info.getToMax())
689 toMin = info.getToMin();
690 toMax = info.getToMax();
694 toMin = (double)NumericTraits<T>::min();
695 toMax = (double)NumericTraits<T>::max();
698 double scale = (toMax - toMin) / (fromMax - fromMin);
699 double offset = (toMin / scale) - fromMin;
700 BasicImage<T> image(slr-sul);
701 transformImage( sul, slr, sget, image.upperLeft(), image.accessor(),
704 image.lowerRight(), image.accessor(), zero );
708 template <
class SrcIterator,
class SrcAccessor,
class T >
709 void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
710 Encoder * enc, T zero)
712 int bands = sget.size(sul);
713 vigra_precondition(isBandNumberSupported(enc->getFileType(), bands),
714 "exportImage(): file format does not support requested number of bands (color channels)");
719 template <
class SrcIterator,
class SrcAccessor,
class T >
720 void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget,
722 const ImageExportInfo & info,
725 unsigned int bands = sget.size(sul);
726 vigra_precondition(isBandNumberSupported(enc->getFileType(), bands),
727 "exportImage(): file format does not support requested number of bands (color channels)");
729 typedef typename SrcAccessor::ElementAccessor SrcElementAccessor;
730 typedef typename SrcElementAccessor::value_type SrcComponent;
731 double fromMin, fromMax, toMin, toMax;
732 if(info.getFromMin() < info.getFromMax())
734 fromMin = info.getFromMin();
735 fromMax = info.getFromMax();
739 FindMinMax<SrcComponent> minmax;
740 for(
unsigned int i=0; i<bands; ++i)
742 SrcElementAccessor band(i, sget);
746 fromMin = (double)minmax.min;
747 fromMax = (
double)minmax.max;
748 if(fromMax <= fromMin)
749 fromMax = fromMin + 1.0;
752 if(info.getToMin() < info.getToMax())
754 toMin = info.getToMin();
755 toMax = info.getToMax();
759 toMin = (double)NumericTraits<T>::min();
760 toMax = (double)NumericTraits<T>::max();
763 double scale = (toMax - toMin) / (fromMax - fromMin);
764 double offset = (toMin / scale) - fromMin;
765 int w = slr.x - sul.x;
766 int h = slr.y - sul.y;
769 MArray array(
typename MArray::difference_type(w, h, bands));
771 for(
unsigned int i=0; i<bands; ++i)
774 SrcElementAccessor band(i, sget);
775 transformImage( sul, slr, band, subImage.upperLeft(), subImage.accessor(),
801 template <
class SrcIterator,
class SrcAccessor >
803 const ImageExportInfo & info )
825 template <
class SrcIterator,
class SrcAccessor >
827 const ImageExportInfo & info )
849 template <
class SrcIterator,
class SrcAccessor >
851 const ImageExportInfo & info )
873 template <
class SrcIterator,
class SrcAccessor >
875 const ImageExportInfo & info )
970 template <
class SrcIterator,
class SrcAccessor >
971 void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
972 const ImageExportInfo & info )
974 typedef typename NumericTraits<typename SrcAccessor::value_type>::isScalar is_scalar;
980 catch(Encoder::TIFFCompressionException &)
982 const_cast<ImageExportInfo &
>(info).setCompression(
"");
987 template <
class SrcIterator,
class SrcAccessor >
989 void exportImage( triple<SrcIterator, SrcIterator, SrcAccessor> src,
990 const ImageExportInfo & info )
992 exportImage( src.first, src.second, src.third, info );
995 template <
class SrcIterator,
class SrcAccessor >
996 void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
997 const ImageExportInfo & info, VigraFalseType )
999 typedef typename SrcAccessor::value_type AccessorValueType;
1000 typedef typename AccessorValueType::value_type SrcValueType;
1001 std::string pixeltype = info.getPixelType();
1002 std::auto_ptr<Encoder> enc = encoder(info);
1003 bool downcast = negotiatePixelType(enc->getFileType(),
1004 TypeAsString<SrcValueType>::result(), pixeltype);
1005 enc->setPixelType(pixeltype);
1006 if(downcast || info.hasForcedRangeMapping())
1008 if(pixeltype ==
"UINT8")
1009 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (
UInt8)0);
1010 else if(pixeltype ==
"INT16")
1011 detail::exportVectorImage( sul, slr, sget, enc.get(), info,
Int16());
1012 else if(pixeltype ==
"UINT16")
1013 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (
UInt16)0);
1014 else if(pixeltype ==
"INT32")
1015 detail::exportVectorImage( sul, slr, sget, enc.get(), info,
Int32());
1016 else if(pixeltype ==
"UINT32")
1017 detail::exportVectorImage( sul, slr, sget, enc.get(), info, (
UInt32)0);
1018 else if(pixeltype ==
"FLOAT")
1019 detail::exportVectorImage( sul, slr, sget, enc.get(), info, float());
1020 else if(pixeltype ==
"DOUBLE")
1021 detail::exportVectorImage( sul, slr, sget, enc.get(), info, double());
1025 if(pixeltype ==
"UINT8")
1026 detail::exportVectorImage( sul, slr, sget, enc.get(), (
UInt8)0);
1027 else if(pixeltype ==
"INT16")
1028 detail::exportVectorImage( sul, slr, sget, enc.get(),
Int16());
1029 else if(pixeltype ==
"UINT16")
1030 detail::exportVectorImage( sul, slr, sget, enc.get(), (
UInt16)0);
1031 else if(pixeltype ==
"INT32")
1032 detail::exportVectorImage( sul, slr, sget, enc.get(),
Int32());
1033 else if(pixeltype ==
"UINT32")
1034 detail::exportVectorImage( sul, slr, sget, enc.get(), (
UInt32)0);
1035 else if(pixeltype ==
"FLOAT")
1036 detail::exportVectorImage( sul, slr, sget, enc.get(), float());
1037 else if(pixeltype ==
"DOUBLE")
1038 detail::exportVectorImage( sul, slr, sget, enc.get(), double());
1043 template <
class SrcIterator,
class SrcAccessor >
1044 void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
1045 const ImageExportInfo & info, VigraTrueType )
1047 typedef typename SrcAccessor::value_type SrcValueType;
1048 std::string pixeltype = info.getPixelType();
1049 std::auto_ptr<Encoder> enc = encoder(info);
1050 bool downcast = negotiatePixelType(enc->getFileType(),
1051 TypeAsString<SrcValueType>::result(), pixeltype);
1052 enc->setPixelType(pixeltype);
1053 if(downcast || info.hasForcedRangeMapping())
1055 if(pixeltype ==
"UINT8")
1056 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (
UInt8)0);
1057 else if(pixeltype ==
"INT16")
1058 detail::exportScalarImage( sul, slr, sget, enc.get(), info,
Int16());
1059 else if(pixeltype ==
"UINT16")
1060 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (
UInt16)0);
1061 else if(pixeltype ==
"INT32")
1062 detail::exportScalarImage( sul, slr, sget, enc.get(), info,
Int32());
1063 else if(pixeltype ==
"UINT32")
1064 detail::exportScalarImage( sul, slr, sget, enc.get(), info, (
UInt32)0);
1065 else if(pixeltype ==
"FLOAT")
1066 detail::exportScalarImage( sul, slr, sget, enc.get(), info, float());
1067 else if(pixeltype ==
"DOUBLE")
1068 detail::exportScalarImage( sul, slr, sget, enc.get(), info, double());
1072 if(pixeltype ==
"UINT8")
1073 detail::exportScalarImage( sul, slr, sget, enc.get(), (
UInt8)0);
1074 else if(pixeltype ==
"INT16")
1075 detail::exportScalarImage( sul, slr, sget, enc.get(),
Int16());
1076 else if(pixeltype ==
"UINT16")
1077 detail::exportScalarImage( sul, slr, sget, enc.get(), (
UInt16)0);
1078 else if(pixeltype ==
"INT32")
1079 detail::exportScalarImage( sul, slr, sget, enc.get(),
Int32());
1080 else if(pixeltype ==
"UINT32")
1081 detail::exportScalarImage( sul, slr, sget, enc.get(), (
UInt32)0);
1082 else if(pixeltype ==
"FLOAT")
1083 detail::exportScalarImage( sul, slr, sget, enc.get(), float());
1084 else if(pixeltype ==
"DOUBLE")
1085 detail::exportScalarImage( sul, slr, sget, enc.get(), double());