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_VERTICAL_SYMMETRY_HH
00031 # define MLN_GEOM_VERTICAL_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 vertical_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 vertical_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>
00072 pi(input.domain()),
00073 po(output.domain());
00074
00075 unsigned ncols = input.ncols();
00076
00077 for_all_2(pi, po)
00078 {
00079 mln_site(I) idi = pi, ido = po;
00080 ido[1] = ncols - 1;
00081 for (unsigned n = 0; n < ncols; ++n, ++idi[1], --ido[1])
00082 output(ido) = input(idi);
00083 }
00084
00085 return output;
00086 }
00087
00088 }
00089
00090
00091 template <typename I>
00092 mln_concrete(I)
00093 vertical_symmetry_fastest(const Image<I>& input_)
00094 {
00095 const I& input = exact(input_);
00096 mln_precondition(input.is_valid());
00097
00098 mln_concrete(I) output(input.domain());
00099
00100 typedef mln_site(I) P;
00101 box_runstart_piter<P>
00102 pi(input.domain()),
00103 po(output.domain());
00104
00105 unsigned ncols = input.ncols();
00106
00107 typedef mln_value(I)* ptr_t;
00108
00109 for_all_2(pi, po)
00110 {
00111 const mln_value(I)* ptr_in = & input(pi);
00112 ptr_t ptr_out = (& output(po)) + ncols - 1;
00113
00114 for (unsigned n = 0; n < ncols; ++n)
00115 *ptr_out-- = *ptr_in++;
00116 }
00117
00118 return output;
00119 }
00120
00121
00122 }
00123
00124
00125
00126
00127
00128 namespace internal
00129 {
00130
00131 template <typename I>
00132 mln_concrete(I)
00133 vertical_symmetry_dispatch(
00134 trait::image::value_alignment::any,
00135 trait::image::value_storage::any,
00136 trait::image::value_access::any,
00137 const Image<I>& input)
00138 {
00139 return impl::generic::vertical_symmetry(input);
00140 }
00141
00142
00143 template <typename I>
00144 mln_concrete(I)
00145 vertical_symmetry_dispatch(
00146 trait::image::value_alignment::with_grid,
00147 trait::image::value_storage::one_block,
00148 trait::image::value_access::direct,
00149 const Image<I>& input)
00150 {
00151 return impl::vertical_symmetry_fastest(input);
00152 }
00153
00154
00155 template <typename I>
00156 mln_concrete(I)
00157 vertical_symmetry_dispatch(const Image<I>& input)
00158 {
00159 return vertical_symmetry_dispatch(
00160 mln_trait_image_value_alignment(I)(),
00161 mln_trait_image_value_storage(I)(),
00162 mln_trait_image_value_access(I)(),
00163 input);
00164 }
00165
00166 }
00167
00168
00169
00170
00171
00172 template <typename I>
00173 mln_concrete(I)
00174 vertical_symmetry(const Image<I>& input_)
00175 {
00176 trace::entering("geom::vertical_symmetry");
00177
00178 const I& input = exact(input_);
00179 mln_precondition(input.is_valid());
00180
00181 mln_concrete(I) output = internal::vertical_symmetry_dispatch(input);
00182
00183 trace::exiting("geom::vertical_symmetry");
00184 return output;
00185 }
00186
00187
00188 # endif // ! MLN_INCLUDE_ONLY
00189
00190
00191 }
00192
00193 }
00194
00195
00196 #endif // ! MLN_GEOM_VERTICAL_SYMMETRY_HH