$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
border/duplicate.hh
1 // Copyright (C) 2007, 2008, 2009, 2011, 2012 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_DUPLICATE_HH
28 # define MLN_BORDER_DUPLICATE_HH
29 
33 
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/routine/primary.hh>
36 # include <mln/core/box_runstart_piter.hh>
37 # include <mln/border/get.hh>
38 # include <mln/opt/element.hh>
39 
40 
41 namespace mln
42 {
43 
44  namespace border
45  {
46 
58  template <typename I>
59  void duplicate(const Image<I>& ima);
60 
61 
62 # ifndef MLN_INCLUDE_ONLY
63 
64  namespace impl
65  {
66 
67  template <typename I>
68  inline
69  void duplicate_1D(I& ima)
70  {
71  mln_trace("border::impl::duplicate_1D");
72 
73  typedef mln_psite(I) P;
74  mln_box_runstart_piter(I) pl(ima.domain());
75  unsigned len_c = ima.bbox().len(P::dim - 1);
76  unsigned border = ima.border();
77 
78  for (unsigned i = 0; i < border; ++i)
79  opt::element(ima, i) = opt::element(ima, border);
80 
81  unsigned st = border + len_c - 1;
82  for (unsigned i = st + 1; i < opt::nelements(ima); ++i)
83  opt::element(ima, i) = opt::element(ima, st);
84 
85  }
86 
87  template <typename I>
88  inline
89  void duplicate_2D(I& ima)
90  {
91  mln_trace("border::impl::duplicate_2D");
92 
93  typedef mln_psite(I) P;
94  mln_box_runstart_piter(I) pl(ima.domain());
95  unsigned border = ima.border();
96  unsigned border_2x = 2 * ima.border();
97  unsigned len_c = ima.bbox().len(1);
98  unsigned len_r = ima.bbox().len(0);
99  unsigned real_len_c = len_c + border_2x;
100  unsigned st;
101 
102  // Duplicate
103  for_all (pl)
104  {
105  st = ima.offset_of_point (pl);
106  for (unsigned i = 1; i <= border; ++i)
107  opt::element(ima, st - i) = opt::element(ima, st);
108  st = st + len_c - 1;
109  for (unsigned i = 1; i <= border; ++i)
110  opt::element(ima, st + i) = opt::element(ima, st);
111  }
112 
113  // Duplicate n first * border line
114  st = real_len_c * border;
115  for (unsigned k = 0; k < border; ++k)
116  for (unsigned i = 0; i < real_len_c; ++i)
117  opt::element(ima, k * real_len_c + i) = opt::element(ima, st + i);
118 
119  // Duplicate n last * border line
120  st = real_len_c * (border + len_r - 1);
121  for (unsigned k = 1; k <= border; ++k)
122  for (unsigned i = st; i < st + real_len_c; ++i)
123  opt::element(ima, k * real_len_c + i) = opt::element(ima, i);
124 
125  }
126 
127  template <typename I>
128  inline
129  void duplicate_3D(I& ima)
130  {
131  mln_trace("border::impl::duplicate_3D");
132 
133  mln_precondition(ima.is_valid());
134 
135  typedef mln_psite(I) P;
136  mln_box_runstart_piter(I) pl(ima.domain());
137  unsigned border = ima.border();
138  unsigned border_2x = 2 * ima.border();
139  unsigned len_c = ima.bbox().len(P::dim - 1);
140  unsigned len_r = ima.bbox().len(1);
141  unsigned len_s = ima.bbox().len(0);
142  unsigned real_len_c = len_c + border_2x;
143  unsigned real_len_r = len_r + border_2x;
144  unsigned face = real_len_c * real_len_r;
145  unsigned st;
146 
147  pl.start();
148 
149  for (unsigned k = 0; k < len_s; ++k)
150  {
151 
152  // Duplicate
153  for (unsigned j = 0; j < len_r; ++j)
154  {
155  st = ima.offset_of_point (pl);
156  for (unsigned i = 1; i <= border; ++i)
157  opt::element(ima, st - i) = opt::element(ima, st);
158  st = st + len_c - 1;
159  for (unsigned i = 1; i <= border; ++i)
160  opt::element(ima, st + i) = opt::element(ima, st);
161  pl.next();
162  }
163 
164  // Duplicate n last * border line
165  st = border * face + k * face + border * real_len_c ;
166  for (unsigned j = 1; j <= border; ++j)
167  for (unsigned i = 0; i < real_len_c; ++i)
168  opt::element(ima, st - j * real_len_c + i) =
169  opt::element(ima, st + i);
170 
171  // Duplicate n last * border line
172  st = border * face + k * face + (len_r + border - 1) * real_len_c ;
173  for (unsigned j = 1; j <= border; ++j)
174  for (unsigned i = 0; i < real_len_c; ++i)
175  opt::element(ima, st + j * real_len_c + i) =
176  opt::element(ima, st + i);
177  }
178 
179  // Duplicate n first * border face
180  st = border * face;
181  for (unsigned k = 0; k < border; ++k)
182  for (unsigned i = 0; i < face; ++i)
183  opt::element(ima, k * face + i) = opt::element(ima, st + i);
184 
185  // Duplicate n last * border face
186  st = (len_s + border - 1) * face;
187  for (unsigned k = 1; k <= border; ++k)
188  for (unsigned i = 0; i < face; ++i)
189  opt::element(ima, st + k * face + i) = opt::element(ima, st + i);
190 
191  }
192 
193  } // end of namespace mln::border::impl
194 
195 
196  namespace internal
197  {
198 
199  template <typename I>
200  void duplicate_dispatch_on(metal::int_<1>, I& ima)
201  {
202  impl::duplicate_1D(ima);
203  }
204 
205  template <typename I>
206  void duplicate_dispatch_on(metal::int_<2>, I& ima)
207  {
208  impl::duplicate_2D(ima);
209  }
210 
211  template <typename I>
212  void duplicate_dispatch_on(metal::int_<3>, I& ima)
213  {
214  impl::duplicate_3D(ima);
215  }
216 
217  template <typename I>
218  void duplicate_dispatch_on(trait::image::speed::fastest,
219  const Image<I>& ima)
220  {
221  typedef mln_site(I) P;
222  duplicate_dispatch_on(metal::int_<P::dim>(),
223  const_cast<I&>(exact(ima)));
224  }
225 
226  template <typename I>
227  void duplicate_dispatch_on(trait::image::speed::any,
228  const Image<I>& ima)
229  {
230  (void) ima;
231  // No-op.
232  }
233 
234  template <typename I>
235  void duplicate_dispatch_on(const Image<I>& ima)
236  {
237  duplicate_dispatch_on(mln_trait_image_speed(I)(),
238  ima);
239  }
240 
241  template <typename I>
242  void duplicate_dispatch(const Image<I>& ima)
243  {
244  duplicate_dispatch_on(primary(ima));
245  }
246 
247  } // end of namespace mln::border::internal
248 
249 
250  // Facade.
251 
252  template <typename I>
253  void duplicate(const Image<I>& ima)
254  {
255  mln_trace("border::duplicate");
256  mln_precondition(exact(ima).is_valid());
257 
258  if (border::get(ima) != 0)
259  internal::duplicate_dispatch(ima);
260 
261  }
262 
263 
264 # endif // ! MLN_INCLUDE_ONLY
265 
266  } // end of namespace mln::border
267 
268 } // end of namespace mln
269 
270 
271 #endif // ! MLN_BORDER_DUPLICATE_HH