$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
antialiased.hh
1 // Copyright (C) 2009, 2010, 2012, 2013 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_SUBSAMPLING_ANTIALIASED_HH
28 # define MLN_SUBSAMPLING_ANTIALIASED_HH
29 
33 
34 
35 #include <mln/core/concept/image.hh>
36 #include <mln/core/alias/point2d.hh>
37 #include <mln/border/thickness.hh>
38 #include <mln/extension/adjust_duplicate.hh>
39 #include <mln/core/macros.hh>
40 
41 namespace mln
42 {
43 
44  namespace subsampling
45  {
46 
56  template <typename I>
57  inline
58  mln_concrete(I)
59  antialiased(const Image<I>& input,
60  unsigned factor,
61  const mln_domain(I)& output_domain,
62  unsigned border_thickness);
63 
64 
68  template <typename I>
69  mln_concrete(I)
70  antialiased(const Image<I>& input, unsigned factor);
71 
72 
73 
74 # ifndef MLN_INCLUDE_ONLY
75 
76 
77 
78  // Tests
79 
80  namespace internal
81  {
82 
83  template <typename I>
84  inline
85  void
86  antialiased_tests(const Image<I>& input,
87  unsigned factor,
88  const mln_domain(I)& output_domain,
89  unsigned border_thickness)
90  {
91  typedef mln_site(I) P;
92 
93  mlc_is_a(mln_domain(I), Box)::check();
94  mln_precondition(exact(input).is_valid());
95  mln_precondition(exact(input).domain().pmin() == literal::origin);
96 
97  (void) input;
98  (void) factor;
99  (void) output_domain;
100  (void) border_thickness;
101  }
102 
103  } // end of namespace mln::subsampling::internal
104 
105 
106 
107 
108  // Implementations.
109 
110  namespace impl
111  {
112 
113  namespace generic
114  {
115 
116  template <typename I>
117  inline
118  mln_concrete(I)
119  antialiased(const Image<I>& input_,
120  unsigned factor,
121  const mln_domain(I)& output_domain,
122  unsigned border_thickness)
123  {
124  (void) input_;
125  (void) factor;
126  (void) output_domain;
127  (void) border_thickness;
128 
129  // To be written...
130  mlc_abort(I)::check();
131 
132  mln_concrete(I) output;
133  return output;
134  }
135 
136  } // end of namespace mln::subsampling::impl::generic
137 
138 
139 
140  template <typename I>
141  inline
142  mln_concrete(I)
143  antialiased_2d_fastest_scalar(const Image<I>& input_,
144  unsigned factor,
145  const mln_domain(I)& output_domain,
146  unsigned border_thickness)
147  {
148  mln_trace("subsampling::impl::antialiased_2d_fastest");
149 
150  internal::antialiased_tests(input_, factor,
151  output_domain, border_thickness);
152 
153  const I& input = exact(input_);
154 
155  // No reduction.
156  if (factor == 1)
157  {
158  return duplicate(input);
159  }
160 
161  typedef mln_value(I) V;
162  typedef mln_sum(V) S;
163 
164  typedef mln_site(I) P;
165  box<P> b = output_domain;
166  if (!b.is_valid())
167  {
168  P pmin = input.domain().pmin() / factor,
169  pmax = input.domain().pmax() / factor;
170  b = box<P>(pmin, pmax);
171  }
172  typedef mln_concrete(I) O;
173  O output(b, border_thickness);
174 
175  // Make sure there is enough data in input border.
176  unsigned input_border = factor - std::min(input.nrows() % factor,
177  input.ncols() % factor);
178  extension::adjust_duplicate(input, input_border);
179 
180 
181  typedef const V* ptr_t;
182 
183  util::array<ptr_t> ptrs(factor, 0);
184  for (unsigned i = 0; i < factor; ++i)
185  ptrs[i] = & input.at_(i, 0);
186 
187  mln_box_runstart_piter(O) s(output.domain());
188  const unsigned n = s.run_length();
189  const unsigned
190  factor_2 = factor * factor,
191  factor_round = factor_2 / 2;
192  unsigned offset = input.delta_offset(point2d(factor,0) - point2d(0,factor*n));
193 
194  for_all(s)
195  {
196  mln_value(O)* po = & output(s);
197  for (unsigned i = 0; i < n; ++i)
198  {
199  mln_sum(V) s = literal::zero;
200  for (unsigned j = 0; j < factor; ++j)
201  for (unsigned k = 0; k < factor; ++k)
202  s += *ptrs[j]++;
203 
204  convert::from_to((s + factor_round) / factor_2, *po);
205  ++po;
206  }
207 
208  for (unsigned j = 0; j < factor; ++j)
209  ptrs[j] += offset;
210  }
211 
212  return output;
213  }
214 
215 
216 
217  template <typename I>
218  inline
219  mln_concrete(I)
220  antialiased_2d_fastest_rgb(const Image<I>& input_,
221  unsigned factor,
222  const mln_domain(I)& output_domain,
223  unsigned border_thickness)
224  {
225  mln_trace("subsampling::impl::antialiased_2d_rgb");
226 
227  internal::antialiased_tests(input_, factor,
228  output_domain, border_thickness);
229 
230  const I& input = exact(input_);
231 
232 
233  // No reduction.
234  if (factor == 1)
235  {
236  return duplicate(input);
237  }
238 
239  typedef mln_value(I) V;
240  typedef mln_sum(V) S;
241 
242  typedef mln_site(I) P;
243  box<P> b = output_domain;
244  if (!b.is_valid())
245  {
246  P pmin = input.domain().pmin() / factor,
247  pmax = input.domain().pmax() / factor;
248  b = box<P>(pmin, pmax);
249  }
250  typedef mln_concrete(I) O;
251  O output(b, border_thickness);
252 
253  // Make sure there is enough data in input border.
254  unsigned input_border = factor - std::min(input.nrows() % factor,
255  input.ncols() % factor);
256  extension::adjust_duplicate(input, input_border);
257 
258 
259  typedef const V* ptr_t;
260 
261  util::array<ptr_t> ptrs(factor, 0);
262  for (unsigned i = 0; i < factor; ++i)
263  ptrs[i] = & input.at_(i, 0);
264 
265  mln_box_runstart_piter(O) s(output.domain());
266  const unsigned n = s.run_length();
267  const unsigned
268  factor_2 = factor * factor,
269  factor_round = factor_2 / 2;
270  unsigned offset = input.delta_offset(point2d(factor,0) - point2d(0,factor*n));
271 
272  for_all(s)
273  {
274  mln_value(O)* po = & output(s);
275  for (unsigned i = 0; i < n; ++i)
276  {
277  mln_sum(V) s = literal::zero;
278  for (unsigned j = 0; j < factor; ++j)
279  for (unsigned k = 0; k < factor; ++k)
280  {
281  algebra::vec<3, float> tmp = *ptrs[j]++;
282  s += tmp;
283  }
284 
285  // FIXME: should be removed and replaced by the
286  // commented part below.
287  for (unsigned j = 0; j < P::dim; ++j)
288  s[j] += factor_round;
289 
290  *po++ = (s /*+ factor_round*/) / factor_2;
291  }
292  for (unsigned j = 0; j < factor; ++j)
293  ptrs[j] += offset;
294  }
295 
296  return output;
297  }
298 
299 
300 
301  } // end of namespace mln::subsampling::impl
302 
303 
304 
305  // Dispatch.
306 
307  namespace internal
308  {
309 
310  template <unsigned dim, typename I>
311  inline
312  mln_concrete(I)
313  antialiased_dispatch(trait::image::value_alignment::any,
314  trait::image::value_storage::any,
315  trait::image::value_access::any,
316  const Image<I>& input,
317  unsigned factor,
318  const mln_domain(I)& output_domain,
319  unsigned border_thickness)
320  {
321  (void) input;
322  (void) factor;
323  (void) output_domain;
324  (void) border_thickness;
325 
326  // Not implemented yet.
327  mlc_abort(I)::check();
328  }
329 
330  template <typename I>
331  inline
332  mln_concrete(I)
333  antialiased_2d_fastest_dispatch(const mln_value(I)&,
334  const Image<I>& input,
335  unsigned factor,
336  const mln_domain(I)& output_domain,
337  unsigned border_thickness)
338  {
339  return impl::antialiased_2d_fastest_scalar(input, factor,
340  output_domain,
341  border_thickness);
342  }
343 
344 
345  template <unsigned n, typename I>
346  inline
347  mln_concrete(I)
348  antialiased_2d_fastest_dispatch(const value::rgb<n>&,
349  const Image<I>& input,
350  unsigned factor,
351  const mln_domain(I)& output_domain,
352  unsigned border_thickness)
353  {
354  return impl::antialiased_2d_fastest_rgb(input, factor,
355  output_domain,
356  border_thickness);
357  }
358 
359 
360  template <typename I>
361  inline
362  mln_concrete(I)
363  antialiased_2d_fastest_dispatch(const Image<I>& input,
364  unsigned factor,
365  const mln_domain(I)& output_domain,
366  unsigned border_thickness)
367  {
368  typedef mln_value(I) V;
369  return antialiased_2d_fastest_dispatch(V(), input, factor,
370  output_domain,
371  border_thickness);
372  }
373 
374 
375  template <typename I>
376  inline
377  mln_concrete(I)
378  antialiased_dispatch_2d(trait::image::value_alignment::with_grid,
379  trait::image::value_storage::one_block,
380  trait::image::value_access::direct,
381  const Image<I>& input,
382  unsigned factor,
383  const mln_domain(I)& output_domain,
384  unsigned border_thickness)
385  {
386  return antialiased_2d_fastest_dispatch(input, factor,
387  output_domain,
388  border_thickness);
389  }
390 
391 
392  template <typename I>
393  inline
394  mln_concrete(I)
395  antialiased_dispatch(const Image<I>& input,
396  unsigned factor,
397  const mln_domain(I)& output_domain,
398  unsigned border_thickness)
399  {
400  unsigned dim = mln_site_(I)::dim;
401 
402  if (dim == 2)
403  return antialiased_dispatch_2d(
404  mln_trait_image_value_alignment(I)(),
405  mln_trait_image_value_storage(I)(),
406  mln_trait_image_value_access(I)(),
407  input,
408  factor,
409  output_domain,
410  border_thickness);
411  else
412  mln_trace_warning("Not implemented yet.");
413 
414  mln_concrete(I) output;
415  return output;
416  }
417 
418  } // end of namespace mln::subsampling::internal
419 
420 
421 
422  // Facades.
423 
424  template <typename I>
425  inline
426  mln_concrete(I)
427  antialiased(const Image<I>& input,
428  unsigned factor,
429  const mln_domain(I)& output_domain,
430  unsigned border_thickness)
431  {
432  mln_trace("subsampling::antialiased");
433 
434  typedef mln_site(I) P;
435 
436  internal::antialiased_tests(input, factor,
437  output_domain, border_thickness);
438 
439  mln_concrete(I)
440  output = internal::antialiased_dispatch(input, factor,
441  output_domain,
442  border_thickness);
443 
444  return output;
445  }
446 
447 
448  template <typename I>
449  inline
450  mln_concrete(I)
451  antialiased(const Image<I>& input, unsigned factor)
452  {
453  mln_domain(I) domain;
454  return antialiased(input, factor, domain, border::thickness);
455  }
456 
457 
458 
459 # endif // ! MLN_INCLUDE_ONLY
460 
461  } // end of namespace mln::subsampling
462 
463 } // end of namespace mln
464 
465 
466 #endif // ! MLN_SUBSAMPLING_ANTIALIASED_HH