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