Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
pnm/load.hh
1 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 MLN_IO_PNM_LOAD_HH
27 # define MLN_IO_PNM_LOAD_HH
28 
33 
34 # include <iostream>
35 # include <fstream>
36 # include <string>
37 
38 # include <mln/core/image/image2d.hh>
39 
40 # include <mln/value/int_u8.hh>
41 # include <mln/value/rgb.hh>
42 
43 # include <mln/io/pnm/load_header.hh>
44 # include <mln/io/pnm/max_component.hh>
45 # include <mln/io/pnm/macros.hh>
46 
47 # include <mln/metal/is_a.hh>
48 
49 namespace mln
50 {
51 
52  namespace io
53  {
54 
55  namespace pnm
56  {
57 
58 
59 # ifndef MLN_INCLUDE_ONLY
60 
61  template <typename I>
62  void load_ascii_value(std::ifstream& file, I& ima);
63 
64  template <typename I>
65  void load_ascii_builtin(std::ifstream& file, I& ima);
66 
67 
68  namespace internal
69  {
70 
71  template <typename I>
72  inline
73  void
74  load_ascii_dispatch(std::ifstream& file, I& ima, const metal::bool_<true>&)
75  {
76  load_ascii_value(file, ima);
77  }
78 
79  template <typename I>
80  inline
81  void
82  load_ascii_dispatch(std::ifstream& file, I& ima, const metal::bool_<false>&)
83  {
84  load_ascii_builtin(file, ima);
85  }
86 
87  } // end of namespace mln::io::pnm::internal
88 
89 
90  // Read a Milena rgb value (sizeof(int_u8) != 1).
91  template <unsigned int n>
92  inline
93  void read_value(std::ifstream& file, value::rgb<n>& v)
94  {
95  typedef typename value::int_u<n>::enc E;
96 
97  E c;
98  file.read((char*)(&c), sizeof(E));
99  v.red() = c;
100  file.read((char*)(&c), sizeof(E));
101  v.green() = c;
102  file.read((char*)(&c), sizeof(E));
103  v.blue() = c;
104  }
105 
106  // Read a Milena scalar value (sizeof(int_u8) != 1).
107  template <class V>
108  inline
109  void read_value(std::ifstream& file, value::Scalar<V>& v)
110  {
111  typedef typename V::enc E;
112 
113  E c;
114  file.read((char*)(&c), sizeof(E));
115  exact(v) = c;
116  }
117 
118  // Read a builtin scalar value.
119  template <typename V>
120  inline
121  void read_value(std::ifstream& file, V& v)
122  {
123  V c;
124  file.read((char*)(&c), sizeof(V));
125  v = c;
126  }
127 
128  // used when (sizeof(int_u8) != 1)
129  template <typename V>
130  inline
131  void load_raw_2d_uncontiguous(std::ifstream& file, image2d<V>& ima)
132  {
133  const def::coord
134  min_row = geom::min_row(ima),
135  max_row = geom::max_row(ima),
136  min_col = geom::min_col(ima),
137  max_col = geom::max_col(ima);
138 
139  point2d p;
140  for (p.row() = min_row; p.row() <= max_row; ++p.row())
141  for (p.col() = min_col; p.col() <= max_col; ++p.col())
142  read_value(file, ima(p));
143  }
144 
145  // used in g++ > 2.95
146  template <typename I>
147  inline
148  void load_raw_2d_contiguous(std::ifstream& file, I& ima)
149  {
150  point2d p = point2d(0, ima.domain().pmin().col());
151  typedef mln_value(I) V;
152  const mln_deduce(I, site, coord)
153  min_row = geom::min_row(ima),
154  max_row = geom::max_row(ima);
155 
156  std::size_t len = geom::ncols(ima) * sizeof(V);
157  for (p.row() = min_row; p.row() <= max_row; ++p.row())
158  file.read((char*)(&ima(p)), len);
159  }
160 
162  template <typename I>
163  inline
164  void load_ascii_value(std::ifstream& file, I& ima)
165  {
166  mln_equiv(mln_value_(I)) c;
167  mln_fwd_piter(I) p(ima.domain());
168  for_all(p)
169  {
170  file >> c;
171  ima(p) = c;
172  }
173  }
174 
176  template <typename I>
177  inline
178  void load_ascii_builtin(std::ifstream& file, I& ima)
179  {
180  mln_fwd_piter(I) p(ima.domain());
181 
182  // FIXME: May be wrong!
183  // Worked out with an image with a max value of 255
184  // loaded in an image2d<unsigned char>.
185  unsigned n;
186 
187  for_all(p)
188  {
189  file >> n;
190  ima(p) = n;
191  }
192  }
193 
196  template <typename I>
197  inline
198  void load_raw_2d(std::ifstream& file, I& ima)
199  {
200  typedef mln_value(I) V;
201  if (sizeof(V) == 1)
202  load_raw_2d_contiguous(file, ima);
203  else
204  load_raw_2d_uncontiguous(file, ima);
205  }
206 
208  template <typename V>
209  inline
210  image2d<V> load(char type_, const std::string& filename)
211  {
212  trace::entering("mln::io::pnm::load");
213 
214  std::ifstream file(filename.c_str());
215  if (! file)
216  {
217  std::cerr << "error: file '" << filename
218  << "' not found!";
219  abort();
220  }
221  char type = 0;
222  int nrows, ncols;
223  unsigned int maxval;
224  read_header(static_cast<char>(type_ - 3), type_, file, type,
225  nrows, ncols, maxval);
226 
227  if (max_component(V()) != maxval)
228  {
229  std::cerr << "error: file '" << filename
230  << "' cannot be loaded into this type of image"
231  << std::endl;
232 
233  std::cerr << "input image have " << maxval
234  << " as maximum value while the destination's one is "
235  << max_component(V()) << " (should be the same)."
236  << std::endl;
237  abort();
238  }
239 
240  image2d<V> ima(nrows, ncols);
241  if (type == type_)
242  load_raw_2d(file, ima);
243  else
244  if (type == (type_ - 3))
245  pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(V, mln::Value)());
246 
247  trace::exiting("mln::io::pnm::load");
248 
249  return ima;
250  }
251 
255  template <typename I>
256  inline
257  void load(char type_,
258  Image<I>& ima_,
259  const std::string& filename)
260  {
261  trace::entering("mln::io::pnm::load");
262 
263  std::ifstream file(filename.c_str());
264  if (! file)
265  {
266  std::cerr << "error: file '" << filename
267  << "' not found!";
268  abort();
269  }
270 
271  I& ima = exact(ima_);
272 
273  char type = 0;
274  int nrows, ncols;
275  unsigned int maxval;
276  read_header(static_cast<char>(type_ - 3), type_, file, type,
277  nrows, ncols, maxval);
278 
279  if (max_component(mln_value(I)()) != maxval)
280  {
281  std::cerr << "error: file '" << filename
282  << "' cannot be loaded into this type of image"
283  << std::endl;
284 
285  std::cerr << "input image have " << maxval
286  << " as maximum value while the destination's one is "
287  << max_component(mln_value(I)()) << "."
288  << std::endl;
289  abort();
290  }
291 
292  ima.init_(make::box2d(nrows, ncols));
293  if (type == type_)
294  load_raw_2d(file, ima);
295  else
296  if (type == (type_ - 3))
297  pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(mln_value(I), mln::Value)());
298 
299  trace::exiting("mln::io::pnm::load");
300  }
301 
302 # endif // ! MLN_INCLUDE_ONLY
303 
304  } // end of namespace mln::io::pnm
305 
306  } // end of namespace mln::io
307 
308 } // end of namespace mln
309 
310 
311 #endif // ! MLN_IO_PNM_LOAD_HH