00001
00027 #ifndef _VIGRA_EXT_IMAGETRANSFORMS_H
00028 #define _VIGRA_EXT_IMAGETRANSFORMS_H
00029
00030 #include <fstream>
00031
00032 #include <vigra/basicimage.hxx>
00033 #include <vigra_ext/ROIImage.h>
00034 #include <vigra_ext/Interpolators.h>
00035 #include <vigra/impex.hxx>
00036 #include <vigra_ext/impexalpha.hxx>
00037
00038 #include <hugin_math/hugin_math.h>
00039 #include <hugin_utils/utils.h>
00040 #include <appbase/ProgressDisplayOld.h>
00041
00042 #include "MultiThreadOperations.h"
00043 #include <boost/thread/thread.hpp>
00044 #include <boost/bind.hpp>
00045 #include <boost/function.hpp>
00046
00047
00048 namespace vigra_ext
00049 {
00050
00052 template <class T>
00053 T zeroNegative(T p)
00054 {
00055 if (p < 0) {
00056 return vigra::NumericTraits<T>::zero();
00057 } else {
00058 return p;
00059 }
00060 }
00061
00063 template <class T>
00064 vigra::RGBValue<T> zeroNegative(vigra::RGBValue<T> p)
00065 {
00066 if (p.red() < 0) p.setRed(vigra::NumericTraits<T>::zero());
00067 if (p.green() < 0) p.setGreen(vigra::NumericTraits<T>::zero());
00068 if (p.blue() < 0) p.setBlue(vigra::NumericTraits<T>::zero());
00069 return p;
00070 }
00071
00072
00097 template <class SrcImageIterator, class SrcAccessor,
00098 class DestImageIterator, class DestAccessor,
00099 class TRANSFORM,
00100 class PixelTransform,
00101 class AlphaImageIterator, class AlphaAccessor,
00102 class Interpolator>
00103 void transformImageIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00104 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00105 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00106 TRANSFORM & transform,
00107 PixelTransform & pixelTransform,
00108 vigra::Diff2D destUL,
00109 Interpolator interp,
00110 bool warparound,
00111 AppBase::MultiProgressDisplay & prog)
00112 {
00113 vigra::Diff2D destSize = dest.second - dest.first;
00114
00115 int xstart = destUL.x;
00116 int xend = destUL.x + destSize.x;
00117 int ystart = destUL.y;
00118 int yend = destUL.y + destSize.y;
00119
00120 prog.pushTask(AppBase::ProgressTask("Remapping", "", 1.0/(yend-ystart)));
00121
00122 vigra::Diff2D srcSize = src.second - src.first;
00123
00124 vigra_ext::ImageInterpolator<SrcImageIterator, SrcAccessor, Interpolator>
00125 interpol (src, interp, warparound);
00126
00127
00128 DestImageIterator yd(dest.first);
00129
00130 AlphaImageIterator ydm(alpha.first);
00131
00132 typename SrcAccessor::value_type tempval;
00133
00134 for(int y=ystart; y < yend; ++y, ++yd.y, ++ydm.y)
00135 {
00136
00137 DestImageIterator xd(yd);
00138 AlphaImageIterator xdm(ydm);
00139 for(int x=xstart; x < xend; ++x, ++xd.x, ++xdm.x)
00140 {
00141 double sx,sy;
00142 if (transform.transformImgCoord(sx,sy,x,y)) {
00143 if (interpol.operator()(sx, sy, tempval)){
00144
00145 dest.third.set( zeroNegative(pixelTransform(tempval, hugin_utils::FDiff2D(sx, sy))), xd);
00146 alpha.second.set(pixelTransform.hdrWeight(tempval, vigra::UInt8(255)), xdm);
00147 } else {
00148 alpha.second.set(0, xdm);
00149 }
00150 } else {
00151 alpha.second.set(0, xdm);
00152 }
00153 }
00154 if (destSize.y > 100) {
00155 if ((y-ystart)%(destSize.y/20) == 0) {
00156 prog.setProgress(((double)y-ystart)/destSize.y);
00157 }
00158 }
00159 }
00160 prog.popTask();
00161 }
00162
00163
00165 template <class SrcImageIterator, class SrcAccessor,
00166 class DestImageIterator, class DestAccessor,
00167 class TRANSFORM,
00168 class PixelTransform,
00169 class AlphaImageIterator, class AlphaAccessor,
00170 class Interpolator>
00171 struct TransformImageIntern
00172 {
00173 vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src;
00174 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest;
00175 std::pair<AlphaImageIterator, AlphaAccessor> alpha;
00176 const TRANSFORM & transform;
00177 const PixelTransform & pixelTransform;
00178 vigra::Diff2D destUL;
00179 Interpolator interp;
00180 bool warparound;
00181 AppBase::MultiProgressDisplay & prog;
00182
00183 TransformImageIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00184 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00185 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00186 const TRANSFORM & transform,
00187 const PixelTransform & pixelTransform,
00188 vigra::Diff2D destUL,
00189 Interpolator interp,
00190 bool warparound,
00191 AppBase::MultiProgressDisplay & prog)
00192 : src(src), dest(dest), alpha(alpha), transform(transform), pixelTransform(pixelTransform), destUL(destUL), interp(interp), warparound(warparound),
00193 prog(prog)
00194 {
00195 }
00196
00197 void operator()()
00198 {
00199 DEBUG_DEBUG("Starting threaded remap, destUL: " << destUL << " area: " << dest.second - dest.first);
00200 transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL, interp, warparound, prog);
00201 DEBUG_DEBUG("Finished threaded remap, destUL: " << destUL << " area: " << dest.second - dest.first);
00202 }
00203 };
00204
00205
00207 template <class SrcImageIterator, class SrcAccessor,
00208 class SrcAlphaIterator, class SrcAlphaAccessor,
00209 class DestImageIterator, class DestAccessor,
00210 class TRANSFORM,
00211 class PixelTransform,
00212 class AlphaImageIterator, class AlphaAccessor,
00213 class Interpolator>
00214 void transformImageAlphaIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00215 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
00216 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00217 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00218 TRANSFORM & transform,
00219 PixelTransform & pixelTransform,
00220 vigra::Diff2D destUL,
00221 Interpolator interp,
00222 bool warparound,
00223 AppBase::MultiProgressDisplay & prog)
00224 {
00225 vigra::Diff2D destSize = dest.second - dest.first;
00226
00227 int xstart = destUL.x;
00228 int xend = destUL.x + destSize.x;
00229 int ystart = destUL.y;
00230 int yend = destUL.y + destSize.y;
00231
00232 prog.pushTask(AppBase::ProgressTask("Remapping", "", 1.0/(yend-ystart)));
00233
00234 vigra::Diff2D srcSize = src.second - src.first;
00235
00236 vigra_ext::ImageMaskInterpolator<SrcImageIterator, SrcAccessor, SrcAlphaIterator,
00237 SrcAlphaAccessor, Interpolator>
00238 interpol (src, srcAlpha, interp, warparound);
00239
00240
00241 DestImageIterator yd(dest.first);
00242
00243 AlphaImageIterator ydist(alpha.first);
00244
00245 typename SrcAccessor::value_type tempval;
00246
00247 typename SrcAlphaAccessor::value_type alphaval;
00248
00249
00250 for(int y=ystart; y < yend; ++y, ++yd.y, ++ydist.y)
00251 {
00252
00253 DestImageIterator xd(yd);
00254 AlphaImageIterator xdist(ydist);
00255 for(int x=xstart; x < xend; ++x, ++xd.x, ++xdist.x)
00256 {
00257 double sx,sy;
00258 if (transform.transformImgCoord(sx,sy,x,y)) {
00259
00260 if (interpol(sx, sy, tempval, alphaval)) {
00261 dest.third.set(zeroNegative(pixelTransform(tempval, hugin_utils::FDiff2D(sx, sy))), xd);
00262 alpha.second.set(pixelTransform.hdrWeight(tempval, alphaval), xdist);
00263 } else {
00264
00265 alpha.second.set(0, xdist);
00266 }
00267 } else {
00268 alpha.second.set(0, xdist);
00269 }
00270 }
00271 if (destSize.y > 100) {
00272 if ((y-ystart)%(destSize.y/20) == 0) {
00273 prog.setProgress(((double)y-ystart)/destSize.y);
00274 }
00275 }
00276 }
00277 prog.popTask();
00278 };
00279
00280
00282 template <class SrcImageIterator, class SrcAccessor,
00283 class SrcAlphaIterator, class SrcAlphaAccessor,
00284 class DestImageIterator, class DestAccessor,
00285 class TRANSFORM,
00286 class PixelTransform,
00287 class AlphaImageIterator, class AlphaAccessor,
00288 class Interpolator>
00289 struct TransformImageAlphaIntern
00290 {
00291 vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src;
00292 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha;
00293 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest;
00294 std::pair<AlphaImageIterator, AlphaAccessor> alpha;
00295 const TRANSFORM & transform;
00296 const PixelTransform & pixelTransform;
00297 vigra::Diff2D destUL;
00298 Interpolator interp;
00299 bool warparound;
00300 AppBase::MultiProgressDisplay & prog;
00301
00302 TransformImageAlphaIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00303 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
00304 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00305 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00306 const TRANSFORM & transform,
00307 const PixelTransform & pixelTransform,
00308 vigra::Diff2D destUL,
00309 Interpolator interp,
00310 bool warparound,
00311 AppBase::MultiProgressDisplay & prog)
00312 : src(src), srcAlpha(srcAlpha), dest(dest), alpha(alpha), transform(transform),
00313 pixelTransform(pixelTransform), destUL(destUL), interp(interp), warparound(warparound),
00314 prog(prog)
00315 {
00316 }
00317
00318 void operator()()
00319 {
00320 DEBUG_DEBUG("Starting threaded remap, destUL: " << destUL << " area: " << dest.second - dest.first);
00321 transformImageAlphaIntern(src, srcAlpha, dest, alpha, transform, pixelTransform, destUL, interp, warparound, prog);
00322 DEBUG_DEBUG("Finished threaded remap, destUL: " << destUL << " area: " << dest.second - dest.first);
00323 }
00324 };
00325
00326
00351 template <class SrcImageIterator, class SrcAccessor,
00352 class DestImageIterator, class DestAccessor,
00353 class TRANSFORM,
00354 class DistImageIterator, class DistAccessor,
00355 class Interpolator>
00356 void transformImageDist(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00357 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00358 vigra::Diff2D destUL,
00359 TRANSFORM & transform,
00360 vigra::triple<DistImageIterator, DistImageIterator, DistAccessor> centerDist,
00361 Interpolator & interp,
00362 AppBase::MultiProgressDisplay & prog)
00363 {
00364 vigra::Diff2D destSize = dest.second - dest.first;
00365 vigra::Diff2D distSize = centerDist.second - centerDist.first;
00366
00367 bool calcDist=true;
00368 if (distSize.x == 0 && distSize.y == 0) {
00369 calcDist=false;
00370 }
00371
00372 if (calcDist) {
00373 DEBUG_ASSERT(distSize == destSize);
00374 }
00375 int xstart = destUL.x;
00376 int xend = destUL.x + destSize.x;
00377 int ystart = destUL.y;
00378 int yend = destUL.y + destSize.y;
00379
00380 prog.pushTask(AppBase::ProgressTask("Remapping", "", 1.0/(yend-ystart)));
00381
00382 vigra::Diff2D srcSize = src.second - src.first;
00383
00384 vigra::Diff2D srcMiddle = srcSize / 2;
00385
00386
00387
00388
00389 vigra_ext::InterpolatingAccessor<SrcAccessor,
00390 typename SrcAccessor::value_type,
00391 Interpolator> interpol(src.third, interp);
00392
00393
00394
00395
00396
00397
00398
00399 DestImageIterator yd(dest.first);
00400
00401 DistImageIterator ydist(centerDist.first);
00402
00403 for(int y=ystart; y < yend; ++y, ++yd.y, ++ydist.y)
00404 {
00405
00406 DestImageIterator xd(yd);
00407 DistImageIterator xdist(ydist);
00408 for(int x=xstart; x < xend; ++x, ++xd.x, ++xdist.x)
00409 {
00410 double sx,sy;
00411 if (transform.transformImgCoord(sx,sy,x,y)) {
00412
00413
00414
00415 if (sx < interp.size/2 -1
00416 || sx > srcSize.x-interp.size/2 - 1
00417 || sy < interp.size/2 - 1
00418 || sy > srcSize.y-interp.size/2 - 1)
00419 {
00420 if (calcDist) {
00421
00422 *xdist = FLT_MAX;
00423 }
00424
00425 } else {
00426
00427
00428
00429
00430
00431 *xd = interpol(src.first, sx, sy);
00432 if (calcDist) {
00433 double mx = sx - srcMiddle.x;
00434 double my = sy - srcMiddle.y;
00435 *xdist = sqrt(mx*mx + my*my);
00436 }
00437 }
00438 } else {
00439 *xdist = FLT_MAX;
00440 }
00441 }
00442 if ((y-ystart)%100 == 0) {
00443 prog.setProgress(((double)y-ystart)/(yend-ystart));
00444 }
00445 }
00446 prog.popTask();
00447 }
00448
00449
00451
00452
00454 template <class SrcImageIterator, class SrcAccessor,
00455 class SrcAlphaIterator, class SrcAlphaAccessor,
00456 class DestImageIterator, class DestAccessor,
00457 class TRANSFORM,
00458 class PixelTransform,
00459 class AlphaImageIterator, class AlphaAccessor,
00460 class Interpolator>
00461 void transformImageAlphaInternMT(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00462 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
00463 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00464 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00465 TRANSFORM & transform,
00466 PixelTransform & pixelTransform,
00467 vigra::Diff2D destUL,
00468 Interpolator interp,
00469 bool warparound,
00470 AppBase::MultiProgressDisplay & prog)
00471 {
00472
00473 unsigned int nThreads = ThreadManager::get().getNThreads();
00474
00475 vigra::Diff2D destSize = dest.second - dest.first;
00476
00477
00478 if (destSize.y < (int) nThreads) {
00479 nThreads = destSize.y;
00480 }
00481
00482 if (nThreads == 1) {
00483 transformImageAlphaIntern(src, srcAlpha, dest, alpha, transform, pixelTransform,
00484 destUL, interp, warparound, prog);
00485 return;
00486 }
00487
00488 DEBUG_DEBUG("creating " << nThreads << " threads for remapping");
00489
00490 unsigned int chunkSize = destSize.y / nThreads;
00491
00492
00493
00494
00495 boost::thread_group threads;
00496
00497
00498 DestImageIterator destStart = dest.first;
00499 DestImageIterator destEnd = dest.second;
00500 destEnd.y -= destSize.y - chunkSize;
00501 AlphaImageIterator destAStart = alpha.first;
00502
00503 typedef TransformImageAlphaIntern<SrcImageIterator, SrcAccessor, SrcAlphaIterator, SrcAlphaAccessor, DestImageIterator, DestAccessor,
00504 TRANSFORM, PixelTransform, AlphaImageIterator, AlphaAccessor, Interpolator> RFunctor;
00505
00506 std::vector< AppBase::DummyMultiProgressDisplay> dummyProgs(nThreads-1);
00507 unsigned int i;
00508 for (i = 0; i < nThreads-1; ++i) {
00509
00510 RFunctor t(src, srcAlpha, vigra::triple<DestImageIterator, DestImageIterator, DestAccessor>(destStart, destEnd, dest.third),
00511 vigra::pair<AlphaImageIterator, AlphaAccessor>(destAStart, alpha.second),
00512 transform, pixelTransform, destUL, interp, warparound, dummyProgs[i]);
00513 boost::function0<void> f;
00514 f = t;
00515 DEBUG_DEBUG("Starting thread " << i);
00516 threads.create_thread(f);
00517
00518 destStart.y += chunkSize;
00519 destEnd.y += chunkSize;
00520 destAStart.y += chunkSize;
00521 destUL.y += chunkSize;
00522 }
00523
00524 destEnd = dest.second;
00525
00526 if (i == nThreads-1) {
00527 DEBUG_DEBUG("remapping in main thread, destUL: " << destUL << " area: " << dest.second - dest.first);
00528 transformImageAlphaIntern( src, srcAlpha,
00529 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor>(destStart, destEnd, dest.third),
00530 vigra::pair<AlphaImageIterator, AlphaAccessor>(destAStart, alpha.second),
00531 transform, pixelTransform, destUL, interp, warparound, prog);
00532 }
00533
00534 DEBUG_DEBUG("Waiting for threads to join");
00535 threads.join_all();
00536 DEBUG_DEBUG("Threads joined");
00537 }
00538
00539 template <class SrcImageIterator, class SrcAccessor,
00540 class DestImageIterator, class DestAccessor,
00541 class TRANSFORM,
00542 class PixelTransform,
00543 class AlphaImageIterator, class AlphaAccessor,
00544 class Interpolator>
00545 void transformImageInternMT(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00546 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00547 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00548 TRANSFORM & transform,
00549 PixelTransform & pixelTransform,
00550 vigra::Diff2D destUL,
00551 Interpolator interp,
00552 bool warparound,
00553 AppBase::MultiProgressDisplay & prog)
00554 {
00555
00556 unsigned int nThreads = ThreadManager::get().getNThreads();
00557
00558 vigra::Diff2D destSize = dest.second - dest.first;
00559
00560
00561 if (destSize.y < (int) nThreads) {
00562 nThreads = destSize.y;
00563 }
00564
00565 if (nThreads == 1) {
00566 transformImageIntern(src, dest, alpha, transform, pixelTransform,
00567 destUL, interp, warparound, prog);
00568 return;
00569 }
00570
00571 DEBUG_DEBUG("creating " << nThreads << " threads for remapping");
00572
00573 unsigned int chunkSize = destSize.y / nThreads;
00574
00575
00576
00577
00578 boost::thread_group threads;
00579
00580
00581 DestImageIterator destStart = dest.first;
00582 DestImageIterator destEnd = dest.second;
00583 destEnd.y -= destSize.y - chunkSize;
00584 AlphaImageIterator destAStart = alpha.first;
00585
00586 typedef TransformImageIntern<SrcImageIterator, SrcAccessor, DestImageIterator, DestAccessor,
00587 TRANSFORM, PixelTransform, AlphaImageIterator, AlphaAccessor, Interpolator> RFunctor;
00588
00589 std::vector< AppBase::DummyMultiProgressDisplay> dummyProgs(nThreads-1);
00590 unsigned int i;
00591 for (i = 0; i < nThreads-1; ++i) {
00592
00593 RFunctor t(src, vigra::triple<DestImageIterator, DestImageIterator, DestAccessor>(destStart, destEnd, dest.third),
00594 vigra::pair<AlphaImageIterator, AlphaAccessor>(destAStart, alpha.second),
00595 transform, pixelTransform, destUL, interp, warparound, dummyProgs[i]);
00596 boost::function0<void> f;
00597 f = t;
00598 DEBUG_DEBUG("Starting thread " << i);
00599 threads.create_thread(f);
00600
00601 destStart.y += chunkSize;
00602 destEnd.y += chunkSize;
00603 destAStart.y += chunkSize;
00604 destUL.y += chunkSize;
00605 }
00606
00607 destEnd = dest.second;
00608
00609 if (i == nThreads-1) {
00610 DEBUG_DEBUG("remapping in main thread, destUL: " << destUL << " area: " << dest.second - dest.first);
00611 transformImageIntern( src,
00612 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor>(destStart, destEnd, dest.third),
00613 vigra::pair<AlphaImageIterator, AlphaAccessor>(destAStart, alpha.second),
00614 transform, pixelTransform, destUL, interp, warparound, prog);
00615 }
00616
00617 DEBUG_DEBUG("Waiting for threads to join");
00618 threads.join_all();
00619 DEBUG_DEBUG("Threads joined");
00620 }
00621
00622
00647 template <class SrcImageIterator, class SrcAccessor,
00648 class DestImageIterator, class DestAccessor,
00649 class AlphaImageIterator, class AlphaAccessor,
00650 class TRANSFORM,
00651 class PixelTransform>
00652 void transformImage(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00653 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00654 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00655 vigra::Diff2D destUL,
00656 TRANSFORM & transform,
00657 PixelTransform & pixelTransform,
00658 bool warparound,
00659 Interpolator interpol,
00660 AppBase::MultiProgressDisplay & progress)
00661 {
00662 switch (interpol) {
00663 case INTERP_CUBIC:
00664 DEBUG_DEBUG("using cubic interpolator");
00665 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00666 vigra_ext::interp_cubic(), warparound,
00667 progress);
00668 break;
00669 case INTERP_SPLINE_16:
00670 DEBUG_DEBUG("interpolator: spline16");
00671 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00672 vigra_ext::interp_spline16(), warparound,
00673 progress);
00674 break;
00675 case INTERP_SPLINE_36:
00676 DEBUG_DEBUG("interpolator: spline36");
00677 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00678 vigra_ext::interp_spline36(), warparound,
00679 progress);
00680 break;
00681 case INTERP_SPLINE_64:
00682 DEBUG_DEBUG("interpolator: spline64");
00683 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00684 vigra_ext::interp_spline64(), warparound,
00685 progress);
00686 break;
00687 case INTERP_SINC_256:
00688 DEBUG_DEBUG("interpolator: sinc 256");
00689 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00690 vigra_ext::interp_sinc<8>(), warparound,
00691 progress);
00692 break;
00693 case INTERP_BILINEAR:
00694 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00695 vigra_ext::interp_bilin(), warparound,
00696 progress);
00697 break;
00698 case INTERP_NEAREST_NEIGHBOUR:
00699 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00700 vigra_ext::interp_nearest(), warparound,
00701 progress);
00702 break;
00703 case INTERP_SINC_1024:
00704 transformImageInternMT(src, dest, alpha, transform, pixelTransform, destUL,
00705 vigra_ext::interp_sinc<32>(), warparound,
00706 progress);
00707 break;
00708 }
00709 }
00710
00712 template <class SrcImageIterator, class SrcAccessor,
00713 class SrcAlphaIterator, class SrcAlphaAccessor,
00714 class DestImageIterator, class DestAccessor,
00715 class AlphaImageIterator, class AlphaAccessor,
00716 class TRANSFORM, class PixelTransform>
00717 void transformImageAlpha(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00718 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
00719 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00720 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00721 vigra::Diff2D destUL,
00722 TRANSFORM & transform,
00723 PixelTransform & pixelTransform,
00724 bool warparound,
00725 Interpolator interpol,
00726 AppBase::MultiProgressDisplay & progress)
00727 {
00728 switch (interpol) {
00729 case INTERP_CUBIC:
00730 DEBUG_DEBUG("using cubic interpolator");
00731 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00732 vigra_ext::interp_cubic(), warparound,
00733 progress);
00734 break;
00735 case INTERP_SPLINE_16:
00736 DEBUG_DEBUG("interpolator: spline16");
00737 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00738 vigra_ext::interp_spline16(), warparound,
00739 progress);
00740 break;
00741 case INTERP_SPLINE_36:
00742 DEBUG_DEBUG("interpolator: spline36");
00743 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00744 vigra_ext::interp_spline36(), warparound,
00745 progress);
00746 break;
00747 case INTERP_SPLINE_64:
00748 DEBUG_DEBUG("interpolator: spline64");
00749 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00750 vigra_ext::interp_spline64(), warparound,
00751 progress);
00752 break;
00753 case INTERP_SINC_256:
00754 DEBUG_DEBUG("interpolator: sinc 256");
00755 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00756 vigra_ext::interp_sinc<8>(), warparound,
00757 progress);
00758 break;
00759 case INTERP_BILINEAR:
00760 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00761 vigra_ext::interp_bilin(), warparound,
00762 progress);
00763 break;
00764 case INTERP_NEAREST_NEIGHBOUR:
00765 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00766 vigra_ext::interp_nearest(), warparound,
00767 progress);
00768 break;
00769 case INTERP_SINC_1024:
00770 transformImageAlphaInternMT(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00771 vigra_ext::interp_sinc<32>(), warparound,
00772 progress);
00773 break;
00774 }
00775 }
00776
00777 template <class T, int nr>
00778 void fillVector(T vec[3], T &val, int len)
00779 {
00780 for (int i=0; i<len; i++) vec[i] = val;
00781 }
00782
00783
00784 };
00785
00786 #endif // _VIGRA_EXT_IMAGETRANSFORMS_H