00001 #ifndef Impala_Core_Array_Pattern_FuncGenConv2d_h
00002 #define Impala_Core_Array_Pattern_FuncGenConv2d_h
00003
00004 #include "Core/Array/Pattern/Categories.h"
00005 #include "Core/Array/Pattern/ArrayFunc.h"
00006 #include "Core/Geometry/Rectangle.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Array
00013 {
00014 namespace Pattern
00015 {
00016
00017
00018 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00019 class PixOpT, class RedOpT>
00020 void
00021 FuncGenConv2d_NaiInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00022 PixOpT& pixOp, RedOpT& redOp, TagCallValue dummy2)
00023 {
00024 typedef typename DstArrayT::StorType DstStorT;
00025 typedef typename DstArrayT::ArithType DstArithT;
00026 typedef typename SrcArrayT::StorType SrcStorT;
00027 typedef typename SrcArrayT::ArithType SrcArithT;
00028 typedef typename KerArrayT::StorType KerStorT;
00029 typedef typename KerArrayT::ArithType KerArithT;
00030
00031 int imgWidth = ArrayCW(dst);
00032 int imgHeight = ArrayCH(dst);
00033 int kerWidth = ArrayCW(ker);
00034 int kerHeight = ArrayCH(ker);
00035 int kerBW = ArrayCW(ker) / 2;
00036 int kerBH = ArrayCH(ker) / 2;
00037 KerArithT neutralElement(RedOpT::NeutralElement());
00038
00039 for (int y=0 ; y<imgHeight ; y++)
00040 {
00041 DstStorT* dPtr = ArrayCPB(dst, 0, y);
00042 for (int x=0 ; x<imgWidth ; x++)
00043 {
00044 KerArithT result = neutralElement;
00045 for (int j=0 ; j<kerHeight ; j++)
00046 {
00047 SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, -kerBH + y + j);
00048 KerStorT* kPtr = ArrayCPB(ker, 0, j);
00049 for (int i=0 ; i<kerWidth ; i++)
00050 {
00051 redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00052 PtrRead(kPtr, KerArithT())));
00053 sPtr += SrcArrayT::ElemSize();
00054 kPtr += KerArrayT::ElemSize();
00055 }
00056 }
00057 PtrWrite(dPtr, result);
00058 dPtr += DstArrayT::ElemSize();
00059 }
00060 }
00061 }
00062
00063 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00064 class PixOpT, class RedOpT>
00065 void
00066 FuncGenConv2d_NaiInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00067 PixOpT& pixOp, RedOpT& redOp, TagCallPointer dummy2)
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 typedef typename KerArrayT::StorType KerStorT;
00074 typedef typename KerArrayT::ArithType KerArithT;
00075
00076 int imgWidth = ArrayCW(dst);
00077 int imgHeight = ArrayCH(dst);
00078 int kerWidth = ArrayCW(ker);
00079 int kerHeight = ArrayCH(ker);
00080 int kerBW = ArrayCW(ker) / 2;
00081 int kerBH = ArrayCH(ker) / 2;
00082
00083 DstStorT* temp = new DstStorT[DstArrayT::ElemSize()];
00084
00085 for (int y=0 ; y<imgHeight ; y++)
00086 {
00087 DstStorT* dPtr = ArrayCPB(dst, 0, y);
00088 for (int x=0 ; x<imgWidth ; x++)
00089 {
00090 RedOpT::NeutralElement(dPtr);
00091 for (int j=0 ; j<kerHeight ; j++)
00092 {
00093 SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, -kerBH + y + j);
00094 KerStorT* kPtr = ArrayCPB(ker, 0, j);
00095 for (int i=0 ; i<kerWidth ; i++)
00096 {
00097 pixOp.DoIt(temp, sPtr, kPtr);
00098 redOp.DoIt(dPtr, temp);
00099 sPtr += SrcArrayT::ElemSize();
00100 kPtr += KerArrayT::ElemSize();
00101 }
00102 }
00103 dPtr += DstArrayT::ElemSize();
00104 }
00105 }
00106
00107 delete temp;
00108 }
00109
00110
00111
00112
00113
00114 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00115 class PixOpT, class RedOpT>
00116 void
00117 FuncGenConv2d_NaiIncRect(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00118 PixOpT& pixOp, RedOpT& redOp, const Geometry::Rectangle& rect)
00119 {
00120 typedef typename DstArrayT::StorType DstStorT;
00121 typedef typename DstArrayT::ArithType DstArithT;
00122 typedef typename SrcArrayT::StorType SrcStorT;
00123 typedef typename SrcArrayT::ArithType SrcArithT;
00124 typedef typename KerArrayT::StorType KerStorT;
00125 typedef typename KerArrayT::ArithType KerArithT;
00126
00127 int imgWidth = ArrayCW(dst);
00128 int imgHeight = ArrayCH(dst);
00129 int kerWidth = ArrayCW(ker);
00130 int kerHeight = ArrayCH(ker);
00131 int kerBW = ArrayCW(ker) / 2;
00132 int kerBH = ArrayCH(ker) / 2;
00133
00134 DstStorT* temp = new DstStorT[DstArrayT::ElemSize()];
00135
00136 for (int y=rect.mTop ; y<rect.mBottom ; y++)
00137 {
00138 DstStorT* dPtr = ArrayCPB(dst, rect.mLeft, y);
00139 for (int x=rect.mLeft ; x<rect.mRight ; x++)
00140 {
00141 RedOpT::NeutralElement(dPtr);
00142 for (int j=0 ; j<kerHeight ; j++)
00143 {
00144 SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, -kerBH + y + j);
00145 KerStorT* kPtr = ArrayCPB(ker, 0, j);
00146 for (int i=0 ; i<kerWidth ; i++)
00147 {
00148 pixOp.DoIt(temp, sPtr, kPtr);
00149 redOp.DoIt(dPtr, temp);
00150 sPtr += SrcArrayT::ElemSize();
00151 kPtr += KerArrayT::ElemSize();
00152 }
00153 }
00154 dPtr += DstArrayT::ElemSize();
00155 }
00156 }
00157
00158 delete temp;
00159 }
00160
00161
00162
00163
00164
00165 template<class DstArrayT, class SrcArrayT, class KerArrayT, class MaskArrayT,
00166 class PixOpT, class RedOpT>
00167 void
00168 FuncGenConv2d_NaiIncMask(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker, MaskArrayT* mask,
00169 PixOpT& pixOp, RedOpT& redOp)
00170 {
00171 typedef typename DstArrayT::StorType DstStorT;
00172 typedef typename DstArrayT::ArithType DstArithT;
00173 typedef typename SrcArrayT::StorType SrcStorT;
00174 typedef typename SrcArrayT::ArithType SrcArithT;
00175 typedef typename KerArrayT::StorType KerStorT;
00176 typedef typename KerArrayT::ArithType KerArithT;
00177 typedef typename MaskArrayT::StorType MaskStorT;
00178
00179 int imgWidth = ArrayCW(dst);
00180 int imgHeight = ArrayCH(dst);
00181 int kerWidth = ArrayCW(ker);
00182 int kerHeight = ArrayCH(ker);
00183 int kerBW = ArrayCW(ker) / 2;
00184 int kerBH = ArrayCH(ker) / 2;
00185
00186 DstStorT* temp = new DstStorT[DstArrayT::ElemSize()];
00187
00188 for (int y=0 ; y<imgHeight ; y++)
00189 {
00190 DstStorT* dPtr = ArrayCPB(dst, 0, y);
00191 MaskStorT* mPtr = mask->CPB(0, y);
00192 for (int x=0 ; x<imgWidth ; x++)
00193 {
00194 if (*mPtr)
00195 {
00196 RedOpT::NeutralElement(dPtr);
00197 for (int j=0 ; j<kerHeight ; j++)
00198 {
00199 SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, -kerBH + y + j);
00200 KerStorT* kPtr = ArrayCPB(ker, 0, j);
00201 for (int i=0 ; i<kerWidth ; i++)
00202 {
00203 pixOp.DoIt(temp, sPtr, kPtr);
00204 redOp.DoIt(dPtr, temp);
00205 sPtr += SrcArrayT::ElemSize();
00206 kPtr += KerArrayT::ElemSize();
00207 }
00208 }
00209 }
00210 dPtr += DstArrayT::ElemSize();
00211 mPtr += MaskArrayT::ElemSize();
00212 }
00213 }
00214
00215 delete temp;
00216 }
00217
00218
00219
00220
00221
00222
00223 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00224 class PixOpT, class RedOpT, class CE>
00225 void
00226 FuncGenConv2d_NaiIncCE(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00227 PixOpT& pixOp, RedOpT& redOp, CE& ce)
00228 {
00229 typedef typename DstArrayT::StorType DstStorT;
00230 typedef typename DstArrayT::ArithType DstArithT;
00231 typedef typename SrcArrayT::StorType SrcStorT;
00232 typedef typename SrcArrayT::ArithType SrcArithT;
00233 typedef typename KerArrayT::StorType KerStorT;
00234 typedef typename KerArrayT::ArithType KerArithT;
00235
00236 int imgWidth = ArrayCW(dst);
00237 int imgHeight = ArrayCH(dst);
00238 int kerWidth = ArrayCW(ker);
00239 int kerHeight = ArrayCH(ker);
00240 int kerBW = ArrayCW(ker) / 2;
00241 int kerBH = ArrayCH(ker) / 2;
00242
00243 DstStorT* temp = new DstStorT[DstArrayT::ElemSize()];
00244
00245 while (!ce.Done())
00246 {
00247 RedOpT::NeutralElement(ce.DstPointer(dst));
00248 for (int j=0 ; j<kerHeight ; j++)
00249 {
00250 SrcStorT* sPtr = ArrayCPB(src, -kerBW + ce.X(), -kerBH + ce.Y() + j);
00251 KerStorT* kPtr = ArrayCPB(ker, 0, j);
00252 for (int i=0 ; i<kerWidth ; i++)
00253 {
00254 pixOp.DoIt(temp, sPtr, kPtr);
00255 redOp.DoIt(ce.DstPointer(dst), temp);
00256 sPtr += SrcArrayT::ElemSize();
00257 kPtr += KerArrayT::ElemSize();
00258 }
00259 }
00260 ce.NextCoordinate(dst, src);
00261 }
00262 delete temp;
00263 }
00264
00267 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00268 class PixOpT, class RedOpT>
00269 void
00270 FuncGenConv2dDispatch(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00271 PixOpT& pixOp, RedOpT& redOp)
00272 {
00273 FuncGenConv2d_NaiInc(dst, src, ker, pixOp, redOp,
00274 typename PixOpT::CallCategory());
00275 }
00276
00277 }
00278 }
00279 }
00280 }
00281
00282 #endif