00001 #ifndef vipl_filter_helper_h_
00002 #define vipl_filter_helper_h_
00003
00004 typedef unsigned int VIPL_FILTER_STATE;
00005
00006
00007
00008
00009
00010 #define READY(x) (x & Ready)
00011 #define NOT_READY(x) (!(x & Ready))
00012 #define UNCHANGED(x) (x & Unchanged)
00013 #define CHANGED(x) (!(x & Unchanged))
00014 #define USER_OWNED(x) (!(x & Filter_Owned))
00015 #define FILTER_OWNED(x) (x & Filter_Owned)
00016 #define NOT(x) (!x)
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define FILL(X1, Y1, X2, Y2, DST, FV) do {\
00031 for (int y = (Y1); y < (Y2); ++y) {\
00032 for (int x = (X1); x < (X2); ++x) {\
00033 SET_PIXEL((DST),x, y, (FV));\
00034 }\
00035 }\
00036 } while (false)
00037
00038 #define MASK_CONV(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) do {\
00039 KernType val;\
00040 vcl_clock_t ct = clock(),ct1;\
00041 for (int y = (Y1); y < (Y2); ++y)\
00042 for (int x = (X1) ; x < (X2); ++x) {\
00043 val = 0.0;\
00044 int je = (KERN).y_end(); int ie = (KERN).x_end();\
00045 for (int j = (KERN).y_start(), jj=y+j; j < je; ++j) {\
00046 for (int i = (KERN).x_start(), ii=x+i; i < ie; ++i)\
00047 val += ((KERN) (i, j) * FGET_PIXEL((SRC), ii++, jj));\
00048 ++jj;\
00049 FSET_PIXEL((DST), x, y, (CONVERT_TO_OUT(val)));\
00050 }\
00051 }\
00052 ct1 = clock();\
00053 } while (false)
00054
00055 #define MASK_CONV_BOARDER(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) \
00056 do {\
00057 KernType val;\
00058 vcl_clock_t ct = clock(),ct1;\
00059 for (int y = (Y1); y < (Y2); ++y)\
00060 for (int x = (X1) ; x < (X2); ++x) {\
00061 val = 0.0;\
00062 int je = (KERN).y_end(); int ie = (KERN).x_end();\
00063 for (int j = (KERN).y_start(), jj=y+j; j < je; ++j) {\
00064 for (int i = (KERN).x_start(), ii=x+i; i < ie; ++i)\
00065 val += ((KERN) (i, j) * GET_PIXEL((SRC), ii++, jj));\
00066 ++jj;\
00067 SET_PIXEL((DST), x, y, (CONVERT_TO_OUT(val)));\
00068 }\
00069 }\
00070 ct1 = clock();\
00071 } while (false)
00072
00073 #define NORMAL_INTERMEDIATE
00074 #ifdef NORMAL_INTERMEDIATE
00075
00076
00077
00078 #define HORIZ_CONV(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) do {\
00079 vcl_clock_t ct = clock();\
00080 KernType val;\
00081 for (int y = ((Y1) ); y < ((Y2) ); ++y) {\
00082 for (int x = ((X1) ); x < ((X2) ); ++x) {\
00083 val = 0.0;\
00084 for (int i = (KERN).kernel_start(0),j=i+x; i < (KERN).kernel_end(0); ++i) \
00085 val += ((KERN)(i) * FGET_PIXEL((SRC),j++, y));\
00086 FSET_PIXEL((DST),x, y, (CONVERT_TO_OUT(val)));\
00087 }\
00088 }\
00089 vcl_clock_t ct2= clock();\
00090 } while (false)
00091
00092 #define HORIZ_CONV_BOARDER(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) do {\
00093 vcl_clock_t ct = clock();\
00094 KernType val;\
00095 for (int y = ((Y1) ); y < ((Y2) ); ++y) {\
00096 for (int x = ((X1) ); x < ((X2) ); ++x) {\
00097 val = 0.0;\
00098 for (int i = (KERN).kernel_start(0),j=i+x; i < (KERN).kernel_end(0); ++i) \
00099 val += ((KERN)(i) * GET_PIXEL((SRC),j++, y));\
00100 SET_PIXEL((DST),x, y, (CONVERT_TO_OUT(val)));\
00101 }\
00102 }\
00103 vcl_clock_t ct2= clock();\
00104 } while (false)
00105
00106 #define VERTI_CONV(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) do {\
00107 KernType val;\
00108 vcl_clock_t ct = clock();\
00109 for (int x = ((X1) ); x < ((X2) ); ++x) {\
00110 for (int y = ((Y1) ); y < ((Y2) ); ++y) {\
00111 val = 0;\
00112 for (int i = (KERN).kernel_start(0), j =y+i; i < (KERN).kernel_end(0); ++i)\
00113 val += ((KERN)(i) * FGET_PIXEL((SRC),x, j++));\
00114 FSET_PIXEL((DST),x, y, (CONVERT_TO_OUT(val)));\
00115 }\
00116 }\
00117 vcl_clock_t ct2= clock();\
00118 } while (false)
00119
00120 #define VERTI_CONV_BOARDER(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) do {\
00121 KernType val;\
00122 vcl_clock_t ct = clock();\
00123 for (int x = ((X1) ); x < ((X2) ); ++x) {\
00124 for (int y = ((Y1) ); y < ((Y2) ); ++y) {\
00125 val = 0;\
00126 for (int i = (KERN).kernel_start(0), j =y+i; i < (KERN).kernel_end(0); ++i)\
00127 val += ((KERN)(i) * GET_PIXEL((SRC),x, j++));\
00128 SET_PIXEL((DST),x, y, (CONVERT_TO_OUT(val)));\
00129 }\
00130 }\
00131 vcl_clock_t ct2= clock();\
00132 } while (false)
00133
00134 #else //else we flip intermediate
00135
00136 #define HORIZ_CONV(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) do {\
00137 KernType val;\
00138 vcl_clock_t ct = clock();\
00139 for (int y = ((Y1) + DELTA_Y); y < ((Y2) - (DELTA_Y)); ++y) {\
00140 for (int x = ((X1) + (DELTA_X)); x < ((X2) - (DELTA_X)); ++x) {\
00141 val = 0.0;\
00142 for (int i = (KERN).kernel_start(0); i < (KERN).kernel_end(0); ++i) \
00143 val += ((KERN) (i) * FGET_PIXEL((SRC), x+i,y));\
00144 FSET_PIXEL((DST), y,x, (CONVERT_TO_OUT(val)));\
00145 }\
00146 }\
00147 vcl_clock_t ct2= clock();\
00148 } while (false)
00149
00150 #define HORIZ_CONV_BOARDER(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN) \ do {\
00151 KernType val;\
00152 vcl_clock_t ct = clock();\
00153 for (int y = ((Y1) + DELTA_Y); y < ((Y2) - (DELTA_Y)); ++y) {\
00154 for (int x = ((X1) + (DELTA_X)); x < ((X2) - (DELTA_X)); ++x) {\
00155 val = 0.0;\
00156 for (int i = (KERN).kernel_start(0); i < (KERN).kernel_end(0); ++i) \
00157 val += ((KERN) (i) * GET_PIXEL((SRC), x+i,y));\
00158 SET_PIXEL((DST), y,x, (CONVERT_TO_OUT(val)));\
00159 }\
00160 }\
00161 vcl_clock_t ct2= clock();\
00162 } while (false)
00163
00164 #define VERTI_CONV(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN)
00165 do {\
00166 KernType val;\
00167 vcl_clock_t ct = clock();\
00168 for (int x = ((X1) + (DELTA_X)); x < ((X2) - (DELTA_X)); ++x) {\
00169 for (int y = ((Y1) + (DELTA_Y)); y < ((Y2) - (DELTA_Y)); ++y) {\
00170 val = 0;\
00171 for (int i = (KERN).kernel_start(0); i < (KERN).kernel_end(0); ++i)\
00172 val += ((KERN) (i) * FGET_PIXEL((SRC),y+i,x));\
00173 FSET_PIXEL((DST),x, y, (CONVERT_TO_OUT(val)));\
00174 }\
00175 }\
00176 vcl_clock_t ct2= clock();\
00177 } while (false)
00178
00179 #define VERTI_CONV_BOARDER(X1, Y1, X2, Y2, DELTA_X, DELTA_Y, SRC, DST, KERN)\ do {\
00180 KernType val;\
00181 vcl_clock_t ct = clock();\
00182 for (int x = ((X1) + (DELTA_X)); x < ((X2) - (DELTA_X)); ++x) {\
00183 for (int y = ((Y1) + (DELTA_Y)); y < ((Y2) - (DELTA_Y)); ++y) {\
00184 val = 0;\
00185 for (int i = (KERN).kernel_start(0); i < (KERN).kernel_end(0); ++i)\
00186 val += ((KERN) (i) * GET_PIXEL((SRC),y+i,x));\
00187 SET_PIXEL((DST),x, y, (CONVERT_TO_OUT(val)));\
00188 }\
00189 }\
00190 vcl_clock_t ct2= clock();\
00191 } while (false)
00192
00193 #endif
00194
00195
00196
00197
00198
00199 #define IMB_LEFT(D,C) ((D).curr_sec_start(X_Axis()) == (C).image_start(X_Axis()))
00200 #define IMB_RIGHT(D,C) ((D).curr_sec_end(X_Axis()) == (C).image_end(X_Axis()))
00201 #define IMB_TOP(D,C) ((D).curr_sec_end(Y_Axis()) == (C).image_end(Y_Axis()))
00202 #define IMB_BOTTOM(D,C) ((D).curr_sec_start(Y_Axis()) == (C).image_start(Y_Axis()))
00203
00204
00205
00206
00207 #define CONVOL_PREAMBLE(CONTAINER, DESCRIPTOR) \
00208 const vipl_section_container<DataTypeOut> &C=(CONTAINER);\
00209 const vipl_section_descriptor<DataTypeOut> &D=(DESCRIPTOR);\
00210 int border = 0;\
00211 const int ibs = image_border_size();\
00212 const int d0 = ibs;\
00213 const int bdr = ibs;\
00214 const DataTypeOut fv = def_fill_value();\
00215 int xcs[4], ycs[4], xce[4], yce[4];\
00216 int do_fill[4]; \
00217 const int XS = D.curr_sec_start(X_Axis()), YS = D.curr_sec_start(Y_Axis());\
00218 const int XE = D.curr_sec_end(X_Axis()), YE = D.curr_sec_end(Y_Axis());\
00219 do_fill[0] = do_fill[1] = do_fill[2] = do_fill[3] = false
00220
00221 #define CALC_BORDER(B, D, C) (B) = 0; \
00222 if (IMB_LEFT((D), (C))) (B) |= 1;\
00223 if (IMB_TOP((D), (C))) (B) |= 2;\
00224 if (IMB_RIGHT((D), (C))) (B) |= 4;\
00225 if (IMB_BOTTOM((D), (C))) (B) |= 8;
00226
00227
00228
00229 #define IMB_L (1)
00230 #define IMB_T (2)
00231 #define IMB_R (4)
00232 #define IMB_B (8)
00233
00234
00235
00236 #define CHECK_START_AND_END_FILL(CONTAINER) \
00237 if ((CONTAINER).image_start(Y_Axis()) > ycs[tmpi]){ ycs[tmpi] = (CONTAINER).image_start(Y_Axis()); }\
00238 if ((CONTAINER).image_start(X_Axis()) > xcs[tmpi]){ xcs[tmpi] = (CONTAINER).image_start(X_Axis()); }\
00239 if ((CONTAINER).image_start(Y_Axis()) > yce[tmpi]){ yce[tmpi] = (CONTAINER).image_start(Y_Axis()); }\
00240 if ((CONTAINER).image_start(X_Axis()) > xce[tmpi]){ xce[tmpi] = (CONTAINER).image_start(X_Axis()); }\
00241 if ((CONTAINER).image_end(Y_Axis()) < ycs[tmpi]){ ycs[tmpi] = (CONTAINER).image_end(Y_Axis()); }\
00242 if ((CONTAINER).image_end(X_Axis()) < xcs[tmpi]){ xcs[tmpi] = (CONTAINER).image_end(X_Axis()); }\
00243 if ((CONTAINER).image_end(Y_Axis()) < yce[tmpi]){ yce[tmpi] = (CONTAINER).image_end(Y_Axis()); }\
00244 if ((CONTAINER).image_end(X_Axis()) < xce[tmpi]){ xce[tmpi] = (CONTAINER).image_end(X_Axis()); }
00245 #define CHECK_START_AND_END_OPERATION(CONTAINER) \
00246 if ((CONTAINER).image_start(Y_Axis()) + ibs > ycs[tmpi]){ ycs[tmpi] = (CONTAINER).image_start(Y_Axis()) +ibs; }\
00247 if ((CONTAINER).image_start(X_Axis()) +ibs> xcs[tmpi]){ xcs[tmpi] = (CONTAINER).image_start(X_Axis())+ibs; }\
00248 if ((CONTAINER).image_start(Y_Axis()) +ibs > yce[tmpi]){ yce[tmpi] = (CONTAINER).image_start(Y_Axis()) +ibs; }\
00249 if ((CONTAINER).image_start(X_Axis()) +ibs > xce[tmpi]){ xce[tmpi] = (CONTAINER).image_start(X_Axis()) +ibs; }\
00250 if ((CONTAINER).image_end(Y_Axis()) -ibs < ycs[tmpi]){ ycs[tmpi] = (CONTAINER).image_end(Y_Axis()) -ibs; }\
00251 if ((CONTAINER).image_end(X_Axis())-ibs < xcs[tmpi]){ xcs[tmpi] = (CONTAINER).image_end(X_Axis()) -ibs; }\
00252 if ((CONTAINER).image_end(Y_Axis())-ibs < yce[tmpi]){ yce[tmpi] = (CONTAINER).image_end(Y_Axis()) -ibs; }\
00253 if ((CONTAINER).image_end(X_Axis())-ibs < xce[tmpi]){ xce[tmpi] = (CONTAINER).image_end(X_Axis()) -ibs; }
00254
00255
00256
00257
00258
00259
00260 #define DO_PREOP(OPERATION, DESCRIPTOR, CONTAINER, SRC, DST, KERN) do {\
00261 CONVOL_PREAMBLE(CONTAINER, DESCRIPTOR);\
00262 CALC_BORDER(border, DESCRIPTOR, CONTAINER);\
00263 if (border & (IMB_L|IMB_B)) {\
00264 do_fill[0] = true;\
00265 xcs[0] = XS; ycs[0] = YS;\
00266 xce[0] = XS + ibs; yce[0] = YS + ibs;\
00267 } else {\
00268 xcs[0] = XS; ycs[0] = YS;\
00269 xce[0] = XS + bdr; yce[0] = YS + bdr;\
00270 }\
00271 if (border & (IMB_B)) {\
00272 do_fill[1] = true; \
00273 xcs[1] = XS + ibs; ycs[1] = YS;\
00274 xce[1] = XE - ibs; yce[1] = YS + ibs;\
00275 } else {\
00276 xcs[1] = XS + bdr; ycs[1] = YS;\
00277 xce[1] = XE - bdr; yce[1] = YS + bdr;\
00278 } \
00279 if (border & (IMB_B|IMB_R)) {\
00280 do_fill[2] = true;\
00281 xcs[2] = XE - ibs; ycs[2] = YS;\
00282 xce[2] = XE; yce[2] = YS + ibs;\
00283 } else {\
00284 xcs[2] = XE - bdr; ycs[2] = YS;\
00285 xce[2] = XE; yce[2] = YS + bdr;\
00286 }\
00287 if (border & IMB_L) {\
00288 do_fill[3] = true;\
00289 xcs[3] = XS; ycs[3] = YS + ibs;\
00290 xce[3] = XS + ibs; yce[3] = YE - ibs;\
00291 } else {\
00292 xcs[3] = XS; ycs[3] = YS + bdr;\
00293 xce[3] = XS + bdr; yce[3] = YE - bdr;\
00294 }\
00295 for (int tmpi = 0; tmpi < 4; ++tmpi) {\
00296 if (do_fill[tmpi]) {\
00297 CHECK_START_AND_END_FILL(CONTAINER) \
00298 handle_image_border(tmpi+1, xcs[tmpi], ycs[tmpi], xce[tmpi], yce[tmpi]);}\
00299 else {\
00300 CHECK_START_AND_END_OPERATION(CONTAINER) \
00301 OPERATION(xcs[tmpi], ycs[tmpi], xce[tmpi], yce[tmpi], 0, 0, SRC, DST, KERN);}\
00302 }\
00303 } while (false)
00304
00305
00306
00307
00308
00309 #define DO_POSTOP(OPERATION, DESCRIPTOR, CONTAINER, SRC, DST, KERN) do {\
00310 CONVOL_PREAMBLE(CONTAINER, DESCRIPTOR);\
00311 CALC_BORDER(border, DESCRIPTOR, CONTAINER);\
00312 if (border & IMB_R) {\
00313 do_fill[0] = true;\
00314 xcs[0] = XE - ibs; ycs[0] = YS + ibs;\
00315 xce[0] = XE; yce[0] = YE - ibs;\
00316 } else {\
00317 xcs[0] = XE - bdr; ycs[0] = YS + bdr;\
00318 xce[0] = XE; yce[0] = YE - bdr;\
00319 }\
00320 if (border & (IMB_L|IMB_T)) {\
00321 do_fill[1] = true; \
00322 xcs[1] = XS; ycs[1] = YE - ibs;\
00323 xce[1] = XS + ibs; yce[1] = YE;\
00324 } else {\
00325 xcs[1] = XS; ycs[1] = YE - bdr;\
00326 xce[1] = XS + bdr; yce[1] = YE;\
00327 } \
00328 if (border & IMB_T) {\
00329 do_fill[2] = true;\
00330 xcs[2] = XS + ibs; ycs[2] = YE - ibs;\
00331 xce[2] = XE - ibs; yce[2] = YE;\
00332 } else {\
00333 xcs[2] = XS + bdr; ycs[2] = YE - bdr;\
00334 xce[2] = XE - bdr; yce[2] = YE;\
00335 }\
00336 if (border & (IMB_T|IMB_R)) {\
00337 do_fill[3] = true;\
00338 xcs[3] = XE - ibs; ycs[3] = YE - ibs;\
00339 xce[3] = XE; yce[3] = YE;\
00340 } else {\
00341 xcs[3] = XE - bdr; ycs[3] = YE - bdr;\
00342 xce[3] = XE; yce[3] = YE;\
00343 }\
00344 for (int tmpi = 0; tmpi < 4; ++tmpi) {\
00345 if (do_fill[tmpi]) {\
00346 CHECK_START_AND_END_FILL(CONTAINER) \
00347 handle_image_border(tmpi+6, xcs[tmpi], ycs[tmpi], xce[tmpi], yce[tmpi]);}\
00348 else {\
00349 CHECK_START_AND_END_OPERATION(CONTAINER) \
00350 OPERATION(xcs[tmpi], ycs[tmpi], xce[tmpi], yce[tmpi], 0, 0, SRC, DST, KERN);}\
00351 }\
00352 } while (false)
00353
00354 #endif