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