00001
00029 #ifndef VIGRA_EXT_IMPEX_ALPHA_IMAGE_H
00030 #define VIGRA_EXT_IMPEX_ALPHA_IMAGE_H
00031
00032 #include <iostream>
00033 #include <vigra/imageiterator.hxx>
00034 #include <vigra/transformimage.hxx>
00035 #include <vigra/initimage.hxx>
00036 #include <vigra/numerictraits.hxx>
00037
00038 #include <vigra/impex.hxx>
00039
00040 namespace vigra {
00041
00042 #if 0
00043
00046 template <class T1>
00047 struct GetMaskTrue;
00048
00049 #define VIGRA_EXT_GETMASKTRUE(T1, S) \
00050 template<> \
00051 struct GetMaskTrue<T1> \
00052 { \
00053 static T1 get() \
00054 { \
00055 return S; \
00056 } \
00057 };
00058
00059 #define VIGRA_EXT_GETMASKMAX(T1) \
00060 template<> \
00061 struct GetMaskTrue<T1> \
00062 { \
00063 static T1 get() \
00064 { \
00065 return vigra::NumericTraits<T1>::max(); \
00066 } \
00067 };
00068
00069 VIGRA_EXT_GETMASKMAX(vigra::UInt8)
00070 VIGRA_EXT_GETMASKMAX(vigra::Int16)
00071 VIGRA_EXT_GETMASKMAX(vigra::UInt16)
00072 VIGRA_EXT_GETMASKMAX(vigra::Int32)
00073 VIGRA_EXT_GETMASKMAX(vigra::UInt32)
00074 VIGRA_EXT_GETMASKTRUE(float, 1.0f)
00075 VIGRA_EXT_GETMASKTRUE(double, 1.0)
00076
00077 #endif
00078
00079
00080 template <class T1>
00081 struct MaskConv;
00082
00083
00084 template<>
00085 struct MaskConv<vigra::UInt8>
00086 {
00087 static vigra::UInt8 toUInt8(vigra::UInt8 v)
00088 {
00089 return v;
00090 }
00091
00092 static vigra::UInt8 fromUInt8(vigra::UInt8 v)
00093 {
00094 return v;
00095 }
00096 };
00097
00098 template<>
00099 struct MaskConv<vigra::UInt16>
00100 {
00101 static vigra::UInt8 toUInt8(vigra::UInt16 v)
00102 {
00103 return v>>8;
00104 }
00105
00106
00107 static vigra::UInt16 fromUInt8(vigra::UInt8 v)
00108 {
00109 return (v<<8) + v;
00110 }
00111 };
00112
00113 template<>
00114 struct MaskConv<vigra::Int16>
00115 {
00116 static vigra::UInt8 toUInt8(vigra::Int16 v)
00117 {
00118 return v>>7;
00119 }
00120
00121
00122 static vigra::Int16 fromUInt8(vigra::UInt8 v)
00123 {
00124 return (v<<7)+ (v & 127);
00125 }
00126 };
00127
00128 template<>
00129 struct MaskConv<vigra::UInt32>
00130 {
00131 static vigra::UInt8 toUInt8(vigra::UInt32 v)
00132 {
00133 return v>>24;
00134 }
00135
00136
00137 static vigra::UInt32 fromUInt8(vigra::UInt8 v)
00138 {
00139 return (v<<24) + (v<<16) + (v<<8) + v;
00140 }
00141 };
00142
00143 template<>
00144 struct MaskConv<vigra::Int32>
00145 {
00146 static vigra::UInt8 toUInt8(vigra::Int32 v)
00147 {
00148 return v>>23;
00149 }
00150
00151
00152 static vigra::Int32 fromUInt8(vigra::UInt8 v)
00153 {
00154 return (v<<23) + (v<<15) + (v<<7) + (v & 127);
00155 }
00156 };
00157
00158 template<>
00159 struct MaskConv<float>
00160 {
00161 static vigra::UInt8 toUInt8(float v)
00162 {
00163 return vigra::NumericTraits<vigra::UInt8>::fromRealPromote(v*255);
00164 }
00165
00166 static float fromUInt8(vigra::UInt8 v)
00167 {
00168 return v/255.0f;
00169 }
00170
00171 };
00172
00173 template<>
00174 struct MaskConv<double>
00175 {
00176 static vigra::UInt8 toUInt8(double v)
00177 {
00178 return vigra::NumericTraits<vigra::UInt8>::fromRealPromote(v*255);
00179 }
00180
00181 static double fromUInt8(vigra::UInt8 v)
00182 {
00183 return v/255.0;
00184 }
00185
00186 };
00187
00188
00189 template <class Iter1, class Acc1, class Iter2, class Acc2>
00190 class MultiImageMaskAccessor2
00191 {
00192 public:
00196 typedef vigra::TinyVector<typename Acc1::value_type, 2> value_type;
00197 typedef typename Acc1::value_type component_type;
00198 typedef typename Acc2::value_type alpha_type;
00199
00202 MultiImageMaskAccessor2(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00203 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00204 {}
00205
00208 template <class DIFFERENCE>
00209 value_type operator()(DIFFERENCE const & d) const
00210 {
00211 return value_type(a1_(i1_, d),
00212 MaskConv<component_type>::fromUInt8(a2_(i2_, d)));
00213 }
00214
00217 template <class DIFFERENCE1, class DIFFERENCE2>
00218 value_type operator()(DIFFERENCE1 d, DIFFERENCE2 const & d2) const
00219 {
00220 d += d2;
00221 return value_type(a1_(i1_, d),
00222 MaskConv<component_type>::fromUInt8(a2_(i2_, d)));
00223
00224
00225
00226 }
00227
00230 template <class DIFFERENCE>
00231 value_type set(const value_type & vt, DIFFERENCE const & d) const
00232 {
00233 a1_.set(vt[0], i1_, d);
00234 a2_.set(MaskConv<component_type>::toUInt8(vt[1]));
00235
00236 }
00237
00239 template <class V, class ITERATOR>
00240 void setComponent( V const & value, ITERATOR const & i, int idx ) const
00241 {
00242 switch (idx) {
00243 case 0:
00244 a1_.set(value, i1_, *i);
00245 break;
00246 case 1:
00247 a2_.set(MaskConv<V>::toUInt8(value), i2_, *i);
00248
00249 break;
00250 default:
00251 vigra_fail("too many components in input value");
00252 }
00253 }
00254
00256 template <class ITERATOR>
00257 component_type getComponent(ITERATOR const & i, int idx) const
00258 {
00259 switch (idx) {
00260 case 0:
00261 return a1_( i1_, *i );
00262 case 1:
00263 return MaskConv<component_type>::fromUInt8(a2_( i2_, *i ));
00264
00265 default:
00266 vigra_fail("too many components in input value");
00267
00268 exit(1);
00269 }
00270 }
00271
00272 template <class ITERATOR>
00273 unsigned int size ( ITERATOR const & i ) const
00274 {
00275 return 2;
00276 }
00277
00278 private:
00279 Iter1 i1_;
00280 Acc1 a1_;
00281 Iter2 i2_;
00282 Acc2 a2_;
00283 };
00284
00285
00286
00287
00288 template <class Iter1, class Acc1, class Iter2, class Acc2>
00289 class MultiImageVectorMaskAccessor4
00290 {
00291 public:
00295 typedef typename Acc1::value_type VT1;
00296
00297 enum { static_size = 4 };
00298
00299 typedef vigra::TinyVector<typename VT1::value_type, static_size> value_type;
00300 typedef typename value_type::value_type component_type;
00301
00302 typedef typename Acc2::value_type alpha_type;
00303
00306 MultiImageVectorMaskAccessor4(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00307 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00308 {}
00309
00312 template <class DIFFERENCE>
00313 value_type operator()(DIFFERENCE const & d) const
00314 {
00315 const VT1 & v1 = a1_.get(i1_,d);
00316 return value_type(v1[0],
00317 v1[1],
00318 v1[2],
00319 MaskConv<component_type>::fromUInt8(a2_(i2_, d)));
00320 }
00321
00324 template <class DIFFERENCE1, class DIFFERENCE2>
00325 value_type operator()(DIFFERENCE1 d, DIFFERENCE2 const & d2) const
00326 {
00327 d += d2;
00328 const VT1 & v1 = a1_.get(i1_,d);
00329 return value_type(v1[0],
00330 v1[1],
00331 v1[2],
00332 MaskConv<component_type>::fromUInt8(a2_(i2_, d)));
00333 }
00334
00337 template <class DIFFERENCE>
00338 value_type set(const value_type & vt, DIFFERENCE const & d) const
00339 {
00340 Iter1 i1(i1_);
00341 i1 +=d;
00342 a1_.setComponent(vt[0], i1_, 0);
00343 a1_.setComponent(vt[1], i1_, 1);
00344 a1_.setComponent(vt[2], i1_, 2);
00345 a2_.set(MaskConv<component_type>::toUInt8(vt[3]), i2_, d);
00346 }
00347
00349 template <class V, class ITERATOR>
00350 void setComponent( V const & value, ITERATOR const & i, int idx ) const
00351 {
00352 if ( idx < static_size - 1 ) {
00353 a1_.setComponent(value, i1_, *i, idx);
00354 } else if ( idx == static_size - 1 ) {
00355 a2_.set(MaskConv<V>::toUInt8(value), i2_, *i);
00356 } else {
00357 vigra_fail("too many components in input value");
00358 }
00359 }
00360
00362 template <class ITERATOR>
00363 component_type getComponent(ITERATOR const & i, int idx) const
00364 {
00365 if ( idx < static_size - 1 ) {
00366 return a1_.getComponent(i1_, *i, idx);
00367 } else
00368 #ifndef DEBUG
00369 return MaskConv<component_type>::fromUInt8(a2_(i2_, *i));
00370 #else
00371 if ( idx == static_size - 1 ) {
00372 return MaskConv<component_type>::fromUInt8(a2_(i2_, *i));
00373 } else {
00374 vigra_fail("too many components in input value");
00375
00376
00377
00378 throw 0;
00379 }
00380 #endif
00381 }
00382
00383 template <class ITERATOR>
00384 unsigned int size ( ITERATOR const & i ) const
00385 {
00386 return static_size;
00387 }
00388
00389 private:
00390 Iter1 i1_;
00391 Acc1 a1_;
00392 Iter2 i2_;
00393 Acc2 a2_;
00394 };
00395
00396
00397
00398 template<class SrcIterator, class SrcAccessor,
00399 class AlphaIterator, class AlphaAccessor>
00400 void exportImageAlpha(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> image,
00401 std::pair<AlphaIterator, AlphaAccessor> alpha,
00402 vigra::ImageExportInfo const & info,
00403 vigra::VigraTrueType)
00404 {
00405 typedef MultiImageMaskAccessor2<SrcIterator, SrcAccessor, AlphaIterator, AlphaAccessor> MAcc;
00406
00407 exportImage(vigra::CoordinateIterator(),
00408 vigra::CoordinateIterator() + (image.second - image.first),
00409 MAcc(image.first, image.third, alpha.first, alpha.second),
00410 info);
00411 }
00412
00413
00414
00415 template<class SrcIterator, class SrcAccessor,
00416 class AlphaIterator, class AlphaAccessor>
00417 void exportImageAlpha(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> image,
00418 std::pair<AlphaIterator, AlphaAccessor> alpha,
00419 vigra::ImageExportInfo const & info,
00420 vigra::VigraFalseType)
00421 {
00422 typedef MultiImageVectorMaskAccessor4<SrcIterator, SrcAccessor, AlphaIterator, AlphaAccessor> MAcc;
00423
00424 exportImage(vigra::CoordinateIterator(), vigra::CoordinateIterator(image.second - image.first),
00425 MAcc(image.first, image.third, alpha.first, alpha.second), info );
00426 }
00427
00428
00437 template<class SrcIterator, class SrcAccessor,
00438 class AlphaIterator, class AlphaAccessor>
00439 void exportImageAlpha(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> image,
00440 std::pair<AlphaIterator, AlphaAccessor> alpha,
00441 vigra::ImageExportInfo const & info)
00442 {
00443 typedef typename vigra::NumericTraits<typename SrcAccessor::value_type>::isScalar is_scalar;
00444
00445
00446
00447 exportImageAlpha( image, alpha, info, is_scalar());
00448 }
00449
00450
00451
00452 template<class DestIterator, class DestAccessor,
00453 class AlphaIterator, class AlphaAccessor>
00454 void importImageAlpha(vigra::ImageImportInfo const & info,
00455 std::pair<DestIterator, DestAccessor> image,
00456 std::pair<AlphaIterator, AlphaAccessor> alpha,
00457 vigra::VigraFalseType)
00458 {
00459 vigra_precondition(image.second(image.first).size() == 3,
00460 "only scalar and 3 channel (vector) images supported by impexalpha.hxx");
00461
00462 typedef MultiImageVectorMaskAccessor4<DestIterator, DestAccessor, AlphaIterator, AlphaAccessor> MAcc;
00463 importImage(info,
00464 vigra::CoordinateIterator(),
00465 MAcc(image.first, image.second, alpha.first, alpha.second) );
00466 }
00467
00468
00469 template<class DestIterator, class DestAccessor,
00470 class AlphaIterator, class AlphaAccessor>
00471 void importImageAlpha(vigra::ImageImportInfo const & info,
00472 std::pair<DestIterator, DestAccessor> image,
00473 std::pair<AlphaIterator, AlphaAccessor> alpha,
00474 vigra::VigraTrueType)
00475 {
00476 typedef MultiImageMaskAccessor2<DestIterator, DestAccessor, AlphaIterator, AlphaAccessor> MAcc;
00477
00478 importImage(info, vigra::CoordinateIterator(),
00479 MAcc(image.first, image.second, alpha.first, alpha.second) );
00480 }
00481
00482
00495 template<class DestIterator, class DestAccessor,
00496 class AlphaIterator, class AlphaAccessor>
00497 void importImageAlpha(vigra::ImageImportInfo const & info,
00498 vigra::pair<DestIterator, DestAccessor> image,
00499 std::pair<AlphaIterator, AlphaAccessor> alpha
00500 )
00501 {
00502 typedef typename vigra::NumericTraits<typename DestAccessor::value_type>::isScalar is_scalar;
00503
00504 if (info.numExtraBands() == 1 ) {
00505
00506 importImageAlpha(info, image, alpha, is_scalar());
00507 } else if (info.numExtraBands() == 0 ) {
00508
00509 importImage(info, image);
00510
00511 vigra::initImage(alpha.first ,
00512 alpha.first + vigra::Diff2D(info.width(), info.height()),
00513 alpha.second,
00514 255);
00515 } else {
00516 vigra_fail("Images with two or more channel are not supported");
00517 }
00518 }
00519
00520 }
00521
00522 #endif // VIGRA_EXT_IMPEX_ALPHA_IMAGE_H