directional.hh 4.04 KB
Newer Older
1
2
// Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and
// Development Laboratory (LRDE)
3
//
4
// This file is part of Olena.
5
//
6
7
8
9
10
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena is distributed in the hope that it will be useful,
11
12
13
14
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// 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
22
23
24
25
// file, or you compile this file and link it with other files to produce
// an executable, this file does not by itself cause the resulting
// executable to be covered by the GNU General Public License.  This
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
26

Simon Nivault's avatar
Simon Nivault committed
27
28
#ifndef MLN_CANVAS_BROWSING_DIRECTIONAL_HH
# define MLN_CANVAS_BROWSING_DIRECTIONAL_HH
29

30
/// \file
31
32
///
/// Directional browsing of an image.
33

34
35
36
# include <mln/core/concept/browsing.hh>
# include <mln/core/concept/image.hh>

37
38
39
40
41
42
namespace mln
{

  namespace canvas
  {

43
    namespace browsing
44
    {
45

46
      /// Browsing in a certain direction.
47
48
49
50
51
52
53
54
55
56
57
58
      /*!
       * This canvas browse all the point of an image 'input' of type
       * 'I' and of dimension 'dim' in the direction 'dir'.
       *
       * The functor should provide (In addition to 'input', 'I',
       * 'dim' and 'dir') three methods :
       *
       *   - init() : Will be called at the beginning.
       *   - next() : Will be called at each point 'p' (also provided by
       *   the fonctor).
       *   - final(): Will be called at the end.
       *
59
60
61
62
63
64
65
66
67
68
69
       * F shall features : \n
       * { \n
       * --- as types: \n
       *   I; \n
       * --- as attributes: \n
       *   dim; \n
       *   dir; // and test dir < dim \n
       *   input; \n
       *   p; \n
       * --- as methods: \n
       *   void init(); \n
70
71
       *   void next(); \n
       *   void final(); \n
72
73
       * } \n
       *
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
       * Example : \n
       *
       *   1 0 0
       *  2 0 0
       * 3 0 0
       *
       *   4 0 0
       *  5 0 0
       * 6 0 0
       *
       *   7 0 0
       *  8 0 0
       * 9 0 0
       *
       *
89
90
91
       */
      struct directional_t : public Browsing< directional_t >
      {
92
93
94
95
	// This default constructor is needed for compilation with gcc
	// 4.6.0, gcc 4.6.1 and Clang.
	directional_t();

96
97
	template <typename F>
	void operator()(F& f) const;
98
      };
99

100
      extern const directional_t directional;
101

102
# ifndef MLN_INCLUDE_ONLY
103

104
105
#  ifndef MLN_WO_GLOBAL_VARS

106
107
      const directional_t directional;

108
109
# endif // ! MLN_WO_GLOBAL_VARS

110
      inline
111
112
113
114
      directional_t::directional_t()
      {
      }

115
      template <typename F>
116
      inline
117
118
      void
      directional_t::operator()(F& f) const
119
      {
120
	trace::entering("canvas::browsing::directional");
121
122
	mln_precondition(f.dir < f.dim);
	typedef typename F::I I;
123

124
	mln_psite(I)
125
126
	  pmin = f.input.domain().pmin(),
	  pmax = f.input.domain().pmax();
127

128
	f.p = pmin;
129

130
	f.init();
131

132
	do
133
	{
134

135
136
137
138
139
140
141
142
143
144
145
	  // Browse the run
	  f.init_run();
	  while (f.p[f.dir] <= pmax[f.dir])
	  {
	    f.next();
	    ++f.p[f.dir];
	  }
	  f.p[f.dir] = pmin[f.dir];


	  // Select the next run start
146
	  for (int c = F::dim - 1; c >= 0; --c)
147
	  {
148
149
150
151
152
153
154
155
	    if (c == int(f.dir))
	      continue;
	    if (f.p[c] != pmax[c])
	    {
	      ++f.p[c];
	      break;
	    }
	    f.p[c] = pmin[c];
156
	  }
157

158
159
160
	} while (f.p != pmin);

	f.final();
161
	trace::exiting("canvas::browsing::directional");
162
      }
163
164
165

# endif // ! MLN_INCLUDE_ONLY

166
167
168
    } // end of namespace mln::canvas::browsing

  } // end of namespace mln::canvas
169
170
171

} // end of namespace mln

Simon Nivault's avatar
Simon Nivault committed
172
#endif // ! MLN_CANVAS_BROWSING_DIRECTIONAL_HH