00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_BORDER_DUPLICATE_HH
00027 # define MLN_BORDER_DUPLICATE_HH
00028
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/routine/primary.hh>
00035 # include <mln/core/box_runstart_piter.hh>
00036 # include <mln/border/get.hh>
00037 # include <mln/opt/element.hh>
00038
00039
00040 namespace mln
00041 {
00042
00043 namespace border
00044 {
00045
00055 template <typename I>
00056 void duplicate(const Image<I>& ima);
00057
00058
00059 # ifndef MLN_INCLUDE_ONLY
00060
00061 namespace impl
00062 {
00063
00064 template <typename I>
00065 inline
00066 void duplicate_1D(I& ima)
00067 {
00068 trace::entering("border::impl::duplicate_1D");
00069
00070 typedef mln_psite(I) P;
00071 mln_box_runstart_piter(I) pl(ima.domain());
00072 unsigned len_c = ima.bbox().len(P::dim - 1);
00073 unsigned border = ima.border();
00074
00075 for (unsigned i = 0; i < border; ++i)
00076 opt::element(ima, i) = opt::element(ima, border);
00077
00078 unsigned st = border + len_c - 1;
00079 for (unsigned i = st + 1; i < opt::nelements(ima); ++i)
00080 opt::element(ima, i) = opt::element(ima, st);
00081
00082 trace::exiting("border::impl::duplicate_1D");
00083 }
00084
00085 template <typename I>
00086 inline
00087 void duplicate_2D(I& ima)
00088 {
00089 trace::entering("border::impl::duplicate_2D");
00090
00091 typedef mln_psite(I) P;
00092 mln_box_runstart_piter(I) pl(ima.domain());
00093 unsigned border = ima.border();
00094 unsigned border_2x = 2 * ima.border();
00095 unsigned len_c = ima.bbox().len(1);
00096 unsigned len_r = ima.bbox().len(0);
00097 unsigned real_len_c = len_c + border_2x;
00098 unsigned st;
00099
00100
00101 for_all (pl)
00102 {
00103 st = ima.index_of_point (pl);
00104 for (unsigned i = 1; i <= border; ++i)
00105 opt::element(ima, st - i) = opt::element(ima, st);
00106 st = st + len_c - 1;
00107 for (unsigned i = 1; i <= border; ++i)
00108 opt::element(ima, st + i) = opt::element(ima, st);
00109 }
00110
00111
00112 st = real_len_c * border;
00113 for (unsigned k = 0; k < border; ++k)
00114 for (unsigned i = 0; i < real_len_c; ++i)
00115 opt::element(ima, k * real_len_c + i) = opt::element(ima, st + i);
00116
00117
00118 st = real_len_c * (border + len_r - 1);
00119 for (unsigned k = 1; k <= border; ++k)
00120 for (unsigned i = st; i < st + real_len_c; ++i)
00121 opt::element(ima, k * real_len_c + i) = opt::element(ima, i);
00122
00123 trace::exiting("border::impl::duplicate_2D");
00124 }
00125
00126 template <typename I>
00127 inline
00128 void duplicate_3D(I& ima)
00129 {
00130 trace::entering("border::impl::duplicate_3D");
00131
00132 mln_precondition(ima.is_valid());
00133
00134 typedef mln_psite(I) P;
00135 mln_box_runstart_piter(I) pl(ima.domain());
00136 unsigned border = ima.border();
00137 unsigned border_2x = 2 * ima.border();
00138 unsigned len_c = ima.bbox().len(P::dim - 1);
00139 unsigned len_r = ima.bbox().len(1);
00140 unsigned len_s = ima.bbox().len(0);
00141 unsigned real_len_c = len_c + border_2x;
00142 unsigned real_len_r = len_r + border_2x;
00143 unsigned face = real_len_c * real_len_r;
00144 unsigned st;
00145
00146 pl.start();
00147
00148 for (unsigned k = 0; k < len_s; ++k)
00149 {
00150
00151
00152 for (unsigned j = 0; j < len_r; ++j)
00153 {
00154 st = ima.index_of_point (pl);
00155 for (unsigned i = 1; i <= border; ++i)
00156 opt::element(ima, st - i) = opt::element(ima, st);
00157 st = st + len_c - 1;
00158 for (unsigned i = 1; i <= border; ++i)
00159 opt::element(ima, st + i) = opt::element(ima, st);
00160 pl.next();
00161 }
00162
00163
00164 st = border * face + k * face + border * real_len_c ;
00165 for (unsigned j = 1; j <= border; ++j)
00166 for (unsigned i = 0; i < real_len_c; ++i)
00167 opt::element(ima, st - j * real_len_c + i) =
00168 opt::element(ima, st + i);
00169
00170
00171 st = border * face + k * face + (len_r + border - 1) * real_len_c ;
00172 for (unsigned j = 1; j <= border; ++j)
00173 for (unsigned i = 0; i < real_len_c; ++i)
00174 opt::element(ima, st + j * real_len_c + i) =
00175 opt::element(ima, st + i);
00176 }
00177
00178
00179 st = border * face;
00180 for (unsigned k = 0; k < border; ++k)
00181 for (unsigned i = 0; i < face; ++i)
00182 opt::element(ima, k * face + i) = opt::element(ima, st + i);
00183
00184
00185 st = (len_s + border - 1) * face;
00186 for (unsigned k = 1; k <= border; ++k)
00187 for (unsigned i = 0; i < face; ++i)
00188 opt::element(ima, st + k * face + i) = opt::element(ima, st + i);
00189
00190 trace::exiting("border::impl::duplicate_3D");
00191 }
00192
00193 }
00194
00195
00196 namespace internal
00197 {
00198
00199 template <typename I>
00200 void duplicate_dispatch_on(metal::int_<1>, I& ima)
00201 {
00202 impl::duplicate_1D(ima);
00203 }
00204
00205 template <typename I>
00206 void duplicate_dispatch_on(metal::int_<2>, I& ima)
00207 {
00208 impl::duplicate_2D(ima);
00209 }
00210
00211 template <typename I>
00212 void duplicate_dispatch_on(metal::int_<3>, I& ima)
00213 {
00214 impl::duplicate_3D(ima);
00215 }
00216
00217 template <typename I>
00218 void duplicate_dispatch_on(trait::image::speed::fastest,
00219 const Image<I>& ima)
00220 {
00221 typedef mln_site(I) P;
00222 duplicate_dispatch_on(metal::int_<P::dim>(),
00223 const_cast<I&>(exact(ima)));
00224 }
00225
00226 template <typename I>
00227 void duplicate_dispatch_on(trait::image::speed::any,
00228 const Image<I>& ima)
00229 {
00230
00231 }
00232
00233 template <typename I>
00234 void duplicate_dispatch_on(const Image<I>& ima)
00235 {
00236 duplicate_dispatch_on(mln_trait_image_speed(I)(),
00237 ima);
00238 }
00239
00240 template <typename I>
00241 void duplicate_dispatch(const Image<I>& ima)
00242 {
00243 duplicate_dispatch_on(primary(ima));
00244 }
00245
00246 }
00247
00248
00249
00250
00251 template <typename I>
00252 void duplicate(const Image<I>& ima)
00253 {
00254 trace::entering("border::duplicate");
00255 mln_precondition(exact(ima).is_valid());
00256
00257 if (border::get(ima) != 0)
00258 internal::duplicate_dispatch(ima);
00259
00260 trace::exiting("border::duplicate");
00261 }
00262
00263
00264 # endif // ! MLN_INCLUDE_ONLY
00265
00266 }
00267
00268 }
00269
00270
00271 #endif // ! MLN_BORDER_DUPLICATE_HH