00001 #ifndef Impala_Core_Array_Pattern_FuncQueueBased_h
00002 #define Impala_Core_Array_Pattern_FuncQueueBased_h
00003
00004 #include <iostream>
00005 #include "Core/Array/Pattern/Categories.h"
00006 #include "Core/Array/Pattern/ArrayFunc.h"
00007 #include "Core/Array/Pattern/PtrFunc.h"
00008 #include "Core/Geometry/PointZ.h"
00009 #include "Core/Array/Pattern/FcvArray.h"
00010 #include "Core/Array/Pattern/QAction.h"
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Array
00017 {
00018 namespace Pattern
00019 {
00020
00021
00022
00023 template <class DstArrayT, class SrcArrayT, class MaskArrayT, class VecPointT,
00024 class VecNeighborT, class NeighborsT>
00025 inline void
00026 FuncQueueBased_FillNeighborValues(DstArrayT* dst, SrcArrayT* src,
00027 MaskArrayT* mask, Geometry::PointZ centralPoint,
00028 const VecPointT& neighborCoordinates,
00029 VecNeighborT& vecneighbors, NeighborsT)
00030 {
00031 typedef typename DstArrayT::StorType DstStorT;
00032 typedef typename DstArrayT::ArithType DstArithT;
00033 typedef typename SrcArrayT::StorType SrcStorT;
00034 typedef typename SrcArrayT::ArithType SrcArithT;
00035 typedef typename MaskArrayT::StorType MaskStorT;
00036 typedef typename MaskArrayT::ArithType MaskArithT;
00037
00038 vecneighbors.clear();
00039 int imgsizex = ArrayCW(dst);
00040 int imgsizey = ArrayCW(dst);
00041 for (int i=0; i<neighborCoordinates.size(); i++)
00042 {
00043 Geometry::PointZ p = neighborCoordinates[i]+centralPoint;
00044 int tempx=p.mX, tempy=p.mY;
00045 if (tempx>=0 && tempy>=0 && tempx<imgsizex && tempy<imgsizey)
00046 {
00047 DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00048 SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00049 SrcStorT* mPtr = ArrayCPB(mask, tempx, tempy);
00050 NeighborsT neighbors;
00051 neighbors.point=p;
00052 neighbors.arith=PtrRead(dPtr, DstArithT());
00053 neighbors.img=PtrRead(sPtr, SrcArithT());
00054 neighbors.mask=PtrRead(mPtr, MaskArithT());
00055 vecneighbors.push_back(neighbors);
00056 }
00057 }
00058 }
00059
00060
00061 template <class DstArrayT, class SrcArrayT, class VecPointT,
00062 class VecNeighborT, class NeighborsT>
00063 inline void
00064 FuncQueueBased_FillNeighborValues(DstArrayT* dst, SrcArrayT* src,
00065 Geometry::PointZ centralPoint,
00066 const VecPointT& neighborCoordinates,
00067 VecNeighborT& vecneighbors, NeighborsT)
00068 {
00069 typedef typename DstArrayT::StorType DstStorT;
00070 typedef typename DstArrayT::ArithType DstArithT;
00071 typedef typename SrcArrayT::StorType SrcStorT;
00072 typedef typename SrcArrayT::ArithType SrcArithT;
00073
00074 vecneighbors.clear();
00075 int imgsizex = ArrayCW(dst);
00076 int imgsizey = ArrayCW(dst);
00077 for (int i=0; i<neighborCoordinates.size(); i++)
00078 {
00079 Geometry::PointZ p = neighborCoordinates[i]+centralPoint;
00080 int tempx=p.mX, tempy=p.mY;
00081 if (tempx>=0 && tempy>=0 && tempx<imgsizex && tempy<imgsizey)
00082 {
00083 DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00084 SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00085 NeighborsT neighbors;
00086 neighbors.point=p;
00087 neighbors.arith=PtrRead(dPtr, DstArithT());
00088 neighbors.img=PtrRead(sPtr, SrcArithT());
00089 vecneighbors.push_back(neighbors);
00090 }
00091 }
00092 }
00093
00094 template <class VecPointT>
00095 void
00096 FuncQueueBased_ComputeNeighbors(VecPointT& neighborCoordinates,
00097 int connectivity, int radiusSqr)
00098 {
00099 neighborCoordinates.clear();
00100 if (radiusSqr<0 && connectivity==4)
00101 radiusSqr = 1;
00102 if (radiusSqr<0 && connectivity==8)
00103 radiusSqr = 2;
00104
00105 int radius;
00106 for (radius=0 ; radius*radius <= radiusSqr ; radius++)
00107 ;
00108 for (int y=-radius ; y<=radius ; y++)
00109 {
00110 for (int x=-radius ; x<=radius ; x++)
00111 {
00112 if (x||y)
00113 {
00114 if (x*x+y*y <= radiusSqr)
00115 neighborCoordinates.push_back(Geometry::PointZ(x,y));
00116 }
00117 }
00118 }
00119 }
00120
00121
00122 template <class DstArrayT, class SrcArrayT, class MaskArrayT, class FunctorT>
00123 void
00124 FuncQueueBasedDispatch(DstArrayT* dst, SrcArrayT* src, MaskArrayT* mask,
00125 FunctorT& functor, int connectivity, int radiusSqr)
00126 {
00127 typedef typename DstArrayT::StorType DstStorT;
00128 typedef typename DstArrayT::ArithType DstArithT;
00129 typedef typename SrcArrayT::StorType SrcStorT;
00130 typedef typename SrcArrayT::ArithType SrcArithT;
00131 typedef typename MaskArrayT::StorType MaskStorT;
00132 typedef typename MaskArrayT::ArithType MaskArithT;
00133
00134 typedef typename FunctorT::PointValueT PointValueT;
00135 typedef typename FunctorT::QT QT;
00136 typedef typename FunctorT::NeighborsT NeighborsT;
00137 typedef typename FunctorT::VecNeighborsT VecNeighborsT;
00138
00139 typedef Pattern::FcvArray<Geometry::PointZ> VecPointT;
00140
00141 QT theQueue;
00142 int imgsizex = ArrayCW(dst);
00143 int imgsizey = ArrayCH(dst);
00144
00145
00146 {
00147 for (int y=0 ; y<imgsizey ; y++)
00148 {
00149 DstStorT* dPtr = ArrayCPB(dst, 0, y);
00150 SrcStorT* sPtr = ArrayCPB(src, 0, y);
00151 SrcStorT* mPtr = ArrayCPB(mask, 0, y);
00152 for (int x=0 ; x<imgsizex ; x++)
00153 {
00154 PointValueT vp;
00155 Geometry::PointZ p(x, y);
00156 vp.point=p;
00157 DstArithT d = PtrRead(dPtr, DstArithT());
00158 SrcArithT s = PtrRead(sPtr, SrcArithT());
00159 MaskArithT m = PtrRead(mPtr, MaskArithT());
00160 bool q = functor.GlobalPixelInit(vp, d, s, m);
00161 if (q)
00162 theQueue.push(vp);
00163 PtrWrite(dPtr, d);
00164 dPtr += DstArrayT::ElemSize();
00165 sPtr += SrcArrayT::ElemSize();
00166 mPtr += MaskArrayT::ElemSize();
00167 }
00168 }
00169 }
00170
00171
00172 VecPointT neighborCoordinates;
00173 FuncQueueBased_ComputeNeighbors(neighborCoordinates, connectivity, radiusSqr);
00174
00175
00176
00177 Geometry::PointZ startpoint(0,0);
00178 VecNeighborsT vecneighbors;
00179
00180
00181 do
00182 {
00183
00184
00185 {
00186 bool freshstart = functor.WantFreshStartLocalPixelInit();
00187 if (freshstart)
00188 {
00189 startpoint.mX=0;
00190 startpoint.mY=0;
00191 }
00192 bool continueloop=true;
00193 int x=startpoint.mX;
00194 int y=startpoint.mY;
00195 bool wenttonewpoint=false;
00196 if (wenttonewpoint)
00197 y=0;
00198 for (; y<imgsizey; y++)
00199 {
00200 if (wenttonewpoint)
00201 x=0;
00202 DstStorT* dPtr = ArrayCPB(dst, x, y);
00203 SrcStorT* sPtr = ArrayCPB(src, x, y);
00204 SrcStorT* mPtr = ArrayCPB(mask, x, y);
00205 for (; x<imgsizex; x++)
00206 {
00207 if (!wenttonewpoint)
00208 {
00209 wenttonewpoint=true;
00210 }
00211 PointValueT vp;
00212 vp.point.mX = x;
00213 vp.point.mY = y;
00214 DstArithT d = PtrRead(dPtr, DstArithT());
00215 SrcArithT s = PtrRead(sPtr, SrcArithT());
00216 MaskArithT m = PtrRead(mPtr, MaskArithT());
00217 bool q = functor.LocalPixelInit(vp, d, s, m, continueloop);
00218 if (q)
00219 theQueue.push(vp);
00220 PtrWrite(dPtr, d);
00221 if (!continueloop)
00222 break;
00223 dPtr += DstArrayT::ElemSize();
00224 sPtr += SrcArrayT::ElemSize();
00225 mPtr += MaskArrayT::ElemSize();
00226 }
00227 if (!continueloop)
00228 break;
00229 }
00230
00231 startpoint.mX = x;
00232 startpoint.mY = y;
00233
00234 }
00235
00236
00237 {
00238 while (!theQueue.empty())
00239 {
00240 PointValueT vp(theQueue.top());
00241 theQueue.pop();
00242
00243
00244 {
00245 int tempx=vp.point.mX, tempy=vp.point.mY;
00246 DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00247 SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00248 SrcStorT* mPtr = ArrayCPB(mask, tempx, tempy);
00249 functor.First(vp, PtrRead(dPtr, DstArithT()),
00250 PtrRead(sPtr, SrcArithT()),
00251 PtrRead(mPtr, MaskArithT()));
00252 }
00253
00254
00255
00256
00257 {
00258 FuncQueueBased_FillNeighborValues(dst, src, mask, vp.point,
00259 neighborCoordinates,
00260 vecneighbors,
00261 NeighborsT());
00262
00263 functor.Calculate(vecneighbors);
00264 }
00265
00266
00267
00268
00269 {
00270 QAction action;
00271 while ((action=functor.Result())!=STOP)
00272 {
00273 switch (action)
00274 {
00275 case QUEUE:
00276 {
00277 PointValueT vp;
00278 functor.GetItemToQueue(vp);
00279 theQueue.push(vp);
00280 }
00281 break;
00282 case REMOVE:
00283 {
00284 PointValueT low, high;
00285 functor.GetItemToRemove(low, high);
00286 typename QT::iterator lowiter=theQueue.lower_bound(low);
00287 typename QT::iterator highiter=theQueue.after_upper_bound(high);
00288 for (typename QT::iterator iter=lowiter; iter!=highiter; iter++)
00289 {
00290 bool k=functor.KillThisOne(*iter);
00291 if (k)
00292 {
00293 theQueue.erase(iter);
00294 break;
00295 }
00296 }
00297 }
00298 break;
00299 case WRITE:
00300 {
00301 Geometry::PointZ point;
00302 DstArithT arith;
00303 functor.GetItemToWrite(point, arith);
00304 DstStorT* dPtr = ArrayCPB(dst, point.mX, point.mY);
00305 PtrWrite(dPtr, arith);
00306 }
00307 break;
00308 default:
00309 std::cerr << "ERROR switch (action) default:" << std::endl;
00310 };
00311 }
00312 }
00313 }
00314 }
00315 }
00316 while (functor.WantAnotherLoop());
00317 }
00318
00319
00320 template <class DstArrayT, class SrcArrayT, class FunctorT>
00321 void
00322 FuncQueueBasedDispatch(DstArrayT* dst, SrcArrayT* src,
00323 FunctorT& functor, int connectivity, int radiusSqr)
00324 {
00325 typedef typename DstArrayT::StorType DstStorT;
00326 typedef typename DstArrayT::ArithType DstArithT;
00327 typedef typename SrcArrayT::StorType SrcStorT;
00328 typedef typename SrcArrayT::ArithType SrcArithT;
00329
00330 typedef typename FunctorT::PointValueT PointValueT;
00331 typedef typename FunctorT::QT QT;
00332 typedef typename FunctorT::NeighborsT NeighborsT;
00333 typedef typename FunctorT::VecNeighborsT VecNeighborsT;
00334
00335 typedef Pattern::FcvArray<Geometry::PointZ> VecPointT;
00336
00337 QT theQueue;
00338 int imgsizex = ArrayCW(dst);
00339 int imgsizey = ArrayCH(dst);
00340
00341
00342 {
00343 for (int y=0 ; y<imgsizey ; y++)
00344 {
00345 DstStorT* dPtr = ArrayCPB(dst, 0, y);
00346 SrcStorT* sPtr = ArrayCPB(src, 0, y);
00347 for (int x=0 ; x<imgsizex ; x++)
00348 {
00349 PointValueT vp;
00350 Geometry::PointZ p(x, y);
00351 vp.point=p;
00352 DstArithT d = PtrRead(dPtr, DstArithT());
00353 SrcArithT s = PtrRead(sPtr, SrcArithT());
00354 bool q = functor.GlobalPixelInit(vp, d, s);
00355 if (q)
00356 theQueue.push(vp);
00357 PtrWrite(dPtr, d);
00358 dPtr += DstArrayT::ElemSize();
00359 sPtr += SrcArrayT::ElemSize();
00360 }
00361 }
00362 }
00363
00364
00365 VecPointT neighborCoordinates;
00366 FuncQueueBased_ComputeNeighbors(neighborCoordinates, connectivity, radiusSqr);
00367
00368
00369
00370 Geometry::PointZ startpoint(0,0);
00371 VecNeighborsT vecneighbors;
00372
00373
00374 do
00375 {
00376
00377 {
00378 bool freshstart = functor.WantFreshStartLocalPixelInit();
00379 if (freshstart)
00380 {
00381 startpoint.mX=0;
00382 startpoint.mY=0;
00383 }
00384 bool continueloop=true;
00385 int x=startpoint.mX;
00386 int y=startpoint.mY;
00387 bool wenttonewpoint=false;
00388 if (wenttonewpoint)
00389 y=0;
00390 for (; y<imgsizey; y++)
00391 {
00392 if (wenttonewpoint)
00393 x=0;
00394 DstStorT* dPtr = ArrayCPB(dst, x, y);
00395 SrcStorT* sPtr = ArrayCPB(src, x, y);
00396 for (; x<imgsizex; x++)
00397 {
00398 if (!wenttonewpoint)
00399 {
00400 wenttonewpoint=true;
00401 }
00402 PointValueT vp;
00403 vp.point.mX=x;
00404 vp.point.mY=y;
00405 DstArithT d = PtrRead(dPtr, DstArithT());
00406 SrcArithT s = PtrRead(sPtr, SrcArithT());
00407 bool q = functor.LocalPixelInit(vp, d, s, continueloop);
00408 if (q)
00409 theQueue.push(vp);
00410 PtrWrite(dPtr, d);
00411 if (!continueloop)
00412 break;
00413 dPtr += DstArrayT::ElemSize();
00414 sPtr += SrcArrayT::ElemSize();
00415 }
00416 if (!continueloop)
00417 break;
00418 }
00419
00420 startpoint.mX=x;
00421 startpoint.mY=y;
00422
00423 }
00424
00425
00426 {
00427 while (!theQueue.empty())
00428 {
00429 PointValueT vp(theQueue.top());
00430 theQueue.pop();
00431
00432
00433 {
00434 int tempx=vp.point.mX, tempy=vp.point.mY;
00435 DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00436 SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00437 functor.First(vp, PtrRead(dPtr, DstArithT()),
00438 PtrRead(sPtr, SrcArithT()));
00439 }
00440
00441
00442
00443
00444 {
00445 FuncQueueBased_FillNeighborValues(dst, src, vp.point,
00446 neighborCoordinates,
00447 vecneighbors,
00448 NeighborsT());
00449
00450 functor.Calculate(vecneighbors);
00451 }
00452
00453
00454
00455
00456 {
00457 QAction action;
00458 while ((action=functor.Result())!=STOP)
00459 {
00460 switch (action)
00461 {
00462 case QUEUE:
00463 {
00464 PointValueT vp;
00465 functor.GetItemToQueue(vp);
00466 theQueue.push(vp);
00467 }
00468 break;
00469 case REMOVE:
00470 {
00471 PointValueT low, high;
00472 functor.GetItemToRemove(low, high);
00473 typename QT::iterator lowiter=theQueue.lower_bound(low);
00474 typename QT::iterator highiter=theQueue.after_upper_bound(high);
00475 for (typename QT::iterator iter=lowiter; iter!=highiter; iter++)
00476 {
00477 bool k=functor.KillThisOne(*iter);
00478 if (k)
00479 {
00480 theQueue.erase(iter);
00481 break;
00482 }
00483 }
00484 }
00485 break;
00486 case WRITE:
00487 {
00488 Geometry::PointZ point;
00489 DstArithT arith;
00490 functor.GetItemToWrite(point, arith);
00491 DstStorT* dPtr = ArrayCPB(dst, point.mX, point.mY);
00492 PtrWrite(dPtr, arith);
00493 }
00494 break;
00495 default:
00496 std::cerr << "ERROR switch (action) default:" << std::endl;
00497 };
00498 }
00499 }
00500 }
00501 }
00502 }
00503 while (functor.WantAnotherLoop());
00504 }
00505
00506 }
00507 }
00508 }
00509 }
00510
00511 #endif