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_MIRROR_HH
00027 # define MLN_BORDER_MIRROR_HH
00028
00035
00036 # include <mln/core/image/image1d.hh>
00037 # include <mln/core/image/image2d.hh>
00038 # include <mln/core/image/image3d.hh>
00039
00040 # include <mln/core/concept/image.hh>
00041 # include <mln/core/internal/fixme.hh>
00042 # include <mln/core/internal/fixme.hh>
00043 # include <mln/geom/min_row.hh>
00044 # include <mln/geom/max_row.hh>
00045 # include <mln/geom/min_col.hh>
00046 # include <mln/geom/max_col.hh>
00047 # include <mln/geom/ninds.hh>
00048
00049 # include <mln/opt/element.hh>
00050
00051
00052 namespace mln
00053 {
00054
00055 namespace border
00056 {
00057
00067 template <typename I>
00068 void mirror(const Image<I>& ima);
00069
00070
00071 # ifndef MLN_INCLUDE_ONLY
00072
00073 namespace impl
00074 {
00075
00076 template <typename I>
00077 inline
00078 void mirror_(const box1d&, const I& ima_)
00079 {
00080 trace::entering("border::impl::mirror_");
00081 I& ima = const_cast<I&>(ima_);
00082
00083 def::coord
00084 border = static_cast<def::coord>(ima.border()),
00085 nbinds = static_cast<def::coord>(geom::ninds(ima)),
00086 min;
00087
00088 if (border > nbinds)
00089 min = nbinds;
00090 else
00091 min = border;
00092
00094 {
00095 def::coord i = 0;
00096 for (; i < min; ++i)
00097 opt::element(ima, border - 1 - i) = ima(point1d(i));
00098
00099 for (; i < border; ++i)
00100 opt::element(ima, border - 1 - i) = ima(point1d(static_cast<def::coord>(min - 1)));
00101 }
00102
00104 {
00105 def::coord
00106 i = 0,
00107 j = static_cast<def::coord>(nbinds - 1);
00108 for (;
00109 i < min;
00110 ++i, --j)
00111 opt::element(ima, border + nbinds + i) = ima(point1d(j));
00112 ++j;
00113 for (;
00114 i < border;
00115 ++i)
00116 opt::element(ima, border + nbinds + i) = ima(point1d(j));
00117 }
00118 trace::exiting("border::impl::mirror_");
00119 }
00120
00121 template <typename I>
00122 inline
00123 void mirror_(const box2d&, const I& ima_)
00124 {
00125 trace::entering("border::impl::mirror_");
00126 I& ima = const_cast<I&>(ima_);
00127
00128 unsigned border = ima.border ();
00129 unsigned nbrows = geom::max_row(ima) - geom::min_row(ima);
00130 unsigned nbcols = geom::max_col(ima) - geom::min_col(ima);
00131 unsigned real_nbcols = (nbcols + 1) + 2 * border;
00132 unsigned start = real_nbcols * border + border;
00133 unsigned s = start;
00134
00135
00136 for (unsigned i = 0; i < border; ++i)
00137 for (unsigned j = 0; j < border; ++j)
00138 opt::element(ima, i * ((nbcols + 1) + 2 * border) + j) =
00139 opt::element(ima, s);
00140
00141
00142 s = start + nbcols;
00143 for (unsigned i = 0; i < border; ++i)
00144 for (unsigned j = 1; j <= border; ++j)
00145 opt::element(ima, i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)) = opt::element(ima, s);
00146
00147
00148 s = start + (nbrows * real_nbcols);
00149 for (unsigned i = 1; i <= border; ++i)
00150 for (unsigned j = 1; j <= border; ++j)
00151 opt::element(ima, s - i + (j * (real_nbcols))) =
00152 opt::element(ima, s);
00153
00154
00155 s = start + (nbrows * real_nbcols) + nbcols;
00156 for (unsigned i = 1; i <= border; ++i)
00157 for (unsigned j = 1; j <= border; ++j)
00158 opt::element(ima, s + i + (j * real_nbcols)) =
00159 opt::element(ima, s);
00160
00161
00162 s = start;
00163 for (unsigned i = 0; i <= nbcols; ++i)
00164 for (unsigned j = 1; j <= border; ++j)
00165 opt::element(ima, s + i - (j * real_nbcols)) =
00166 opt::element(ima, s + i + ((j - 1)* real_nbcols));
00167
00168
00169 s = start;
00170 for (unsigned i = 0; i <= nbrows; ++i)
00171 for (unsigned j = 1; j <= border; ++j)
00172 opt::element(ima, s + (i * real_nbcols) - j) =
00173 opt::element(ima, s + (i * real_nbcols) + (j - 1));
00174
00175
00176 s = start;
00177 for (unsigned i = 0; i <= nbrows; ++i)
00178 for (unsigned j = 1; j <= border; ++j)
00179 opt::element(ima, s + (i * real_nbcols + nbcols) + j) =
00180 opt::element(ima, s + (i * real_nbcols + nbcols) - (j - 1));
00181
00182
00183 s = start + (nbrows * real_nbcols);
00184 for (unsigned i = 0; i <= nbcols; ++i)
00185 for (unsigned j = 1; j <= border; ++j)
00186 opt::element(ima, s + i + (j * real_nbcols)) =
00187 opt::element(ima, s + i - ((j - 1)* real_nbcols));
00188
00189 trace::exiting("border::impl::mirror_");
00190 }
00191
00192 template <typename I>
00193 inline
00194 void mirror_(const box3d&, const I& ima)
00195 {
00196 mln::internal::fixme();
00197 }
00198
00199
00200 }
00201
00202
00203 template <typename I>
00204 inline
00205 void mirror(const Image<I>& ima_)
00206 {
00207 trace::entering("border::mirror");
00208
00209 const I& ima = exact(ima_);
00210
00211 mln_precondition(ima.is_valid());
00212 mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
00213
00214 typedef mln_psite(I) P;
00215
00216 if (!ima.border ())
00217 return;
00218
00219 impl::mirror_(ima.bbox(), ima);
00220
00221 trace::exiting("border::mirror");
00222 }
00223
00224 # endif // ! MLN_INCLUDE_ONLY
00225
00226 }
00227
00228 }
00229
00230
00231 #endif // ! MLN_BORDER_MIRROR_HH