$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
pnm/load.hh
1 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2 // 2012 EPITA Research and Development Laboratory (LRDE).
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // 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 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_IO_PNM_LOAD_HH
28 # define MLN_IO_PNM_LOAD_HH
29 
34 
35 # include <iostream>
36 # include <fstream>
37 # include <string>
38 
39 # include <mln/core/image/image2d.hh>
40 
41 # include <mln/value/int_u8.hh>
42 # include <mln/value/rgb.hh>
43 
44 # include <mln/io/pnm/load_header.hh>
45 # include <mln/io/pnm/max_component.hh>
46 # include <mln/io/pnm/macros.hh>
47 
48 # include <mln/metal/is_a.hh>
49 # include <mln/metal/bool.hh>
50 
51 namespace mln
52 {
53 
54  namespace io
55  {
56 
57  namespace pnm
58  {
59 
60 
61 # ifndef MLN_INCLUDE_ONLY
62 
63  template <typename I>
64  void
65  load_ascii_value(std::ifstream& file, I& ima, metal::true_ is_scalar);
66 
67  template <typename I>
68  void
69  load_ascii_value(std::ifstream& file, I& ima, metal::false_ is_scalar);
70 
71 
72  template <typename I>
73  void load_ascii_builtin(std::ifstream& file, I& ima);
74 
75 
76  namespace internal
77  {
78 
79  template <typename I>
80  inline
81  void
82  load_ascii_dispatch(std::ifstream& file, I& ima,
83  const metal::bool_<true>&)
84  {
85  load_ascii_value(file, ima,
86  mlc_bool( mln_dim(mln_value(I)) == 1 ) () );
87  }
88 
89  template <typename I>
90  inline
91  void
92  load_ascii_dispatch(std::ifstream& file, I& ima,
93  const metal::bool_<false>&)
94  {
95  load_ascii_builtin(file, ima);
96  }
97 
98  } // end of namespace mln::io::pnm::internal
99 
100 
101  // Read a Milena rgb value (sizeof(int_u8) != 1).
102  template <unsigned int n>
103  inline
104  void read_value(std::ifstream& file, value::rgb<n>& v)
105  {
106  typedef typename value::int_u<n>::enc E;
107 
108  E c;
109  file.read((char*)(&c), sizeof(E));
110  v.red() = c;
111  file.read((char*)(&c), sizeof(E));
112  v.green() = c;
113  file.read((char*)(&c), sizeof(E));
114  v.blue() = c;
115  }
116 
117  // Read a Milena scalar value (sizeof(int_u8) != 1).
118  template <class V>
119  inline
120  void read_value(std::ifstream& file, value::Scalar<V>& v)
121  {
122  typedef typename V::enc E;
123 
124  E c;
125  file.read((char*)(&c), sizeof(E));
126  exact(v) = c;
127  }
128 
129  // Read a builtin scalar value.
130  template <typename V>
131  inline
132  void read_value(std::ifstream& file, V& v)
133  {
134  V c;
135  file.read((char*)(&c), sizeof(V));
136  v = c;
137  }
138 
139  // used when (sizeof(int_u8) != 1)
140  template <typename V>
141  inline
142  void load_raw_2d_uncontiguous(std::ifstream& file, image2d<V>& ima)
143  {
144  const def::coord
145  min_row = geom::min_row(ima),
146  max_row = geom::max_row(ima),
147  min_col = geom::min_col(ima),
148  max_col = geom::max_col(ima);
149 
150  point2d p;
151  for (p.row() = min_row; p.row() <= max_row; ++p.row())
152  for (p.col() = min_col; p.col() <= max_col; ++p.col())
153  read_value(file, ima(p));
154  }
155 
156  // used in g++ > 2.95
157  template <typename I>
158  inline
159  void load_raw_2d_contiguous(std::ifstream& file, I& ima)
160  {
161  point2d p = point2d(0, ima.domain().pmin().col());
162  typedef mln_value(I) V;
163  const mln_deduce(I, site, coord)
164  min_row = geom::min_row(ima),
165  max_row = geom::max_row(ima);
166 
167  std::size_t len = geom::ncols(ima) * sizeof(V);
168  for (p.row() = min_row; p.row() <= max_row; ++p.row())
169  file.read((char*)(&ima(p)), len);
170  }
171 
173  template <typename I>
174  inline
175  void
176  load_ascii_value(std::ifstream& file, I& ima, metal::false_)
177  {
178  enum { dim = mln_dim(mln_value(I)) };
179  typedef mln_equiv(mln_value_(I)) E;
180  typedef mln_equiv(trait::value_<E>::comp) T;
181  E v;
182  T x;
183 
184  mln_fwd_piter(I) p(ima.domain());
185  for_all(p)
186  {
187  for (int i = 0; i<dim; ++i) {
188  file >> x;
189  v[i] = x;
190  }
191  ima(p) = v;
192  }
193  }
194 
196  template <typename I>
197  inline
198  void
199  load_ascii_value(std::ifstream& file, I& ima, metal::true_)
200  {
201  mln_equiv(mln_value_(I)) c;
202 
203  mln_fwd_piter(I) p(ima.domain());
204  for_all(p)
205  {
206  file >> c;
207  ima(p) = c;
208  }
209  }
210 
211 
213  template <typename I>
214  inline
215  void load_ascii_builtin(std::ifstream& file, I& ima)
216  {
217  mln_fwd_piter(I) p(ima.domain());
218 
219  // FIXME: May be wrong!
220  // Worked out with an image with a max value of 255
221  // loaded in an image2d<unsigned char>.
222  unsigned n;
223 
224  for_all(p)
225  {
226  file >> n;
227  ima(p) = n;
228  }
229  }
230 
233  template <typename I>
234  inline
235  void load_raw_2d(std::ifstream& file, I& ima)
236  {
237  typedef mln_value(I) V;
238  if (sizeof(V) == 1)
239  load_raw_2d_contiguous(file, ima);
240  else
241  load_raw_2d_uncontiguous(file, ima);
242  }
243 
245  template <typename V>
246  inline
247  image2d<V> load(char type_, const std::string& filename)
248  {
249  mln_trace("mln::io::pnm::load");
250 
251  std::ifstream file(filename.c_str());
252  if (! file)
253  {
254  std::cerr << "error: file '" << filename
255  << "' not found!";
256  abort();
257  }
258  char type = 0;
259  int nrows, ncols;
260  unsigned int maxval;
261  read_header(static_cast<char>(type_ - 3), type_, file, type,
262  nrows, ncols, maxval);
263 
264  if (max_component(V()) != maxval)
265  {
266  std::cerr << "error: file '" << filename
267  << "' cannot be loaded into this type of image"
268  << std::endl;
269 
270  std::cerr << "input image have " << maxval
271  << " as maximum value while the destination's one is "
272  << max_component(V()) << " (should be the same)."
273  << std::endl;
274  abort();
275  }
276 
277  image2d<V> ima(nrows, ncols);
278  if (type == type_)
279  load_raw_2d(file, ima);
280  else
281  if (type == (type_ - 3))
282  pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(V, mln::Value)());
283 
284 
285  return ima;
286  }
287 
291  template <typename I>
292  inline
293  void load(char type_,
294  Image<I>& ima_,
295  const std::string& filename)
296  {
297  mln_trace("mln::io::pnm::load");
298 
299  std::ifstream file(filename.c_str());
300  if (! file)
301  {
302  std::cerr << "error: file '" << filename
303  << "' not found!";
304  abort();
305  }
306 
307  I& ima = exact(ima_);
308 
309  char type = 0;
310  int nrows, ncols;
311  unsigned int maxval;
312  read_header(static_cast<char>(type_ - 3), type_, file, type,
313  nrows, ncols, maxval);
314 
315  if (max_component(mln_value(I)()) != maxval)
316  {
317  std::cerr << "error: file '" << filename
318  << "' cannot be loaded into this type of image"
319  << std::endl;
320 
321  std::cerr << "input image have " << maxval
322  << " as maximum value while the destination's one is "
323  << max_component(mln_value(I)()) << "."
324  << std::endl;
325  abort();
326  }
327 
328  ima.init_(make::box2d(nrows, ncols));
329  if (type == type_)
330  load_raw_2d(file, ima);
331  else
332  if (type == (type_ - 3))
333  pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(mln_value(I), mln::Value)());
334 
335  }
336 
337 # endif // ! MLN_INCLUDE_ONLY
338 
339  } // end of namespace mln::io::pnm
340 
341  } // end of namespace mln::io
342 
343 } // end of namespace mln
344 
345 
346 #endif // ! MLN_IO_PNM_LOAD_HH