$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
border/mirror.hh
1 // Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013 EPITA Research and
2 // Development 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 
73  template <typename I>
74  void mirror(const Image<I>& ima);
75 
76 
77 # ifndef MLN_INCLUDE_ONLY
78 
79  namespace impl
80  {
81 
82  template <typename I>
83  inline
84  void mirror_(const box1d&, const I& ima_)
85  {
86  mln_trace("border::impl::mirror_");
87  I& ima = const_cast<I&>(ima_);
88 
90  border = static_cast<def::coord>(ima.border()),
91  nbinds = static_cast<def::coord>(geom::ninds(ima)),
92  min;
93 
94  if (border > nbinds)
95  min = nbinds;
96  else
97  min = border;
98 
100  {
101  def::coord i = 0;
102  for (; i < min; ++i)
103  opt::element(ima, border - 1 - i) = ima(point1d(i));
104 
105  for (; i < border; ++i)
106  opt::element(ima, border - 1 - i) = ima(point1d(static_cast<def::coord>(min - 1)));
107  }
108 
110  {
111  def::coord
112  i = 0,
113  j = static_cast<def::coord>(nbinds - 1);
114  for (;
115  i < min;
116  ++i, --j)
117  opt::element(ima, border + nbinds + i) = ima(point1d(j));
118  ++j;
119  for (;
120  i < border;
121  ++i)
122  opt::element(ima, border + nbinds + i) = ima(point1d(j));
123  }
124  }
125 
126  template <typename I>
127  inline
128  void mirror_(const box2d&, const I& ima_)
129  {
130  mln_trace("border::impl::mirror_");
131  I& ima = const_cast<I&>(ima_);
132 
133  unsigned border = ima.border ();
134  unsigned nbrows = geom::max_row(ima) - geom::min_row(ima);
135  unsigned nbcols = geom::max_col(ima) - geom::min_col(ima);
136  unsigned real_nbcols = (nbcols + 1) + 2 * border;
137  unsigned start = real_nbcols * border + border;
138  unsigned s = start;
139 
140  // mirror top left corner
141  for (unsigned i = 0; i < border; ++i)
142  for (unsigned j = 0; j < border; ++j)
143  opt::element(ima, i * ((nbcols + 1) + 2 * border) + j) =
144  opt::element(ima, s);
145 
146  // mirror top left corner
147  s = start + nbcols;
148  for (unsigned i = 0; i < border; ++i)
149  for (unsigned j = 1; j <= border; ++j)
150  opt::element(ima, i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)) = opt::element(ima, s);
151 
152  // mirror bottom left corner
153  s = start + (nbrows * real_nbcols);
154  for (unsigned i = 1; i <= border; ++i)
155  for (unsigned j = 1; j <= border; ++j)
156  opt::element(ima, s - i + (j * (real_nbcols))) =
157  opt::element(ima, s);
158 
159  // mirror bottom right corner
160  s = start + (nbrows * real_nbcols) + nbcols;
161  for (unsigned i = 1; i <= border; ++i)
162  for (unsigned j = 1; j <= border; ++j)
163  opt::element(ima, s + i + (j * real_nbcols)) =
164  opt::element(ima, s);
165 
166  // mirror top border
167  s = start;
168  for (unsigned i = 0; i <= nbcols; ++i)
169  for (unsigned j = 1; j <= border; ++j)
170  opt::element(ima, s + i - (j * real_nbcols)) =
171  opt::element(ima, s + i + ((j - 1)* real_nbcols));
172 
173  // mirror left border
174  s = start;
175  for (unsigned i = 0; i <= nbrows; ++i)
176  for (unsigned j = 1; j <= border; ++j)
177  opt::element(ima, s + (i * real_nbcols) - j) =
178  opt::element(ima, s + (i * real_nbcols) + (j - 1));
179 
180  // mirror right border
181  s = start;
182  for (unsigned i = 0; i <= nbrows; ++i)
183  for (unsigned j = 1; j <= border; ++j)
184  opt::element(ima, s + (i * real_nbcols + nbcols) + j) =
185  opt::element(ima, s + (i * real_nbcols + nbcols) - (j - 1));
186 
187  // mirror bottom border
188  s = start + (nbrows * real_nbcols);
189  for (unsigned i = 0; i <= nbcols; ++i)
190  for (unsigned j = 1; j <= border; ++j)
191  opt::element(ima, s + i + (j * real_nbcols)) =
192  opt::element(ima, s + i - ((j - 1)* real_nbcols));
193 
194  }
195 
196  template <typename I>
197  inline
198  void mirror_(const box3d&, const I& ima)
199  {
200  mln_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  mln_trace("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  }
229 
230 # endif // ! MLN_INCLUDE_ONLY
231 
232  } // end of namespace mln::border
233 
234 } // end of namespace mln
235 
236 
237 #endif // ! MLN_BORDER_MIRROR_HH