00001 #ifndef Impala_Core_Array_Pattern_FuncRecGenConv2dSep_h
00002 #define Impala_Core_Array_Pattern_FuncRecGenConv2dSep_h
00003 
00004 #include "Core/Array/Element/E1Cast.h"
00005 #include "Core/Array/Pattern/Categories.h"
00006 #include "Core/Array/Pattern/ArrayFunc.h"
00007 
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Array
00013 {
00014 namespace Pattern
00015 {
00016 
00017 
00018 
00047 template <class ArrayT, class KerArrayT, class ValT, class PixOpT, class RedOpT>
00048 static void
00049 FuncRecGenConv2dSep_Line_XdirSim(ArrayT* a, KerArrayT* ker, PixOpT& pixOp,
00050                                  RedOpT& redOp, ValT rightNorm, int y)
00051 {
00052     typedef typename ArrayT::StorType StorT;
00053     typedef typename ArrayT::ArithType ArithT;
00054     typedef typename KerArrayT::StorType KerStorT;
00055     typedef typename KerArrayT::ArithType KerArithT;
00056 
00057     int width = ArrayCW(a);
00058     int kerWidth = ArrayCW(ker);
00059     int kerBW = ArrayCW(ker) / 2;
00060     StorT* aPtr = ArrayCPB(a, -kerBW, y);
00061     KerArithT rNorm = Element::E1Cast(rightNorm, KerArithT());
00062     KerArithT result;
00063     int x;
00064     int scanSize = width + kerBW;
00065     
00066 
00067     
00068 
00069     for (x=0 ; x<scanSize ; x++)
00070     {
00071         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00072         result = pixOp.DoIt(PtrRead(aPtr, KerArithT()),
00073                             PtrRead(kPtr, KerArithT()));
00074         aPtr += ArrayT::ElemSize();
00075         kPtr += KerArrayT::ElemSize();
00076         for (int n=1 ; n<=kerBW ; n++)
00077         {
00078             redOp.DoIt(result, pixOp.DoIt(PtrRead(aPtr, KerArithT()),
00079                                           PtrRead(kPtr, KerArithT())));
00080             aPtr += ArrayT::ElemSize();
00081             kPtr += KerArrayT::ElemSize();
00082         }
00083         aPtr -= ArrayT::ElemSize();
00084         PtrWrite(aPtr, result);
00085         aPtr -= (kerBW-1) * ArrayT::ElemSize();
00086     }
00087 
00088     
00089 
00090     aPtr += (kerBW-1) * ArrayT::ElemSize();  
00091     KerArithT borderVal = PtrRead(aPtr, KerArithT());
00092     aPtr += ArrayT::ElemSize();
00093     borderVal = borderVal * rNorm;
00094     for (x=0 ; x<kerBW ; x++)
00095     {
00096         PtrWrite(aPtr, borderVal);
00097         aPtr += ArrayT::ElemSize();
00098     }
00099     aPtr -= kerBW * ArrayT::ElemSize();
00100 
00101     
00102 
00103     aPtr -= ArrayT::ElemSize();
00104 
00105     for (x=0 ; x<scanSize ; x++)
00106     {
00107         KerStorT* kPtr = ArrayCPB(ker, kerBW, 0);
00108         result = pixOp.DoIt(PtrRead(aPtr, KerArithT()),
00109                             PtrRead(kPtr, KerArithT()));
00110         aPtr += ArrayT::ElemSize();
00111         kPtr += KerArrayT::ElemSize();
00112         for (int n=1 ; n<=kerBW ; n++)
00113         {
00114             redOp.DoIt(result, pixOp.DoIt(PtrRead(aPtr, KerArithT()),
00115                                           PtrRead(kPtr, KerArithT())));
00116             aPtr += ArrayT::ElemSize();
00117             kPtr += KerArrayT::ElemSize();
00118         }
00119         aPtr -= (kerBW+1) * ArrayT::ElemSize();
00120         PtrWrite(aPtr, result);
00121         aPtr -= ArrayT::ElemSize();
00122     }
00123 }
00124 
00127 template <class ArrayT, class KerArrayT, class ArithT,
00128           class PixOpT, class RedOpT>
00129 static void
00130 FuncRecGenConv2dSep_Line_YdirSim(ArrayT* a, KerArrayT* ker, ArithT* ngbBuf,
00131                                  PixOpT& pixOp, RedOpT& redOp,
00132                                  ArithT bottomNorm, int x)
00133 {
00134     typedef typename ArrayT::StorType StorT;
00135     typedef typename KerArrayT::StorType KerStorT;
00136 
00137     int height = ArrayCH(a);
00138     int kerWidth = ArrayCW(ker);
00139     int kerBW = ArrayCW(ker) / 2;
00140     StorT* aPtr = ArrayCPB(a, x, -kerBW);
00141     int incY = ArrayInc(a, 0, 1);
00142     ArithT result;
00143     ArithT* ngbPtr = ngbBuf;
00144     int y, n;
00145     int scanSize = height+kerBW;
00146     
00147 
00148     
00149 
00150     for (n=0 ; n<kerBW ; n++)
00151     {
00152         ngbBuf[n] =  PtrRead(aPtr, ArithT());
00153         aPtr += incY;
00154     }
00155 
00156     for (y=0 ; y<scanSize ; y++)
00157     {
00158         ngbPtr[kerBW] =  PtrRead(aPtr, ArithT());
00159         aPtr += incY;
00160         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00161         result = pixOp.DoIt(ngbPtr[0], PtrRead(kPtr, ArithT()));
00162         kPtr += KerArrayT::ElemSize();
00163         for (n=1 ; n<=kerBW ; n++)
00164         {
00165             redOp.DoIt(result, pixOp.DoIt(ngbPtr[n], PtrRead(kPtr, ArithT())));
00166             kPtr += KerArrayT::ElemSize();
00167         }
00168         ngbPtr[kerBW] = result;
00169         ngbPtr++;
00170     }
00171 
00172     
00173 
00174     ngbPtr += kerBW-1; 
00175     ArithT borderVal = ngbPtr[0];
00176     borderVal = borderVal * bottomNorm;
00177     ngbPtr++;
00178     for (y=0 ; y<kerBW ; y++)
00179         ngbPtr[y] = borderVal;
00180     aPtr += incY * kerBW;
00181 
00182     
00183 
00184     aPtr -= incY * (kerBW+1);
00185     ngbPtr -= 1;
00186 
00187     for (y=0 ; y<scanSize ; y++)
00188     {
00189         KerStorT* kPtr = ArrayCPB(ker, kerBW, 0);
00190         result = pixOp.DoIt(ngbPtr[0], PtrRead(kPtr, ArithT()));
00191         kPtr += KerArrayT::ElemSize();
00192         for (n=1 ; n<=kerBW ; n++)
00193         {
00194             redOp.DoIt(result, pixOp.DoIt(ngbPtr[n], PtrRead(kPtr, ArithT())));
00195             kPtr += KerArrayT::ElemSize();
00196         }
00197         *ngbPtr-- = result;
00198         PtrWrite(aPtr, result);
00199         aPtr -= incY;
00200     }
00201 }
00202 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00273 
00274 
00275 
00277 
00281 template <class ArrayT, class KerArrayT, class ValT, class PixOpT, class RedOpT>
00282 void
00283 FuncRecGenConv2dSep_XirSim(ArrayT* a, KerArrayT* ker, PixOpT& pixOp,
00284                            RedOpT& redOp, ValT rightNorm)
00285 {
00286     int height = ArrayCH(a);
00287     for (int y=0 ; y<height ; y++)
00288         FuncRecGenConv2dSep_Line_XdirSim(a, ker, pixOp, redOp, rightNorm, y);
00289 }
00290 
00293 template <class ArrayT, class KerArrayT, class ValT, class PixOpT, class RedOpT>
00294 void
00295 FuncRecGenConv2dSep_YdirSim(ArrayT* a, KerArrayT* ker, PixOpT& pixOp,
00296                             RedOpT& redOp, ValT bottomNorm)
00297 {
00298     typedef typename KerArrayT::ArithType KerArithT;
00299     KerArithT* ngbBuf = new KerArithT[ArrayH(a)];
00300     KerArithT bN = Element::E1Cast(bottomNorm, KerArithT());
00301 
00302     int width = ArrayCW(a);
00303     for (int x=0 ; x<width ; x++)
00304         FuncRecGenConv2dSep_Line_YdirSim(a, ker, ngbBuf, pixOp, redOp, bN, x);
00305 
00306     delete ngbBuf;
00307 }
00308 
00309 
00359 
00360 
00361 
00364 template <class ArrayT, class KerArrayT, class ValT, class PixOpT, class RedOpT>
00365 void
00366 FuncRecGenConv2dSepDispatch_H(ArrayT* a, KerArrayT* ker, PixOpT& pixOp,
00367                               RedOpT& redOp, ValT rightNorm)
00368 {
00369     FuncRecGenConv2dSep_XirSim(a, ker, pixOp, redOp, rightNorm);
00370 }
00371 
00374 template <class ArrayT, class KerArrayT, class ValT, class PixOpT, class RedOpT>
00375 void
00376 FuncRecGenConv2dSepDispatch_V(ArrayT* a, KerArrayT* ker,PixOpT& pixOp,
00377                               RedOpT& redOp, ValT bottomNorm, bool buffered)
00378 {
00379     
00380 
00381 
00382 
00383 
00384 
00385     FuncRecGenConv2dSep_YdirSim(a, ker, pixOp, redOp, bottomNorm);
00386 }
00387 
00388 } 
00389 } 
00390 } 
00391 } 
00392 
00393 #endif