Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages
hugin_base/vigra_ext/ImageTransforms.h
Go to the documentation of this file.00001 // -*- c-basic-offset: 4 -*- 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 // create dest y iterator 00128 DestImageIterator yd(dest.first); 00129 // create mask y iterator 00130 AlphaImageIterator ydm(alpha.first); 00131 // loop over the image and transform 00132 typename SrcAccessor::value_type tempval; 00133 00134 for(int y=ystart; y < yend; ++y, ++yd.y, ++ydm.y) 00135 { 00136 // create x iterators 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 // apply pixel transform and write to output 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 // create dest y iterator 00241 DestImageIterator yd(dest.first); 00242 // create dist y iterator 00243 AlphaImageIterator ydist(alpha.first); 00244 00245 typename SrcAccessor::value_type tempval; 00246 00247 typename SrcAlphaAccessor::value_type alphaval; 00248 00249 // loop over the image and transform 00250 for(int y=ystart; y < yend; ++y, ++yd.y, ++ydist.y) 00251 { 00252 // create x iterators 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 // try to interpolate. 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 // point outside of image or mask 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 // FIXME: use d & e here. 00384 vigra::Diff2D srcMiddle = srcSize / 2; 00385 00386 // vigra::BilinearInterpolatingAccessor<SrcAccessor, typename SrcAccessor::value_type> interpol(src.third); 00387 00388 //InterpolatingAccessor(src.third, interp); 00389 vigra_ext::InterpolatingAccessor<SrcAccessor, 00390 typename SrcAccessor::value_type, 00391 Interpolator> interpol(src.third, interp); 00392 00393 00394 // vigra::BilinearInterpolatingAccessor<SrcAccessor, typename SrcAccessor::value_type> interpol(src.third); 00395 00396 // vigra::BilinearInterpolatingAccessor interpol(src.third); 00397 00398 // create dest y iterator 00399 DestImageIterator yd(dest.first); 00400 // create dist y iterator 00401 DistImageIterator ydist(centerDist.first); 00402 // loop over the image and transform 00403 for(int y=ystart; y < yend; ++y, ++yd.y, ++ydist.y) 00404 { 00405 // create x iterators 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 // make sure that the interpolator doesn't 00413 // access pixels outside.. Should we introduce 00414 // some sort of border treatment? 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 // save an invalid distance 00422 *xdist = FLT_MAX; 00423 } 00424 // nothing.. 00425 } else { 00426 // cout << x << "," << y << " -> " << sx << "," << sy << " " << std::endl; 00427 00428 // nearest neighbour 00429 // *xd = src.third(src.first, vigra::Diff2D((int)round(sx), (int)round(sy))); 00430 // use given interpolator function. 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 // divide output image into multiple areas 00473 unsigned int nThreads = ThreadManager::get().getNThreads(); 00474 00475 vigra::Diff2D destSize = dest.second - dest.first; 00476 00477 // limit amount of threads if only a few lines are given. 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 // DGSW FIXME - Unreferenced 00492 // unsigned int lastChunkSize = destSize.y - (nThreads-1) * chunkSize; 00493 00494 // create a threads to remap each area 00495 boost::thread_group threads; 00496 00497 // create first thread with progress counter 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::DummyMultiProgressDispaly> 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 // last chunk 00524 destEnd = dest.second; 00525 // remap last chunk in current thread. 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 // divide output image into multiple areas 00556 unsigned int nThreads = ThreadManager::get().getNThreads(); 00557 00558 vigra::Diff2D destSize = dest.second - dest.first; 00559 00560 // limit amount of threads if only a few lines are given. 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 // DGSW FIXME - Unreferenced 00575 // unsigned int lastChunkSize = destSize.y - (nThreads-1) * chunkSize; 00576 00577 // create a threads to remap each area 00578 boost::thread_group threads; 00579 00580 // create first thread with progress counter 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::DummyMultiProgressDispaly> 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 // last chunk 00607 destEnd = dest.second; 00608 // remap last chunk in current thread. 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 }; // namespace 00785 00786 #endif // _VIGRA_EXT_IMAGETRANSFORMS_H
1.3.9.1