00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __PxFuncBorderOp_h_
00010 #define __PxFuncBorderOp_h_
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Array
00017 {
00018 namespace Pattern
00019 {
00020
00021
00022 template <class ArrayT>
00023 void
00024 PxFuncBorderMirror2d(ArrayT* a, int numX, int numY)
00025 {
00026 typedef typename ArrayT::StorType StorT;
00027
00028 int cw = ArrayCW(a);
00029 int ch = ArrayCH(a);
00030 int x, y;
00031
00032 if (numX > 0) {
00033
00034 PxBorderExchange(a, YZ_PLANE, numX);
00035
00036
00037
00038 if (PxIsLeftCPU(PxMyCPU())) {
00039 for (y=0; y<ch; y++) {
00040 StorT* srcPtr = ArrayCPB(a, 0, y);
00041 StorT* dstPtr = ArrayCPB(a, -1, y);
00042 for (x=0; x<numX; x++) {
00043 for (int e=0; e<ArrayT::ElemSize(); e++) {
00044 dstPtr[e] = srcPtr[e];
00045 }
00046 dstPtr -= ArrayT::ElemSize();
00047 srcPtr += ArrayT::ElemSize();
00048 }
00049 }
00050 }
00051
00052
00053
00054 if (PxIsRightCPU(PxMyCPU())) {
00055 for (y=0; y<ch; y++) {
00056 StorT* srcPtr = ArrayCPB(a, cw - 1, y);
00057 StorT* dstPtr = ArrayCPB(a, cw, y);
00058 for (x=0 ; x<numX ; x++) {
00059 for (int e=0; e<ArrayT::ElemSize(); e++) {
00060 dstPtr[e] = srcPtr[e];
00061 }
00062 dstPtr += ArrayT::ElemSize();
00063 srcPtr -= ArrayT::ElemSize();
00064 }
00065 }
00066 }
00067 }
00068
00069 if (numY > 0) {
00070
00071 PxBorderExchange(a, XZ_PLANE, numY);
00072
00073
00074
00075 if (PxIsTopCPU(PxMyCPU())) {
00076 for (y=0; y<numY; y++) {
00077 StorT* srcPtr = ArrayCPB(a, -numX, y);
00078 StorT* dstPtr = ArrayCPB(a, -numX, -1 - y);
00079 int nElem = (cw + 2*numX) * ArrayT::ElemSize();
00080 for (x=0; x<nElem; x++) {
00081 *dstPtr++ = *srcPtr++;
00082 }
00083 }
00084 }
00085
00086
00087
00088 if (PxIsBottomCPU(PxMyCPU())) {
00089 for (y=0; y<numY; y++) {
00090 StorT* srcPtr = ArrayCPB(a, -numX, ch - 1 - y);
00091 StorT* dstPtr = ArrayCPB(a, -numX, ch + y);
00092 int nElem = (cw + 2 * numX) * ArrayT::ElemSize();
00093 for (x=0; x<nElem; x++) {
00094 *dstPtr++ = *srcPtr++;
00095 }
00096 }
00097 }
00098 }
00099 }
00100
00101
00102 template <class ArrayT, class ValT>
00103 void
00104 PxFuncBorderConstant2d(ArrayT* a, int numX, int numY, ValT value)
00105 {
00106 typedef typename ArrayT::StorType StorT;
00107 typedef typename ArrayT::ArithType ArithT;
00108
00109 int cw = ArrayCW(a);
00110 int ch = ArrayCH(a);
00111 int x, y;
00112 ArithT v = Element::E1Cast(value, ArithT());
00113
00114 if (numX > 0) {
00115
00116 PxBorderExchange(a, YZ_PLANE, numX);
00117
00118
00119
00120 if (PxIsLeftCPU(PxMyCPU())) {
00121 for (y=0 ; y<ch ; y++) {
00122 StorT* dstPtr = ArrayCPB(a, -numX, y);
00123 for (x=0 ; x<numX ; x++) {
00124 PtrWrite(dstPtr, v);
00125 dstPtr += ArrayT::ElemSize();
00126 }
00127 }
00128 }
00129
00130
00131
00132 if (PxIsRightCPU(PxMyCPU())) {
00133 for (y=0 ; y<ch ; y++) {
00134 StorT* dstPtr = ArrayCPB(a, cw, y);
00135 for (x=0 ; x<numX ; x++) {
00136 PtrWrite(dstPtr, v);
00137 dstPtr += ArrayT::ElemSize();
00138 }
00139 }
00140 }
00141 }
00142
00143 if (numY > 0) {
00144
00145 PxBorderExchange(a, XZ_PLANE, numY);
00146
00147
00148
00149 int totalWidth = cw + 2*numX;
00150
00151 if (PxIsTopCPU(PxMyCPU())) {
00152 for (y=0 ; y<numY ; y++) {
00153 StorT* dstPtr = ArrayCPB(a, -numX, -numY + y);
00154 for (x=0 ; x<totalWidth ; x++) {
00155 PtrWrite(dstPtr, v);
00156 dstPtr += ArrayT::ElemSize();
00157 }
00158 }
00159 }
00160
00161
00162
00163 if (PxIsBottomCPU(PxMyCPU())) {
00164 for (y=0 ; y<numY ; y++) {
00165 StorT* dstPtr = ArrayCPB(a, -numX, ch + y);
00166 for (x=0 ; x<totalWidth ; x++) {
00167 PtrWrite(dstPtr, v);
00168 dstPtr += ArrayT::ElemSize();
00169 }
00170 }
00171 }
00172 }
00173 }
00174
00175
00176 template <class ArrayT, class ValT>
00177 void
00178 PxFuncBorderPropagateNormalized2d(ArrayT* a, int numX, int numY,
00179 ValT normLeft, ValT normRight,
00180 ValT normTop, ValT normBottom)
00181 {
00182 typedef typename ArrayT::StorType StorT;
00183 typedef typename ArrayT::ArithType ArithT;
00184
00185 int cw = ArrayCW(a);
00186 int ch = ArrayCH(a);
00187 int x, y;
00188
00189 if (numX > 0) {
00190
00191 PxBorderExchange(a, YZ_PLANE, numX);
00192
00193
00194
00195 if (PxIsLeftCPU(PxMyCPU())) {
00196 for (y=0 ; y<ch ; y++) {
00197 StorT* srcPtr = ArrayCPB(a, 0, y);
00198 StorT* dstPtr = ArrayCPB(a, -numX, y);
00199 ArithT v = PtrRead(srcPtr, ArithT()) *
00200 Element::E1Cast(normLeft, ArithT());
00201 for (x=0 ; x<numX ; x++) {
00202 PtrWrite(dstPtr, v);
00203 dstPtr += ArrayT::ElemSize();
00204 }
00205 }
00206 }
00207
00208
00209
00210 if (PxIsRightCPU(PxMyCPU())) {
00211 for (y=0 ; y<ch ; y++) {
00212 StorT* srcPtr = ArrayCPB(a, cw - 1, y);
00213 StorT* dstPtr = ArrayCPB(a, cw, y);
00214 ArithT v = PtrRead(srcPtr, ArithT());
00215 for (x=0 ; x<numX ; x++) {
00216 PtrWrite(dstPtr, v);
00217 dstPtr += ArrayT::ElemSize();
00218 }
00219 }
00220 }
00221 }
00222
00223 if (numY > 0) {
00224
00225 PxBorderExchange(a, XZ_PLANE, numY);
00226
00227
00228
00229 int totalWidth = cw + 2*numX;
00230
00231 if (PxIsTopCPU(PxMyCPU())) {
00232 for (y=0 ; y<numY ; y++) {
00233 StorT* srcPtr = ArrayCPB(a, -numX, 0);
00234 StorT* dstPtr = ArrayCPB(a, -numX, -numY + y);
00235 ArithT nT = Element::E1Cast(normTop, ArithT());
00236 for (x=0 ; x<totalWidth ; x++) {
00237 PtrWrite(dstPtr, PtrRead(srcPtr, ArithT())*nT);
00238 srcPtr += ArrayT::ElemSize();
00239 dstPtr += ArrayT::ElemSize();
00240 }
00241 }
00242 }
00243
00244
00245
00246 if (PxIsBottomCPU(PxMyCPU())) {
00247 for (y=0 ; y<numY ; y++) {
00248 StorT* srcPtr = ArrayCPB(a, -numX, ch - 1);
00249 StorT* dstPtr = ArrayCPB(a, -numX, ch + y);
00250 ArithT nB = Element::E1Cast(1, ArithT());
00251 for (x=0 ; x<totalWidth ; x++) {
00252 PtrWrite(dstPtr, PtrRead(srcPtr, ArithT())*nB);
00253 srcPtr += ArrayT::ElemSize();
00254 dstPtr += ArrayT::ElemSize();
00255 }
00256 }
00257 }
00258 }
00259 }
00260
00261
00262 }
00263 }
00264 }
00265 }
00266
00267 #endif