$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lazy_recorder.hh
1 // Copyright (C) 2011, 2012 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef APPS_MORPHERS_LAZY_RECORDER_HH
27 # define APPS_MORPHERS_LAZY_RECORDER_HH
28 
38 
39 #include <sstream>
40 #include <iomanip>
41 
42 #include <string>
43 
44 #include <mln/trait/ch_value.hh>
45 
46 #include <mln/core/image/imorph/decorated_image.hh>
47 
48 #include <mln/value/rgb8.hh>
49 
50 #include <mln/core/routine/duplicate.hh>
51 
52 #include <mln/io/ppm/save.hh>
53 
54 #include "apps/data.hh"
55 
56 
57 // Forward declaration.
58 template <typename I> struct lazy_recorder;
59 
60 /* FIXME: mln::decorated_image lacks a proper definition of
61  properties! (see mln/core/image/imorph/decorated_image.hh). We use
62  the following (minimal) set of properties as a workaround for the
63  lazy_recorder decoration. */
64 namespace mln
65 {
66  namespace trait
67  {
68 
69  template <typename I>
70  struct image_< decorated_image< I, lazy_recorder<I> > >
71  : default_image_morpher< I,
72  mln_value(I),
73  decorated_image< I, lazy_recorder<I> > >
74  {
75  typedef trait::image::category::identity_morpher category;
76 
77  // Prevent fast processing of images requiring a specific
78  // interface that we are unable to retrieve now.
79  typedef trait::image::value_storage::disrupted value_storage;
80  };
81 
82  } // end of namespace mln::trait
83 
84 } // end of namespace mln
85 
86 
87 // ``Lazy'' recorder.
88 template <typename I>
90 {
92  {
93  }
94 
96  : initial(mln::duplicate(ima))
97  {
98  }
99 
100  void reading(const I&, const mln_psite(I)&) const
101  {
102  // N/A.
103  }
104 
105  void writing(I&, const mln_psite(I)& p, const mln_value(I)& v)
106  {
107  sequence.push_back(std::make_pair(p, v));
108  }
109 
111  mln_concrete(I) initial;
113  // Make it a tracked_ptr to avoid costly copy operations?
114  std::vector< std::pair<mln_psite(I), mln_value(I)> > sequence;
115 };
116 
117 /* Skeleton of an image decorated with a lazy_recorder.
118 
119  Initialy, I (Roland) wanted to add this to mln/trait/ch_value.hh:
120 
121  template < template <class, class> class M, typename I, typename D,
122  typename V >
123  struct ch_value_< M< tag::image_<I>, tag::data_<D> >, V >
124  {
125  typedef M< mln_ch_value(I, V), D > ret;
126  };
127 
128  However, this would not work in the case of the lazy_recorder since the
129  type D of the data attached to the image (of type I) has to be
130  changed as well. Indeed the initial decoration contains a sequence
131  of images of type I, which should be changed into a sequence of
132  images of type mln_ch_value(I, V).
133 
134  There are several option to improve this. One is to create a
135  ch_value trait for data/decorations such as `lazy_recorder<I>'. Another
136  one is to refine the skeleton of decorated_image<I, D> to have it
137  convey the type the data stored in the decoration, e.g, changing
138 
139  typedef decorated_image< tag::image_<I>, tag::data_<D> > skeleton;
140 
141  into something like
142 
143  typedef decorated_image< tag::image_<I>, tag::data_<D, V> > skeleton;
144 
145  but this seems overly complicated.
146 
147  The workaround chosen here is very local, and address the very
148  specific case of decorated_image< I, lazy_recorder<I> >. */
149 
150 namespace mln
151 {
152  namespace trait
153  {
154  namespace impl
155  {
156  template < typename I, typename V >
157  struct ch_value_< decorated_image< tag::image_<I>,
158  tag::data_< lazy_recorder<I> > >,
159  V >
160  {
161  typedef decorated_image< mln_ch_value(I, V),
163  };
164  } // end namespace mln::trait::impl
165 
166  } // end namespace mln::trait
167 
168 } // end namespace mln
169 
170 // Helper.
171 template <typename I>
172 inline
174 lazy_record(mln::Image<I>& ima)
175 {
176  return mln::decorate(ima, lazy_recorder<I>(ima));
177 }
178 
179 
180 // I/O.
181 namespace ppm
182 {
183  template <typename I>
184  inline
185  void
187  const std::string& prefix)
188  {
189  mln_concrete(I) frame = mln::duplicate(rec.decoration().initial);
190  for (size_t i = 0; i < rec.decoration().sequence.size(); ++i)
191  {
192  std::stringstream s;
193  s << std::setfill ('0') << std::setw (6) << i;
194  mln::io::ppm::save(frame, prefix + s.str() + ".ppm");
195  // Apply the I-th change to the next frame.
196  //
197  // Changes are applied after the I-th image has been written,
198  // to mimic the behavior of the original recorder morpher (see
199  // recorder.hh).
200  frame(rec.decoration().sequence[i].first) =
201  rec.decoration().sequence[i].second;
202  }
203  }
204 }
205 
206 #endif // ! APPS_MORPHERS_LAZY_RECORDER_HH