00001
00007 #define JOIN_(a,b) a ## b
00008 #define JOIN(a,b) JOIN_(a,b)
00009 #define JOIN3_(a,b,c) a ## b ## c
00010 #define JOIN3(a,b,c) JOIN3_(a,b,c)
00011
00012 #undef FLT
00013 #undef VSIZE
00014 #undef VSFX
00015 #undef SFX
00016 #undef VTYPE
00017 #undef VMUL
00018 #undef VADD
00019 #undef VSTZ
00020 #undef VLD1
00021 #undef ALIGNPTR
00022 #undef ALIGNSTRIDE
00023 #undef VL_IMCONVCOL
00024 #undef VL_IMCONVCOLTRI
00025
00026 #if (FLOAT_TYPE == FLOAT_TYPE_FLOAT)
00027 # define FLT float
00028 # define VSIZE 4
00029 # define VSFX ps
00030 # define SFX vf
00031 # define VTYPE __m128
00032 #else
00033 # define FLT double
00034 # define VSIZE 2
00035 # define VSFX pd
00036 # define SFX vd
00037 # define VTYPE __m128d
00038 #endif
00039
00040 #define VMUL JOIN(_mm_mul_, VSFX)
00041 #define VADD JOIN(_mm_add_, VSFX)
00042 #define VSTZ JOIN(_mm_setzero_, VSFX)
00043 #define VLD1 JOIN(_mm_load1_, VSFX)
00044 #define ALIGNPTR (sizeof(FLT) * VSIZE - 1)
00045 #define ALIGNSTRIDE (VSIZE - 1)
00046 #define VL_IMCONVCOL JOIN3(_vl_imconvcol_, SFX, _sse2)
00047 #define VL_IMCONVCOLTRI JOIN3(_vl_imconvcoltri_, SFX, _sse2)
00048
00049
00050 void
00051 VL_IMCONVCOL (FLT* dst, int dst_stride,
00052 FLT const* src,
00053 int src_width, int src_height, int src_stride,
00054 FLT const* filt, int filt_begin, int filt_end,
00055 int step, unsigned int flags)
00056 {
00057 int x = 0 ;
00058 int y ;
00059 int dheight = (src_height - 1) / step + 1 ;
00060 vl_bool use_simd = (src_stride & ALIGNSTRIDE) == 0 ;
00061 vl_bool transp = flags & VL_TRANSPOSE ;
00062 vl_bool zeropad = (flags & VL_PAD_MASK) == VL_PAD_BY_ZERO ;
00063 double totcol = 0 ;
00064 double simdcol = 0 ;
00065
00066
00067 filt += filt_end - filt_begin ;
00068
00069 while (x < src_width) {
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 FLT const *filti ;
00081 int stop ;
00082
00083 if ((x + VSIZE < src_width) &
00084 (((vl_intptr)(src + x) & ALIGNPTR) == 0) &
00085 use_simd)
00086 {
00087
00088 for (y = 0 ; y < src_height ; y += step) {
00089 union {VTYPE v ; FLT x [VSIZE] ; } acc ;
00090 VTYPE v, c ;
00091 FLT const *srci ;
00092 acc.v = VSTZ () ;
00093 v = VSTZ() ;
00094
00095 filti = filt ;
00096 stop = filt_end - y ;
00097 srci = src + x - stop * src_stride ;
00098
00099 if (stop > 0) {
00100 if (zeropad) {
00101 v = VSTZ () ;
00102 } else {
00103 v = * (VTYPE*) (src + x) ;
00104 }
00105 while (filti > filt - stop) {
00106 c = VLD1 (filti--) ;
00107 acc.v = VADD (acc.v, VMUL (v, c)) ;
00108 srci += src_stride ;
00109 }
00110 }
00111
00112 stop = filt_end - VL_MAX(filt_begin, y - src_height + 1) + 1 ;
00113 while (filti > filt - stop) {
00114 v = * (VTYPE*) srci ;
00115 c = VLD1 (filti--) ;
00116 acc.v = VADD (acc.v, VMUL (v, c)) ;
00117 srci += src_stride ;
00118 }
00119
00120 if (zeropad) v = VSTZ () ;
00121
00122 stop = filt_end - filt_begin + 1;
00123 while (filti > filt - stop) {
00124 c = VLD1 (filti--) ;
00125 acc.v = VADD (acc.v, VMUL (v, c)) ;
00126 }
00127
00128 if (transp) {
00129 *dst = acc.x[0] ; dst += dst_stride ;
00130 *dst = acc.x[1] ; dst += dst_stride ;
00131 #if(VSIZE == 4)
00132 *dst = acc.x[2] ; dst += dst_stride ;
00133 *dst = acc.x[3] ; dst += dst_stride ;
00134 #endif
00135 dst += 1 * 1 - VSIZE * dst_stride ;
00136 } else {
00137 *dst = acc.x[0] ; dst += 1 ;
00138 *dst = acc.x[1] ; dst += 1 ;
00139 #if(VSIZE == 4)
00140 *dst = acc.x[2] ; dst += 1 ;
00141 *dst = acc.x[3] ; dst += 1 ;
00142 #endif
00143 dst += 1 * dst_stride - VSIZE * 1 ;
00144 }
00145 }
00146 if (transp) {
00147 dst += VSIZE * dst_stride - dheight * 1 ;
00148 } else {
00149 dst += VSIZE * 1 - dheight * dst_stride ;
00150 }
00151 x += VSIZE ;
00152 simdcol += VSIZE ;
00153 totcol += VSIZE ;
00154 } else {
00155
00156 for (y = 0 ; y < src_height ; y += step) {
00157 FLT acc = 0 ;
00158 FLT v = 0, c ;
00159 FLT const* srci ;
00160
00161 filti = filt ;
00162 stop = filt_end - y ;
00163 srci = src + x - stop * src_stride ;
00164
00165 if (stop > 0) {
00166 if (zeropad) {
00167 v = 0 ;
00168 } else {
00169 v = *(src + x) ;
00170 }
00171 while (filti > filt - stop) {
00172 c = *filti-- ;
00173 acc += v * c ;
00174 srci += src_stride ;
00175 }
00176 }
00177
00178 stop = filt_end - VL_MAX(filt_begin, y - src_height + 1) + 1 ;
00179 while (filti > filt - stop) {
00180 v = *srci ;
00181 c = *filti-- ;
00182 acc += v * c ;
00183 srci += src_stride ;
00184 }
00185
00186 if (zeropad) v = 0 ;
00187
00188 stop = filt_end - filt_begin + 1 ;
00189 while (filti > filt - stop) {
00190 c = *filti-- ;
00191 acc += v * c ;
00192 }
00193
00194 if (transp) {
00195 *dst = acc ; dst += 1 ;
00196 } else {
00197 *dst = acc ; dst += dst_stride ;
00198 }
00199 }
00200 if (transp) {
00201 dst += 1 * dst_stride - dheight * 1 ;
00202 } else {
00203 dst += 1 * 1 - dheight * dst_stride ;
00204 }
00205 x += 1 ;
00206 totcol += 1 ;
00207 }
00208 }
00209 }
00210
00211 #if 0
00212
00213 VL_EXPORT
00214 void
00215 VL_IMCONVCOLTRI (FLT* dst, int dst_stride,
00216 FLT const* src,
00217 int src_width, int src_height, int src_stride,
00218 int filt_size,
00219 int step, unsigned int flags)
00220 {
00221 int x = 0 ;
00222 int y ;
00223 int dheight = (src_height - 1) / step + 1 ;
00224 vl_bool use_simd = ((src_stride & ALIGNSTRIDE) == 0) &&
00225 (! (flags & VL_NO_SIMD)) ;
00226 vl_bool transp = flags & VL_TRANSPOSE ;
00227 vl_bool zeropad = (flags & VL_PAD_MASK) == VL_PAD_BY_ZERO ;
00228
00229 FLT * buff = vl_malloc(sizeof(FLT) * (src_height + filt_size)) ;
00230 #define fa (1.0 / (double) (filt_size + 1))
00231 FLT scale = fa*fa*fa*fa ;
00232 buff += filt_size ;
00233
00234 while (x < src_width) {
00235 FLT const *srci ;
00236
00237 use_simd = 0 ;
00238 if ((x + VSIZE < src_width) &
00239 (((vl_ptrint)(src + x) & ALIGNPTR) == 0) &
00240 use_simd)
00241 {
00242
00243 } else {
00244 int stridex = transp ? dst_stride : 1 ;
00245 int stridey = transp ? 1 : dst_stride ;
00246 srci = src + x + src_stride * (src_height - 1) ;
00247
00248
00249 buff [src_height - 1] = *srci ;
00250 for (y = src_height-2 ; y >= 0 ; --y) {
00251 srci -= src_stride ;
00252 buff [y] = buff [y+1] + *srci ;
00253 }
00254 if (zeropad) {
00255 for ( ; y >= - filt_size ; --y) {
00256 buff [y] = buff [y+1] ;
00257 }
00258 } else {
00259 for ( ; y >= - filt_size ; --y) {
00260 buff [y] = buff[y+1] + *srci ;
00261 }
00262 }
00263
00264
00265 for (y = - filt_size ; y < src_height - filt_size ; ++y) {
00266 buff [y] = buff [y] - buff [y + filt_size] ;
00267 }
00268 if (! zeropad) {
00269 for (y = src_height - filt_size ; y < src_height ; ++y) {
00270 buff [y] = buff [y] - buff [src_height-1] *
00271 (src_height - filt_size - y) ;
00272 }
00273 }
00274
00275
00276 for (y = - filt_size + 1 ; y < src_height ; ++y) {
00277 buff [y] += buff [y - 1] ;
00278 }
00279
00280
00281 for (y = src_height - 1 ; y >= 0 ; --y) {
00282 dst [x*stridex + y*stridey]
00283 = scale * (buff [y] - buff [y - filt_size]) ;
00284 }
00285 }
00286 x += 1 ;
00287 }
00288 vl_free (buff - filt_size) ;
00289 }
00290 #endif