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
00029
00030 #ifndef MLN_GEOM_HORIZONTAL_SYMMETRY_HH
00031 # define MLN_GEOM_HORIZONTAL_SYMMETRY_HH
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/box_runend_piter.hh>
00035 # include <mln/core/box_runstart_piter.hh>
00036
00037 namespace mln
00038 {
00039
00040 namespace geom
00041 {
00042
00044
00045 template <typename I>
00046 mln_concrete(I)
00047 horizontal_symmetry(const Image<I>& input);
00048
00049
00050 # ifndef MLN_INCLUDE_ONLY
00051
00052
00053
00054
00055 namespace impl
00056 {
00057
00058 namespace generic
00059 {
00060
00061 template <typename I>
00062 mln_concrete(I)
00063 horizontal_symmetry(const Image<I>& input_)
00064 {
00065 const I& input = exact(input_);
00066 mln_precondition(input.is_valid());
00067
00068 mln_concrete(I) output(input.domain());
00069
00070 typedef mln_site(I) P;
00071 box_runstart_piter<P> pi(input.domain());
00072 box_runend_piter<P> po(output.domain());
00073
00074 unsigned ncols = input.ncols();
00075
00076 for_all_2(pi, po)
00077 {
00078 mln_site(I) idi = pi, ido = po;
00079 ido[1] -= ncols - 1;
00080 for (unsigned n = 0; n < ncols; ++n, ++idi[1], ++ido[1])
00081 output(ido) = input(idi);
00082 }
00083
00084 return output;
00085 }
00086
00087 }
00088
00089
00090 template <typename I>
00091 mln_concrete(I)
00092 horizontal_symmetry_fastest(const Image<I>& input_)
00093 {
00094 const I& input = exact(input_);
00095 mln_precondition(input.is_valid());
00096
00097 mln_concrete(I) output(input.domain());
00098
00099 typedef mln_site(I) P;
00100 box_runstart_piter<P> pi(input.domain());
00101 box_runend_piter<P> po(output.domain());
00102
00103 unsigned ncols = input.ncols();
00104
00105 typedef mln_value(I)* ptr_t;
00106
00107 for_all_2(pi, po)
00108 {
00109 const mln_value(I)* ptr_in = & input(pi);
00110 ptr_t ptr_out = (& output(po)) - ncols + 1;
00111
00112 for (unsigned n = 0; n < ncols; ++n)
00113 *ptr_out++ = *ptr_in++;
00114 }
00115
00116 return output;
00117 }
00118
00119
00120 }
00121
00122
00123
00124
00125
00126 namespace internal
00127 {
00128
00129 template <typename I>
00130 mln_concrete(I)
00131 horizontal_symmetry_dispatch(
00132 trait::image::value_alignment::any,
00133 trait::image::value_storage::any,
00134 trait::image::value_access::any,
00135 const Image<I>& input)
00136 {
00137 return impl::generic::horizontal_symmetry(input);
00138 }
00139
00140
00141 template <typename I>
00142 mln_concrete(I)
00143 horizontal_symmetry_dispatch(
00144 trait::image::value_alignment::with_grid,
00145 trait::image::value_storage::one_block,
00146 trait::image::value_access::direct,
00147 const Image<I>& input)
00148 {
00149 return impl::horizontal_symmetry_fastest(input);
00150 }
00151
00152
00153 template <typename I>
00154 mln_concrete(I)
00155 horizontal_symmetry_dispatch(const Image<I>& input)
00156 {
00157 return horizontal_symmetry_dispatch(
00158 mln_trait_image_value_alignment(I)(),
00159 mln_trait_image_value_storage(I)(),
00160 mln_trait_image_value_access(I)(),
00161 input);
00162 }
00163
00164 }
00165
00166
00167
00168
00169
00170 template <typename I>
00171 mln_concrete(I)
00172 horizontal_symmetry(const Image<I>& input_)
00173 {
00174 trace::entering("geom::horizontal_symmetry");
00175
00176 const I& input = exact(input_);
00177 mln_precondition(input.is_valid());
00178
00179 mln_concrete(I) output = internal::horizontal_symmetry_dispatch(input);
00180
00181 trace::exiting("geom::horizontal_symmetry");
00182 return output;
00183 }
00184
00185
00186 # endif // ! MLN_INCLUDE_ONLY
00187
00188
00189 }
00190
00191 }
00192
00193
00194 #endif // ! MLN_GEOM_HORIZONTAL_SYMMETRY_HH