Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
fld/load.hh
1 // Copyright (C) 2008, 2009, 2010, 2011 EPITA Research and Development
2 // 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_FLD_LOAD_HH
28 # define MLN_IO_FLD_LOAD_HH
29 
46 
47 # include <fstream>
48 # include <iostream>
49 
50 # include <mln/core/concept/image.hh>
51 # include <mln/io/fld/header.hh>
52 # include <mln/io/fld/load_header.hh>
53 # include <mln/io/fld/max_components.hh>
54 
55 # include <mln/algebra/vec.hh>
56 # include <mln/value/rgb.hh>
57 # include <mln/value/int_u8.hh>
58 
59 # include <mln/geom/nsites.hh>
60 
61 # include <mln/convert/from_to.hh>
62 
63 namespace mln
64 {
65 
66  namespace io
67  {
68 
69  namespace fld
70  {
71 
77  template <typename I>
78  inline
79  void
80  load(Image<I>& ima_, const char* filename);
81 
82 # ifndef MLN_INCLUDE_ONLY
83 
84  namespace internal
85  {
86 
87  inline
88  void
89  abort_load(const char* msg, const char* filename)
90  {
91  std::cerr << "Error: file '" << filename << "'"
92  << "cannot be loaded." << std::endl
93  << "Error description: " << msg << std::endl;
94  abort();
95  }
96 
97  // Read a Milena rgb value (sizeof(int_u8) != 1).
98  template <unsigned int n>
99  inline
100  void read_value(std::ifstream& file, value::rgb<n>& v)
101  {
102  typedef typename value::int_u<n>::enc E;
103 
104  E c;
105  file.read((char*)(&c), sizeof(E));
106  v.red() = c;
107  file.read((char*)(&c), sizeof(E));
108  v.green() = c;
109  file.read((char*)(&c), sizeof(E));
110  v.blue() = c;
111  }
112 
113  // Read a Milena scalar value (sizeof(int_u8) != 1).
114  template <class V>
115  inline
116  void read_value(std::ifstream& file, value::Scalar<V>& v)
117  {
118  typedef typename V::enc E;
119 
120  E c;
121  file.read((char*)(&c), sizeof(E));
122  exact(v) = c;
123  }
124 
125  // Read a builtin scalar value.
126  template <typename V>
127  inline
128  void read_value(std::ifstream& file, V& v)
129  {
130  V c;
131  file.read((char*)(&c), sizeof(V));
132  v = c;
133  }
134 
135  // used when (sizeof(int_u8) != 1)
136  template <typename I>
137  inline
138  void load_raw_uncontiguous(std::ifstream& file, I& ima)
139  {
140  mln_piter(I) p(ima.domain());
141  read_value(file, ima(p));
142  }
143 
144  // used in g++ > 2.95
145  template <typename I>
146  inline
147  void load_raw_contiguous(std::ifstream& file, I& ima)
148  {
149  mln_site(I) pmin = ima.domain().pmin();
150  mln_site(I) pmax = ima.domain().pmax();
151 
152  typedef mln_site(I) P;
153  enum { dim = P::dim };
154 
155  // The first array index varies most quickly (FORTRAN-style).
156  typedef mln_value(I) V;
157 
158 
159  std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
160  std::size_t n = len * sizeof(V);
161 
162  P p = pmin;
163  if (dim == 1)
164  {
165  file.read((char*)(&ima(p)), n);
166  return;
167  }
168 
169  while (true)
170  {
171  file.read((char*)(&ima(p)), n);
172  ++p[dim - 2];
173 
174  for (int i = dim - 2; p[i] > pmax[i]; --i)
175  {
176  if (i == 0)
177  return;
178  p[i] = pmin[i];
179  ++p[i - 1];
180  }
181  }
182  }
183 
184  template <typename I>
185  inline
186  void load_raw(std::ifstream& file, I& ima)
187  {
188  if (sizeof(value::int_u8) == 1)
189  load_raw_contiguous(file, ima);
190  else
191  load_raw_uncontiguous(file, ima);
192  }
193 
194  } // end of mln::io::internal
195 
196  template <typename I>
197  inline
198  void
199  load(Image<I>& ima_, const char* filename)
200  {
201  trace::entering("mln::io::fld::load");
202 
203  std::ifstream file(filename);
204  if (! file)
205  internal::abort_load("Fail to open the file.", filename);
206 
207  typedef mln_value(I) V;
208  typedef mln_site(I) P;
209 
210  I& ima = exact(ima_);
211  fld_header hder = fld::read_header(file);
212  int nspace = P::dim;
213  int veclen = mln_dim(V);
214 
215  if (nspace != hder.nspace)
216  internal::abort_load("The dimension of the input does not match the one from the file.", filename);
217  if (nspace > 3)
218  internal::abort_load("The loader does not handle image dimension greater than three.", filename);
219  if (veclen != hder.veclen)
220  internal::abort_load("The dimension of the value does not match the one from the file.", filename);
221  if (max_component(V ()) != max_component(hder.data))
222  internal::abort_load("The data type of the input mismatches the one from the file.", filename);
223 
224  box<mln_site(I)> bbox;
225  for (int i = 0; i < hder.ndim; ++i)
226  {
227  convert::from_to(hder.min_ext[i], bbox.pmin()[i]);
228  convert::from_to(hder.max_ext[i], bbox.pmax()[i]);
229  }
230 
231  ima.init_(bbox);
232  internal::load_raw(file, ima);
233 
234  file.close();
235  trace::exiting("mln::io::fld::load");
236  }
237 
238 # endif // ! MLN_INCLUDE_ONLY
239 
240  } // end of namespace mln::io::fld
241 
242  } // end of namespace mln::io
243 
244 } // end of namespace mln
245 
246 #endif // !MLN_IO_FLD_LOAD_HH