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