00001 #ifndef Impala_Core_Array_Pattern_FuncGenConv2dSep_h
00002 #define Impala_Core_Array_Pattern_FuncGenConv2dSep_h
00003 
00004 #include "Core/Array/Pattern/Categories.h"
00005 #include "Core/Array/Pattern/ArrayFunc.h"
00006 
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013 namespace Pattern
00014 {
00015 
00016 
00017 
00073 template<class DstStorT, class SrcStorT, class KerStorT, class KerArithT,
00074          class PixOpT, class RedOpT>
00075 static inline void
00076 FuncGenConv2dSep_Pix_Xdir(DstStorT* dPtr, SrcStorT* sPtr, KerStorT* kPtr,
00077                           int kerWidth, int srcInc, int kerInc, PixOpT& pixOp,
00078                           RedOpT& redOp, KerArithT neutralElement,
00079                           TagCallValue dummy)
00080 {
00081     KerArithT result(neutralElement);
00082     for (int k=0; k<kerWidth; k++)
00083     {
00084         redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00085                                       PtrRead(kPtr, KerArithT())));
00086         sPtr += srcInc;
00087         kPtr += kerInc;
00088     }
00089     PtrWrite(dPtr, result);
00090 }
00091 
00097 template<class DstStorT, class SrcStorT, class KerStorT, class KerArithT,
00098          class PixOpT, class RedOpT>
00099 static inline void
00100 FuncGenConv2dSep_Pix_Ydir(DstStorT* dPtr, SrcStorT* sPtr, KerStorT* kPtr,
00101                           int kerWidth, int srcInc, int kerInc, PixOpT& pixOp,
00102                           RedOpT& redOp, KerArithT neutralElement,
00103                           TagCallValue dummy)
00104 {
00105     KerArithT result(neutralElement);
00106     for (int k=0; k<kerWidth; k++)
00107     {
00108         redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00109                                       PtrRead(kPtr, KerArithT())));
00110         sPtr += srcInc;
00111         kPtr += kerInc;
00112     }
00113     PtrWrite(dPtr, result);
00114 }
00115 
00117 
00118 
00119 
00121 
00128 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00129          class PixOpT, class RedOpT>
00130 static void
00131 FuncGenConv2dSep_Line_Xdir(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00132                            PixOpT& pixOp, RedOpT& redOp, int y,
00133                            TagCallValue tag)
00134 {
00135     typedef typename DstArrayT::StorType DstStorT;
00136     typedef typename DstArrayT::ArithType DstArithT;
00137     typedef typename SrcArrayT::StorType SrcStorT;
00138     typedef typename SrcArrayT::ArithType SrcArithT;
00139     typedef typename KerArrayT::StorType KerStorT;
00140     typedef typename KerArrayT::ArithType KerArithT;
00141 
00142     int width = ArrayCW(dst);
00143     int kerWidth = ArrayCW(ker);
00144     int kerBW = ArrayCW(ker) / 2;
00145     KerArithT neutralElement = RedOpT::NeutralElement();
00146     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00147     SrcStorT* sPtr = ArrayCPB(src, -kerBW, y);
00148     KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00149     for (int x=0 ; x<width ; x++)
00150     {
00151         FuncGenConv2dSep_Pix_Xdir(dPtr, sPtr, kPtr, kerWidth,
00152                                   SrcArrayT::ElemSize(), KerArrayT::ElemSize(),
00153                                   pixOp, redOp, neutralElement, tag);
00154         dPtr += DstArrayT::ElemSize();
00155         sPtr += SrcArrayT::ElemSize();
00156     }
00157 }
00158 
00167 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00168          class PixOpT, class RedOpT>
00169 static void
00170 FuncGenConv2dSep_Line_XdirInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00171                               PixOpT& pixOp, RedOpT& redOp, int y,
00172                               TagCallPointer dummy)
00173 {
00174     typedef typename DstArrayT::StorType DstStorT;
00175     typedef typename SrcArrayT::StorType SrcStorT;
00176     typedef typename KerArrayT::StorType KerStorT;
00177 
00178     int width = ArrayCW(dst);
00179     int kerWidth = ArrayCW(ker);
00180     int kerBW = ArrayCW(ker) / 2;
00181     KerStorT buf[KerArrayT::ElemSize()];
00182     for (int x=0 ; x<width ; x++)
00183     {
00184         DstStorT* dPtr = ArrayCPB(dst, x, y);
00185         SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, y);
00186         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00187         redOp.setNeutral(dPtr);
00188         for (int k=0; k<kerWidth; k++)
00189         {
00190             pixOp.DoIt(buf, sPtr, kPtr);
00191             sPtr += SrcArrayT::ElemSize();
00192             kPtr += KerArrayT::ElemSize();
00193             redOp.DoIt(dPtr, buf);
00194         }
00195     }
00196 }
00197 
00206 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00207          class PixOpT, class RedOpT>
00208 static void
00209 FuncGenConv2dSep_Line_XdirInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00210                               PixOpT& pixOp, RedOpT& redOp, int y,
00211                               TagCallValue dummy)
00212 {
00213     typedef typename DstArrayT::StorType DstStorT;
00214     typedef typename DstArrayT::ArithType DstArithT;
00215     typedef typename SrcArrayT::StorType SrcStorT;
00216     typedef typename SrcArrayT::ArithType SrcArithT;
00217     typedef typename KerArrayT::StorType KerStorT;
00218     typedef typename KerArrayT::ArithType KerArithT;
00219 
00220     int width = ArrayCW(dst);
00221     int kerWidth = ArrayCW(ker);
00222     int kerBW = ArrayCW(ker) / 2;
00223     KerArithT neutralElement = RedOpT::NeutralElement();
00224     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00225     for (int x=0 ; x<width ; x++)
00226     {
00227         SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, y);
00228         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00229         KerArithT result(neutralElement);
00230         for (int k=0; k<kerWidth; k++)
00231         {
00232             redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00233                                           PtrRead(kPtr, KerArithT())));
00234             sPtr += SrcArrayT::ElemSize();
00235             kPtr += KerArrayT::ElemSize();
00236         }
00237         PtrWrite(dPtr, result);
00238         dPtr += DstArrayT::ElemSize();
00239     }
00240 }
00241 
00270 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00271          class PixOpT, class RedOpT>
00272 static void
00273 FuncGenConv2dSep_Line_YdirNaiInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00274                                  PixOpT& pixOp, RedOpT& redOp, int x,
00275                                  TagCallPointer dummy)
00276 {
00277     typedef typename DstArrayT::StorType DstStorT;
00278     typedef typename SrcArrayT::StorType SrcStorT;
00279     typedef typename KerArrayT::StorType KerStorT;
00280 
00281     int height = ArrayCH(dst);
00282     int kerWidth = ArrayCW(ker);
00283     int kerBW = ArrayCW(ker) / 2;
00284     int srcInc = ArrayInc(src, 0, 1);
00285     KerStorT buf[KerArrayT::ElemSize()];
00286     for (int y=0 ; y<height ; y++)
00287     {
00288         DstStorT* dPtr = ArrayCPB(dst, x, y);
00289         SrcStorT* sPtr = ArrayCPB(src, x, -kerBW + y);
00290         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00291         redOp.setNeutral(dPtr);
00292         for (int k=0; k<kerWidth; k++)
00293         {
00294             pixOp.DoIt(buf, sPtr, kPtr);
00295             sPtr += srcInc;
00296             kPtr += KerArrayT::ElemSize();
00297             redOp.DoIt(dPtr, buf);
00298         }
00299     }
00300 }
00301 
00304 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00305          class PixOpT, class RedOpT>
00306 static void
00307 FuncGenConv2dSep_Line_YdirNaiInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00308                                  PixOpT& pixOp, RedOpT& redOp, int x,
00309                                  TagCallValue dummy)
00310 {
00311     typedef typename DstArrayT::StorType DstStorT;
00312     typedef typename DstArrayT::ArithType DstArithT;
00313     typedef typename SrcArrayT::StorType SrcStorT;
00314     typedef typename SrcArrayT::ArithType SrcArithT;
00315     typedef typename KerArrayT::StorType KerStorT;
00316     typedef typename KerArrayT::ArithType KerArithT;
00317 
00318     int height = ArrayCH(dst);
00319     int kerWidth = ArrayCW(ker);
00320     int kerBW = ArrayCW(ker) / 2;
00321     int srcInc = ArrayInc(src, 0, 1);
00322     KerArithT neutralElement = RedOpT::NeutralElement();
00323     for (int y=0 ; y<height ; y++)
00324     {
00325         DstStorT* dPtr = ArrayCPB(dst, x, y);
00326         SrcStorT* sPtr = ArrayCPB(src, x, -kerBW + y);
00327         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00328         KerArithT result(neutralElement);
00329         for (int k=0; k<kerWidth; k++)
00330         {
00331             redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00332                                           PtrRead(kPtr, KerArithT())));
00333             sPtr += srcInc;
00334             kPtr += KerArrayT::ElemSize();
00335         }
00336         PtrWrite(dPtr, result);
00337     }
00338 }
00339 
00342 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00343          class PixOpT, class RedOpT>
00344 static void
00345 FuncGenConv2dSep_Line_YdirSim(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00346                               PixOpT& pixOp, RedOpT& redOp, int y,
00347                               TagCallValue tag)
00348 {
00349     typedef typename DstArrayT::StorType DstStorT;
00350     typedef typename DstArrayT::ArithType DstArithT;
00351     typedef typename SrcArrayT::StorType SrcStorT;
00352     typedef typename SrcArrayT::ArithType SrcArithT;
00353     typedef typename KerArrayT::StorType KerStorT;
00354     typedef typename KerArrayT::ArithType KerArithT;
00355 
00356     int width = ArrayCW(dst);
00357     int kerWidth = ArrayCW(ker);
00358     int kerBW = ArrayCW(ker) / 2;
00359     int srcInc = ArrayInc(src, 0, 1);
00360     KerArithT neutralElement = RedOpT::NeutralElement();
00361     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00362     SrcStorT* sPtr = ArrayCPB(src, 0, -kerBW + y);
00363     KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00364     for (int x=0 ; x<width ; x++)
00365     {
00366         FuncGenConv2dSep_Pix_Ydir(dPtr, sPtr, kPtr, kerWidth, srcInc,
00367                                   KerArrayT::ElemSize(), pixOp, redOp,
00368                                   neutralElement, tag);
00369         sPtr += SrcArrayT::ElemSize();
00370         dPtr += DstArrayT::ElemSize();
00371     }
00372 }
00373 
00376 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00377          class PixOpT, class RedOpT>
00378 static void
00379 FuncGenConv2dSep_Line_YdirSimInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00380                                  PixOpT& pixOp, RedOpT& redOp, int y,
00381                                  TagCallValue dummy)
00382 {
00383     typedef typename DstArrayT::StorType DstStorT;
00384     typedef typename DstArrayT::ArithType DstArithT;
00385     typedef typename SrcArrayT::StorType SrcStorT;
00386     typedef typename SrcArrayT::ArithType SrcArithT;
00387     typedef typename KerArrayT::StorType KerStorT;
00388     typedef typename KerArrayT::ArithType KerArithT;
00389 
00390     int width = ArrayCW(dst);
00391     int kerWidth = ArrayCW(ker);
00392     int kerBW = ArrayCW(ker) / 2;
00393     int srcInc = ArrayInc(src, 0, 1);
00394     KerArithT neutralElement = RedOpT::NeutralElement();
00395     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00396     SrcStorT* srcPtr = ArrayCPB(src, 0, -kerBW + y);
00397     for (int x=0 ; x<width ; x++)
00398     {
00399         SrcStorT* sPtr = srcPtr;
00400         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00401         KerArithT result(neutralElement);
00402         for (int k=0; k<kerWidth; k++)
00403         {
00404             redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00405                                           PtrRead(kPtr, KerArithT())));
00406             sPtr += srcInc;
00407             kPtr += KerArrayT::ElemSize();
00408         }
00409         PtrWrite(dPtr, result);
00410         srcPtr += SrcArrayT::ElemSize();
00411         dPtr += DstArrayT::ElemSize();
00412     }
00413 }
00414 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00626 
00627 
00628 
00630 
00981 
00982 
00983 
01028 template<class DstArrayT, class SrcArrayT, class KerArrayT,
01029          class PixOpT, class RedOpT>
01030 void
01031 FuncGenConv2dSepDispatch_H(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
01032                            PixOpT& pixOp, RedOpT& redOp, int vType)
01033 {
01034     int height = ArrayCH(dst);
01035     for (int y=0 ; y<height ; y++)
01036     {
01037         if (vType == 1)
01038             FuncGenConv2dSep_Line_Xdir(dst, src, ker, pixOp, redOp, y,
01039                                        typename PixOpT::CallCategory());
01040         if ((vType == 0) || (vType == 2))
01041             FuncGenConv2dSep_Line_XdirInc(dst, src, ker, pixOp, redOp, y,
01042                                           typename PixOpT::CallCategory());
01043     }
01044 }
01045 
01048 template<class DstArrayT, class SrcArrayT, class KerArrayT,
01049          class PixOpT, class RedOpT>
01050 void
01051 FuncGenConv2dSepDispatch_V(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
01052                            PixOpT& pixOp, RedOpT& redOp, int vType)
01053 {
01054     int width = ArrayCW(dst);
01055     if (vType == 0)
01056     {
01057         for (int x=0 ; x<width ; x++)
01058         {
01059             FuncGenConv2dSep_Line_YdirNaiInc(dst, src, ker, pixOp, redOp, x,
01060                                              typename PixOpT::CallCategory());
01061         }
01062     }
01063     else
01064     { 
01065         int height = ArrayCH(dst);
01066         for (int y=0 ; y<height ; y++)
01067         {
01068             if (vType == 1)
01069                 FuncGenConv2dSep_Line_YdirSim(dst, src, ker, pixOp, redOp, y,
01070                                               typename PixOpT::CallCategory());
01071             if (vType == 2)
01072                 FuncGenConv2dSep_Line_YdirSimInc(dst, src, ker, pixOp, redOp, y,
01073                                                  typename PixOpT::CallCategory());
01074         }
01075     }
01076 }
01077 
01078 } 
01079 } 
01080 } 
01081 } 
01082 
01083 #endif