Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
border/mirror.hh
1 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_BORDER_MIRROR_HH
28 # define MLN_BORDER_MIRROR_HH
29 
39 
40 # include <mln/core/image/image1d.hh>
41 # include <mln/core/image/image2d.hh>
42 # include <mln/core/image/image3d.hh>
43 
44 # include <mln/core/concept/image.hh>
45 # include <mln/core/internal/fixme.hh>
46 # include <mln/core/internal/fixme.hh>
47 # include <mln/geom/min_row.hh>
48 # include <mln/geom/max_row.hh>
49 # include <mln/geom/min_col.hh>
50 # include <mln/geom/max_col.hh>
51 # include <mln/geom/ninds.hh>
52 
53 # include <mln/opt/element.hh>
54 
55 
56 namespace mln
57 {
58 
59  namespace border
60  {
61 
71  template <typename I>
72  void mirror(const Image<I>& ima);
73 
74 
75 # ifndef MLN_INCLUDE_ONLY
76 
77  namespace impl
78  {
79 
80  template <typename I>
81  inline
82  void mirror_(const box1d&, const I& ima_)
83  {
84  trace::entering("border::impl::mirror_");
85  I& ima = const_cast<I&>(ima_);
86 
88  border = static_cast<def::coord>(ima.border()),
89  nbinds = static_cast<def::coord>(geom::ninds(ima)),
90  min;
91 
92  if (border > nbinds)
93  min = nbinds;
94  else
95  min = border;
96 
98  {
99  def::coord i = 0;
100  for (; i < min; ++i)
101  opt::element(ima, border - 1 - i) = ima(point1d(i));
102 
103  for (; i < border; ++i)
104  opt::element(ima, border - 1 - i) = ima(point1d(static_cast<def::coord>(min - 1)));
105  }
106 
108  {
109  def::coord
110  i = 0,
111  j = static_cast<def::coord>(nbinds - 1);
112  for (;
113  i < min;
114  ++i, --j)
115  opt::element(ima, border + nbinds + i) = ima(point1d(j));
116  ++j;
117  for (;
118  i < border;
119  ++i)
120  opt::element(ima, border + nbinds + i) = ima(point1d(j));
121  }
122  trace::exiting("border::impl::mirror_");
123  }
124 
125  template <typename I>
126  inline
127  void mirror_(const box2d&, const I& ima_)
128  {
129  trace::entering("border::impl::mirror_");
130  I& ima = const_cast<I&>(ima_);
131 
132  unsigned border = ima.border ();
133  unsigned nbrows = geom::max_row(ima) - geom::min_row(ima);
134  unsigned nbcols = geom::max_col(ima) - geom::min_col(ima);
135  unsigned real_nbcols = (nbcols + 1) + 2 * border;
136  unsigned start = real_nbcols * border + border;
137  unsigned s = start;
138 
139  // mirror top left corner
140  for (unsigned i = 0; i < border; ++i)
141  for (unsigned j = 0; j < border; ++j)
142  opt::element(ima, i * ((nbcols + 1) + 2 * border) + j) =
143  opt::element(ima, s);
144 
145  // mirror top left corner
146  s = start + nbcols;
147  for (unsigned i = 0; i < border; ++i)
148  for (unsigned j = 1; j <= border; ++j)
149  opt::element(ima, i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)) = opt::element(ima, s);
150 
151  // mirror bottom left corner
152  s = start + (nbrows * real_nbcols);
153  for (unsigned i = 1; i <= border; ++i)
154  for (unsigned j = 1; j <= border; ++j)
155  opt::element(ima, s - i + (j * (real_nbcols))) =
156  opt::element(ima, s);
157 
158  // mirror bottom right corner
159  s = start + (nbrows * real_nbcols) + nbcols;
160  for (unsigned i = 1; i <= border; ++i)
161  for (unsigned j = 1; j <= border; ++j)
162  opt::element(ima, s + i + (j * real_nbcols)) =
163  opt::element(ima, s);
164 
165  // mirror top border
166  s = start;
167  for (unsigned i = 0; i <= nbcols; ++i)
168  for (unsigned j = 1; j <= border; ++j)
169  opt::element(ima, s + i - (j * real_nbcols)) =
170  opt::element(ima, s + i + ((j - 1)* real_nbcols));
171 
172  // mirror left border
173  s = start;
174  for (unsigned i = 0; i <= nbrows; ++i)
175  for (unsigned j = 1; j <= border; ++j)
176  opt::element(ima, s + (i * real_nbcols) - j) =
177  opt::element(ima, s + (i * real_nbcols) + (j - 1));
178 
179  // mirror right border
180  s = start;
181  for (unsigned i = 0; i <= nbrows; ++i)
182  for (unsigned j = 1; j <= border; ++j)
183  opt::element(ima, s + (i * real_nbcols + nbcols) + j) =
184  opt::element(ima, s + (i * real_nbcols + nbcols) - (j - 1));
185 
186  // mirror bottom border
187  s = start + (nbrows * real_nbcols);
188  for (unsigned i = 0; i <= nbcols; ++i)
189  for (unsigned j = 1; j <= border; ++j)
190  opt::element(ima, s + i + (j * real_nbcols)) =
191  opt::element(ima, s + i - ((j - 1)* real_nbcols));
192 
193  trace::exiting("border::impl::mirror_");
194  }
195 
196  template <typename I>
197  inline
198  void mirror_(const box3d&, const I& ima)
199  {
200  trace::warning("border::mirror for 3D image is not implemented,"
201  " so image borders have not been mirrored!");
202  (void) ima;
203  // FIXME write it!
204  }
205 
206 
207  } // end of namespace mln::border::impl
208 
209 
210  template <typename I>
211  inline
212  void mirror(const Image<I>& ima_)
213  {
214  trace::entering("border::mirror");
215 
216  const I& ima = exact(ima_);
217 
218  mln_precondition(ima.is_valid());
219  mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
220 
221  typedef mln_psite(I) P;
222 
223  if (!ima.border ())
224  return;
225 
226  impl::mirror_(ima.bbox(), ima);
227 
228  trace::exiting("border::mirror");
229  }
230 
231 # endif // ! MLN_INCLUDE_ONLY
232 
233  } // end of namespace mln::border
234 
235 } // end of namespace mln
236 
237 
238 #endif // ! MLN_BORDER_MIRROR_HH