00001 #ifndef Impala_Core_Array_Pattern_FuncBorderOp_h
00002 #define Impala_Core_Array_Pattern_FuncBorderOp_h
00003
00004 #include "Core/Array/Pattern/ArrayFunc.h"
00005 #include "Core/Array/Element/E1Cast.h"
00006
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013 namespace Pattern
00014 {
00015
00016
00017 template <class ArrayT>
00018 void
00019 FuncBorderMirror2d(ArrayT* a, Int64 numX, Int64 numY)
00020 {
00021 typedef typename ArrayT::StorType StorT;
00022
00023 Int64 cw = ArrayCW(a);
00024 Int64 ch = ArrayCH(a);
00025 Int64 x, y;
00026
00027 if (numY > 0)
00028 {
00029
00030 for (y=0 ; y<numY ; y++)
00031 {
00032 StorT* srcPtr = ArrayCPB(a, 0, y);
00033 StorT* dstPtr = ArrayCPB(a, 0, -1 - y);
00034 Int64 nElem = cw * ArrayT::ElemSize();
00035 for (x=0 ; x<nElem ; x++)
00036 {
00037 *dstPtr++ = *srcPtr++;
00038 }
00039 }
00040
00041
00042 for (y=0 ; y<numY ; y++)
00043 {
00044 StorT* srcPtr = ArrayCPB(a, 0, ch - 1 - y);
00045 StorT* dstPtr = ArrayCPB(a, 0, ch + y);
00046 Int64 nElem = cw * ArrayT::ElemSize();
00047 for (x=0 ; x<nElem ; x++)
00048 {
00049 *dstPtr++ = *srcPtr++;
00050 }
00051 }
00052 }
00053
00054 if (numX > 0)
00055 {
00056
00057 Int64 totalHeight = ch + 2*numY;
00058 for (y=0 ; y<totalHeight ; y++)
00059 {
00060 StorT* srcPtr = ArrayCPB(a, 0, -numY + y);
00061 StorT* dstPtr = ArrayCPB(a, -1, -numY + y);
00062 for (x=0 ; x<numX ; x++)
00063 {
00064 for (Int64 e=0 ; e<ArrayT::ElemSize() ; e++)
00065 dstPtr[e] = srcPtr[e];
00066 dstPtr -= ArrayT::ElemSize();
00067 srcPtr += ArrayT::ElemSize();
00068 }
00069 }
00070
00071
00072 for (y=0 ; y<totalHeight ; y++)
00073 {
00074 StorT* srcPtr = ArrayCPB(a, cw - 1, -numY + y);
00075 StorT* dstPtr = ArrayCPB(a, cw, -numY + y);
00076 for (x=0 ; x<numX ; x++)
00077 {
00078 for (Int64 e=0 ; e<ArrayT::ElemSize() ; e++)
00079 dstPtr[e] = srcPtr[e];
00080 dstPtr += ArrayT::ElemSize();
00081 srcPtr -= ArrayT::ElemSize();
00082 }
00083 }
00084 }
00085 }
00086
00087 template <class ArrayT, class ValT>
00088 void
00089 FuncBorderConstant2d(ArrayT* a, Int64 numX, Int64 numY, ValT value)
00090 {
00091 typedef typename ArrayT::StorType StorT;
00092 typedef typename ArrayT::ArithType ArithT;
00093
00094 Int64 cw = ArrayCW(a);
00095 Int64 ch = ArrayCH(a);
00096 Int64 x, y;
00097 ArithT v = Element::E1Cast(value, ArithT());
00098
00099 if (numX > 0)
00100 {
00101
00102 for (y=0 ; y<ch ; y++)
00103 {
00104 StorT* dstPtr = ArrayCPB(a, -numX, y);
00105 for (x=0 ; x<numX ; x++)
00106 {
00107 PtrWrite(dstPtr, v);
00108 dstPtr += ArrayT::ElemSize();
00109 }
00110 dstPtr = ArrayCPB(a, cw, y);
00111 for (x=0 ; x<numX ; x++)
00112 {
00113 PtrWrite(dstPtr, v);
00114 dstPtr += ArrayT::ElemSize();
00115 }
00116 }
00117 }
00118
00119 if (numY > 0)
00120 {
00121
00122 Int64 totalWidth = cw + 2*numX;
00123 for (y=0 ; y<numY ; y++)
00124 {
00125 StorT* dstPtr = ArrayCPB(a, -numX, -numY + y);
00126 for (x=0 ; x<totalWidth ; x++)
00127 {
00128 PtrWrite(dstPtr, v);
00129 dstPtr += ArrayT::ElemSize();
00130 }
00131 dstPtr = ArrayCPB(a, -numX, ch + y);
00132 for (x=0 ; x<totalWidth ; x++)
00133 {
00134 PtrWrite(dstPtr, v);
00135 dstPtr += ArrayT::ElemSize();
00136 }
00137 }
00138 }
00139 }
00140
00141 template <class ArrayT, class ValT>
00142 void
00143 FuncBorderPropagateNormalized2d(ArrayT* a, Int64 numX, Int64 numY, ValT normLeft,
00144 ValT normRight, ValT normTop, ValT normBottom)
00145 {
00146 typedef typename ArrayT::StorType StorT;
00147 typedef typename ArrayT::ArithType ArithT;
00148
00149 Int64 cw = ArrayCW(a);
00150 Int64 ch = ArrayCH(a);
00151 Int64 x, y;
00152
00153 if (numX > 0)
00154 {
00155
00156 for (y=0 ; y<ch ; y++)
00157 {
00158 StorT* srcPtr = ArrayCPB(a, 0, y);
00159 ArithT v = PtrRead(srcPtr, ArithT()) * Element::E1Cast(normLeft, ArithT());
00160 StorT* dstPtr = ArrayCPB(a, -numX, y);
00161 for (x=0 ; x<numX ; x++)
00162 {
00163 PtrWrite(dstPtr, v);
00164 dstPtr += ArrayT::ElemSize();
00165 }
00166
00167 srcPtr = ArrayCPB(a, cw - 1, y);
00168
00169
00170 v = PtrRead(srcPtr, ArithT());
00171 dstPtr = ArrayCPB(a, cw, y);
00172 for (x=0 ; x<numX ; x++)
00173 {
00174 PtrWrite(dstPtr, v);
00175 dstPtr += ArrayT::ElemSize();
00176 }
00177 }
00178 }
00179
00180 if (numY > 0)
00181 {
00182
00183
00184 Int64 totalWidth = cw + 2*numX;
00185 for (y=0 ; y<numY ; y++)
00186 {
00187 StorT* srcPtr = ArrayCPB(a, -numX, 0);
00188 StorT* dstPtr = ArrayCPB(a, -numX, -numY + y);
00189 ArithT nT = Element::E1Cast(normTop, ArithT());
00190 for (x=0 ; x<totalWidth ; x++)
00191 {
00192 PtrWrite(dstPtr, PtrRead(srcPtr, ArithT()) * nT);
00193 srcPtr += ArrayT::ElemSize();
00194 dstPtr += ArrayT::ElemSize();
00195 }
00196
00197 srcPtr = ArrayCPB(a, -numX, ch - 1);
00198 dstPtr = ArrayCPB(a, -numX, ch + y);
00199
00200
00201 ArithT nB = Element::E1Cast(1, ArithT());
00202 for (x=0 ; x<totalWidth ; x++)
00203 {
00204 PtrWrite(dstPtr, PtrRead(srcPtr, ArithT()) * nB);
00205 srcPtr += ArrayT::ElemSize();
00206 dstPtr += ArrayT::ElemSize();
00207 }
00208 }
00209 }
00210 }
00211
00212 }
00213 }
00214 }
00215 }
00216
00217 #endif