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